Camera Rotation / Player movement - orientation problem

I’m working on a top down 3rd person game

player object has playermovement script attached

using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour
{
    CharacterController _controller;
   
    [SerializeField]
    float _moveSpeed = 5.0f;
   
    [SerializeField]
    float _walkSpeed = 2.0f;
   
    [SerializeField]
    float _runSpeed = 10.0f;
   
    [SerializeField]
    float _gravity = 1.0f;
   
    float _yVelocity = 0.0f;
    bool _walking = false;

    public Quaternion _lookrotation;
   
   
    void Start ()
    {
        _controller = GetComponent<CharacterController>();
    }
   
    void FixedUpdate ()
    {
        float h = Input.GetAxis ("Horizontal");
        float v = Input.GetAxis ("Vertical");

        MouseLook();
        Move (h,v);
    }


    void Move(float h, float v)
    {
        Vector3 direction = new Vector3(h, 0, v);
        Vector3 velocity = direction * _moveSpeed;
       
        if (Input.GetKeyDown ("left ctrl"))
        {
            _walking = !_walking;
        }
       
        if (_walking == true)
        {
            velocity = direction * _walkSpeed;
        }
       
        if (Input.GetKey ("left shift"))
        {
            velocity = direction * _runSpeed;
        }
       
       
        _yVelocity -= _gravity;
       
        velocity.y = _yVelocity;
       
        //velocity = transform.TransformDirection (velocity); commented out due rotation probs with mouselook
       
        _controller.Move (velocity * Time.deltaTime);

    }

    void MouseLook()
    {
        Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);

        RaycastHit mouseloc;

        if(Physics.Raycast(camRay,out mouseloc, 100))
        {
            Vector3 playertomouse = mouseloc.point - transform.position;

            playertomouse.y = 0f;

            _lookrotation = Quaternion.LookRotation(playertomouse);

            transform.rotation = _lookrotation;
        }
    }
}

The main camera is a child object to an empty game object called CamFocus, CamFocus has the CamMovement script attached to it

using UnityEngine;
using System.Collections;

public class CamMovement : MonoBehaviour
{
    public Transform _targetpos;
    public float _camsmoothing = 5f;

    float _camrotation;
    Vector3 _currentrot;

    void Start ()
    {
        transform.position = _targetpos.transform.position;
    }
   

    void FixedUpdate ()
    {
        Vector3 targetcampos = _targetpos.position;
        transform.position = Vector3.Lerp (transform.position, targetcampos, _camsmoothing * Time.deltaTime);

        _camrotation = Input.GetAxis("Rotation");
        _currentrot = transform.localEulerAngles;
        _currentrot.y += _camrotation * _camsmoothing;
        transform.localEulerAngles = _currentrot;
    }
}

the end result of this is that the players rotation is always set to look at the mouse location on screen, he moves with a standard wasd movement scheme maintaining his rotation to look at the mouse location

the problem I am having is when I added the Camera rotation ability the camera rotation works, but the players movement orientation stays the same, I took a break from this for a while and have just come back to it. I believe the answer lies in Quaternions but I’ve always kinda sucked at them… could somebody point me in the right direction?

I need movement orientation to always remain in line with the camera, but the player rotation has to continue to focus on mouse point on screen.

On line 84:

transform.rotation = _lookrotation;

Change that to transform.localRotation. Should fix your problem, I believe.

I’ve found that quaternions are almost never the answer. I’m still trying to figure out why we even bother with quaternions. The best I can tell so far is that in animation you can’t SLERP matrices without decomposing them.

I don’t have a problem with quaternions really. Six of one and half a dozen of the other. But, I haven’t noticed them actually bringing anything to the table. There’s a rumor of gimbal lock, but in the years I’ve been playing with this stuff I’ve never seen a matrix go into gimbal lock. And I’ve heard they do SLERP better. The jury is still out on that one. I just SLERP’ed for the first time this last week. :smile: So, maybe I’ll figure it out pretty soon.

In the end the graphics card doesn’t know what a quaternion is and is only going to accept a matrix for the world, view, projection calculations its doing to put stuff on the screen. So, I’m still trying to figure out why we don’t just use matrices in every case. (What Unity calls a transform is usually implemented as a matrix although Unity’s documentation says they’ve implemented as a SQT (Scale, Quaternion, Translation- where Translation is position). There may be a valid reason for it since animation seems to always use SQT’s but I haven’t seen the reason yet.)

Sometimes I think programmers get all religious and even dogmatic about quaternions just because they’re kind of mystical being multi-dimensional complex(imaginary) numbers and all. “If you can’t understand them, they must be good!” I’m not particularly for them or against them, but still don’t see the advantage over matrices and since matrices are the final product needed, I see a small disadvantage if there is no advantage to offset that.

100000001218704--1121384--clear.png

the localrotation fix will not work in this particular situation because the CamFocus object is not a child of the player object

I had debated going that route, but I’m trying to keep it separate so that if a player selects a different character the CamFocus object can make that new character it’s target and the camera would focus itself appropriately

any other suggestions?

I’m not that familiar with adding and removing child objects through code, but I know it’s possible, if it’s relatively easy maybe that is an option combined with the localrotation fix

the script is attached to the CamFocus empty game object… what would the code be to child itself to the player object, and then to remove itself from being a child of the player object?

no other ideas on this subject? please help, hate being stuck on a simple matter for too long

Changing parents on an object is extremely easy.

transform.parent = someObject;

Once you change the parent, it automagically stops being a child of what it was previously.

began testing with parenting the cam to player, in this situation it doesnt seem to work well since I dont want the rotation of player to actually influence camera placement, with the mouselook the players orientation changes constantly, i only want the cameras orientation to influence movement direction not player rotation