Playmaker Forum

PlayMaker Help & Tips => PlayMaker Help => Topic started by: Franck on October 19, 2018, 03:44:26 PM

Title: Camera lock vertical look when rotate animation
Post by: Franck on October 19, 2018, 03:44:26 PM
Hi there,

I have a camera problem when I do an animation. I use the SimpleSmoothMouseLook script which works very well but as soon as I want to make a camera animation by giving it a rotation, when I run the game I can not look up and down anymore.
The problem comes from the rotation animation of the camera but I do not know how to adjust it.

An idea?

Here is the script:

Code: [Select]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[AddComponentMenu("Camera/Simple Smooth Mouse Look ")]
public class SimpleSmoothMouseLook : MonoBehaviour
{
    Vector2 _mouseAbsolute;
    Vector2 _smoothMouse;

    public Vector2 clampInDegrees = new Vector2(360, 180);
    public bool lockCursor;
    public Vector2 sensitivity = new Vector2(2, 2);
    public Vector2 smoothing = new Vector2(3, 3);
    public Vector2 targetDirection;
    public Vector2 targetCharacterDirection;

   
    // Assign this if there's a parent object controlling motion, such as a Character Controller.
    // Yaw rotation will affect this object instead of the camera if set.
    public GameObject characterBody;

    void Start()
    {
        // Set target direction to the camera's initial orientation.
        targetDirection = transform.localRotation.eulerAngles;

        // Set target direction for the character body to its inital state.
        if (characterBody)
            targetCharacterDirection = characterBody.transform.localRotation.eulerAngles;
    }

    void Update()
    {
        // Ensure the cursor is always locked when set
        if (lockCursor)
        {
            Cursor.lockState = CursorLockMode.Locked;
        }

        // Allow the script to clamp based on a desired target value.
        var targetOrientation = Quaternion.Euler(targetDirection);
        var targetCharacterOrientation = Quaternion.Euler(targetCharacterDirection);

        // Get raw mouse input for a cleaner reading on more sensitive mice.
        var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        // Scale input against the sensitivity setting and multiply that against the smoothing value.
        mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));

        // Interpolate mouse movement over time to apply smoothing delta.
        _smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
        _smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);

        // Find the absolute mouse movement value from point zero.
        _mouseAbsolute += _smoothMouse;

        // Clamp and apply the local x value first, so as not to be affected by world transforms.
        if (clampInDegrees.x < 360)
            _mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);

        // Then clamp and apply the global y value.
        if (clampInDegrees.y < 360)
            _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);

        transform.localRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right) * targetOrientation;

        // If there's a character body that acts as a parent to the camera
        if (characterBody)
        {
            var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, Vector3.up);
            characterBody.transform.localRotation = yRotation * targetCharacterOrientation;
        }
        else
        {
            var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(Vector3.up));
            transform.localRotation *= yRotation;
        }

        // Hide cursor
        Cursor.visible = false;
    }
}
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 22, 2018, 09:06:17 AM
Help Please :)
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 22, 2018, 05:39:26 PM
Hi. you probably need to make a parent and drop in you character, then do the mouselook on the parent

What kind of setup do you have (first person, third person, 2d,..)
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 23, 2018, 02:04:34 AM
Hi djaydino,

it's a first person. I don't use standard assets for the controller.
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 23, 2018, 03:21:50 AM
Hi.
Are you using the movement on the character itself or on a empty parent.

Also it better to separate the camera and use get/set position to follow the player.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 23, 2018, 09:48:07 AM
For the movement, I use the FPSWalkerEnhanced script:

Code: [Select]
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterController))]
public class FPSWalkerEnhanced : MonoBehaviour
{

    public float walkSpeed = 6.0f;

    public float runSpeed = 11.0f;

    // If true, diagonal speed (when strafing + moving forward or back) can't exceed normal move speed; otherwise it's about 1.4 times faster
    public bool limitDiagonalSpeed = true;

    // If checked, the run key toggles between running and walking. Otherwise player runs if the key is held down and walks otherwise
    // There must be a button set up in the Input Manager called "Run"
    public bool toggleRun = false;

    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;

    // Units that player can fall before a falling damage function is run. To disable, type "infinity" in the inspector
    public float fallingDamageThreshold = 10.0f;

    // If the player ends up on a slope which is at least the Slope Limit as set on the character controller, then he will slide down
    public bool slideWhenOverSlopeLimit = false;

    // If checked and the player is on an object tagged "Slide", he will slide down it regardless of the slope limit
    public bool slideOnTaggedObjects = false;

    public float slideSpeed = 12.0f;

    // If checked, then the player can change direction while in the air
    public bool airControl = false;

    // Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
    public float antiBumpFactor = .75f;

    // Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
    public int antiBunnyHopFactor = 1;

    private Vector3 moveDirection = Vector3.zero;
    private bool grounded = false;
    private CharacterController controller;
    private Transform myTransform;
    private float speed;
    private RaycastHit hit;
    private float fallStartLevel;
    private bool falling;
    private float slideLimit;
    private float rayDistance;
    private Vector3 contactPoint;
    private bool playerControl = false;
    private int jumpTimer;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        myTransform = transform;
        speed = walkSpeed;
        rayDistance = controller.height * .5f + controller.radius;
        slideLimit = controller.slopeLimit - .1f;
        jumpTimer = antiBunnyHopFactor;
    }

    void FixedUpdate()
    {
        float inputX = Input.GetAxis("Horizontal");
        float inputY = Input.GetAxis("Vertical");
        // If both horizontal and vertical are used simultaneously, limit speed (if allowed), so the total doesn't exceed normal move speed
        float inputModifyFactor = (inputX != 0.0f && inputY != 0.0f && limitDiagonalSpeed) ? .7071f : 1.0f;

        if (grounded)
        {
            bool sliding = false;
            // See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point,
            // because that interferes with step climbing amongst other annoyances
            if (Physics.Raycast(myTransform.position, -Vector3.up, out hit, rayDistance))
            {
                if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
                    sliding = true;
            }
            // However, just raycasting straight down from the center can fail when on steep slopes
            // So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
            else
            {
                Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, out hit);
                if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
                    sliding = true;
            }

            // If we were falling, and we fell a vertical distance greater than the threshold, run a falling damage routine
            if (falling)
            {
                falling = false;
                if (myTransform.position.y < fallStartLevel - fallingDamageThreshold)
                    FallingDamageAlert(fallStartLevel - myTransform.position.y);
            }

            // If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
            if (!toggleRun)
                speed = Input.GetButton("Run") ? runSpeed : walkSpeed;

            // If sliding (and it's allowed), or if we're on an object tagged "Slide", get a vector pointing down the slope we're on
            if ((sliding && slideWhenOverSlopeLimit) || (slideOnTaggedObjects && hit.collider.tag == "Slide"))
            {
                Vector3 hitNormal = hit.normal;
                moveDirection = new Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
                Vector3.OrthoNormalize(ref hitNormal, ref moveDirection);
                moveDirection *= slideSpeed;
                playerControl = false;
            }
            // Otherwise recalculate moveDirection directly from axes, adding a bit of -y to avoid bumping down inclines
            else
            {
                moveDirection = new Vector3(inputX * inputModifyFactor, -antiBumpFactor, inputY * inputModifyFactor);
                moveDirection = myTransform.TransformDirection(moveDirection) * speed;
                playerControl = true;
            }

            // Jump! But only if the jump button has been released and player has been grounded for a given number of frames
            if (!Input.GetButton("Jump"))
                jumpTimer++;
            else if (jumpTimer >= antiBunnyHopFactor)
            {
                moveDirection.y = jumpSpeed;
                jumpTimer = 0;
            }
        }
        else
        {
            // If we stepped over a cliff or something, set the height at which we started falling
            if (!falling)
            {
                falling = true;
                fallStartLevel = myTransform.position.y;
            }

            // If air control is allowed, check movement but don't touch the y component
            if (airControl && playerControl)
            {
                moveDirection.x = inputX * speed * inputModifyFactor;
                moveDirection.z = inputY * speed * inputModifyFactor;
                moveDirection = myTransform.TransformDirection(moveDirection);
            }
        }

        // Apply gravity
        moveDirection.y -= gravity * Time.deltaTime;

        // Move the controller, and set grounded true or false depending on whether we're standing on something
        grounded = (controller.Move(moveDirection * Time.deltaTime) & CollisionFlags.Below) != 0;
    }

    void Update()
    {
        // If the run button is set to toggle, then switch between walk/run speed. (We use Update for this...
        // FixedUpdate is a poor place to use GetButtonDown, since it doesn't necessarily run every frame and can miss the event)
        if (toggleRun && grounded && Input.GetButtonDown("Run"))
            speed = (speed == walkSpeed ? runSpeed : walkSpeed);
    }

    // Store point that we're in contact with for use in FixedUpdate if needed
    void OnControllerColliderHit(ControllerColliderHit hit)
    {
        contactPoint = hit.point;
    }

    // If falling damage occured, this is the place to do something about it. You can make the player
    // have hitpoints and remove some of them based on the distance fallen, add sound effects, etc.
    void FallingDamageAlert(float fallDistance)
    {
        print("Ouch! Fell " + fallDistance + " units!");
    }
}

I have the parent FPSCharacter, and in it I have 2 cameras. One (the main camera) for all, except weapons and one just for Weapons in order to hide the clipping with walls.

In the main camera I have my WeaponHolder. And the script for the camera is on the main camera and the camera for weapons.

Is it good or not?
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 23, 2018, 10:02:12 AM
Hi.
It might be better to separate the camera and use a simple fsm to follow the weapon holder

Using Get / Set position and Check Late Update

For the rotation i usually do this on the separated camera and if to object needs to be rotated with the camera i use get / set rotation but then get rot from camera and set rot to object.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 23, 2018, 10:59:51 AM
Hi djaydino,

do you have examples of tutorials to get this result?
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 23, 2018, 05:24:26 PM
Hi.
If you have my PlayMaker Sample Asset (https://www.assetstore.unity3d.com/#!/content/102446), on the bullet hole sample i have a separate camera.

I do have plans for character setup tutorials but i have to much other work at the moment, but its in the top 3 of my upcoming tutorials list
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 24, 2018, 05:09:18 AM
Hi djaydino,

I bought your asset. It is especially to support you with all the help that you bring here.
I'm going to take a look at the camera in the bullet hole scene.
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 24, 2018, 06:24:09 AM
Hi.
Thanks!
If you have questions, let me know.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 10:28:53 AM
Hi djaydino,

it works with your method.
But now I try to make my Character lean right and left, I don't know how to do it with this method.
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 25, 2018, 12:31:28 PM
Hi.
You you mean like standing in front of a wall and then look on the side of it?

There are 2 ways i can think of to manipulate the camera :

1 : if camera is set as a child and the parent handles the movement you could move the camera left/right in local space.

2 : have a dedicated follow (empty) object on the player that is a child to the player object that handles the movement.
and set the camera handler to follow that object.
Then move the dedicated follow (empty) object left/right in local space.


2nd option you could maybe even give a collider to the dedicated follow (empty) object as a 'Head' collider if you want the enemy to be able to hit the player.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 12:40:14 PM
I have the Camera Holder as parent and the Main Camera as Child.
I try to create an animation on the Camera Holder. In this animation I set the Main Camera and move on X.

But when I play this animation the X is taken as Global and not Local. How can I use the Local transform in animation?
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 25, 2018, 12:45:23 PM
Hi.
the animation should probably be on the camera or a child of the camera holder where you can place the camera in.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 12:48:21 PM
Yes I tried that too just now and it's the same. The X is considered as Global :(
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 01:13:42 PM
In fact, the position is always the same. When I press the LEAN Button my Character goes to the same direction. Finaly there is just one direction that's right.
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 25, 2018, 03:25:19 PM
Hi.
Just did a quick test with a quick animation and parenting should work.

on the video i just placed a cube so its easier to see :


if you can't find the solution, mabye i can have a look at your setup (you can pm me a link)
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 03:34:32 PM
Sure, but my folder is 3Go... You have a good internet connection?
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 25, 2018, 04:13:06 PM
Hi.
At the moment i have 200Mbps so that will be fine :D

When i am in the Philippines its a lot less :s
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 25, 2018, 05:11:53 PM
PM Sent.

Be carreful about the bind. I use zsqd not wasd :)
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 27, 2018, 09:32:58 AM
Hi djaydino,

did you had the  time to download the project?
If yes is it ok? You can open it?
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 29, 2018, 03:11:32 AM
Hi.
I had a quick look and i can see that the animator is on the camera holder.
It should be on the camera or on a child which holds the camera.

Also the animation itself should be on the camera or a child which holds the camera.

The camera holder is following the position of the player, so if it is moved by the animation it will be overridden by the set position and the animation will not work.
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 30, 2018, 10:30:44 AM
Hi djaydino,

I put the animator on the maincamera and I created the animation on it too. But that does not change anything my character is always on the same side.
Have you tried to do it on my project?
Title: Re: Camera lock vertical look when rotate animation
Post by: Franck on October 30, 2018, 10:32:41 AM
Hmmm,

I think it's because I have an animator that stays on my camera holder right?
I must completely remove the animator on my camera holder.
Title: Re: Camera lock vertical look when rotate animation
Post by: djaydino on October 30, 2018, 05:52:11 PM
Hi.
Yes, it must be on a child inside the holder :)