3D Character Rotation Issue
Hello!
I've been working on 3D character controls for my game, and I've managed to make a character that takes the forward direction of the camera and the input on the vertical and horizontal axes, moves in the combined direction and rotates to face the way it's moving! It works a lot like a character in a 3D platformer and feels very nice. The character uses a rigidbody for the sake of controls, and has no Character Controller component or animations.
The problem I'm getting however, is that whenever the character isn't being moved with WASD or the gamepad analog sticks, the character immediately faces directly north in the game world and logs the error:
Look rotation viewing vector is zero
UnityEngine.Quaternion:LookRotation(Vector3, Vector3)
PlayerController3:Movement() (at Assets/Scripts/PlayerController3.cs:78)
PlayerController3:FixedUpdate() (at Assets/Scripts/PlayerController3.cs:53)
Inside the code are two methods called "Movement" and "CameraForward" and I think these are where the problem lies. I feel that I don't understand quaternions very well and it is probably because I'm misusing one. What I want is the character to face whatever direction it was moving before it stopped, and to not get that error... .
If any other information is needed, let me know.
[SerializeField]
public float movePower = 5f;
[SerializeField]
public float jumpPower = 325f;
public float groundRayLength = 1f;
private Rigidbody rBody;
private bool jump;
private Transform cam;
private Vector3 camForward;
float horizontalMove;
float verticalMove;
private Vector3 move;
// Use this for initialization
private void Awake()
{
if (Camera.main != null)
{
cam = Camera.main.transform;
}
else
{
Debug.LogWarning("Warning: no main camera found. Player needs a Camera tagged \"MainCamera\", for camera-relative controls.");
// we use world-relative controls in this case, which may not be what the user wants, but hey, we warned them!
}
}
void Start()
{
rBody = GetComponent<Rigidbody>();
}
void GetControls()
{
horizontalMove = Input.GetAxis("Horizontal");
verticalMove = Input.GetAxis("Vertical");
jump = Input.GetButton("Jump");
}
// Update is called once per frame
public void FixedUpdate()
{
GetControls();
CameraForward();
Movement();
Jumping();
}
void CameraForward()
{
if (cam != null)
{
// calculate camera relative direction to move:
camForward = Vector3.Scale(cam.forward, new Vector3(1, 0, 1)).normalized;
move = (verticalMove * camForward + horizontalMove * cam.right) * movePower * Time.deltaTime;
}
else
{
// we use world-relative directions in the case of no main camera
camForward = Vector3.forward;
}
}
void Movement()
{
rBody.MovePosition(transform.position + move * Time.deltaTime);
if (move != null)
{
rBody.MoveRotation(Quaternion.LookRotation(move, Vector3.up));
}
else
{
rBody.MoveRotation(Quaternion.LookRotation(camForward, Vector3.up));
}
}
void Jumping()
{
Debug.DrawRay(transform.position, -Vector3.up * groundRayLength, Color.red);
//If the player's center is less than the groundRayLength distance from the ground, they can jump
if (Physics.Raycast(transform.position, Vector3.down, groundRayLength) && jump)
{
// change upwards velocity directly.
rBody.velocity = new Vector3(0, 1, 0) * jumpPower * Time.deltaTime;
}
}