- Home /
Character movement always faces forwards
Hi all,
After making a lot of progress today getting a character to move on a plane responding to clicks, I've hit a wall when it comes to rotation and direction. I now have the character moving nicely and a smooth rotation using Quaternion.Slerp, but it always 'turns back to the front' direction during the move.
My face function:
// Make the character face the direction of movement
void FaceMovementDirection( )
{
Quaternion targetRotation = Quaternion.LookRotation ( targetLocation - thisTransform.position );
targetRotation.z = 0;
targetRotation.x = 0;
//targetRotation.y = 0;
float smooth = 2.0F;
Vector3 tempVector = targetLocation - thisTransform.position;
if (tempVector.magnitude > 0.1)
{
thisTransform.rotation = Quaternion.Slerp (thisTransform.rotation,
targetRotation,
smooth * Time.deltaTime);
}
}
The move function:
// Control the character
void CharacterControl()
{
// Check to see if a new destination has been found
if (state == (int)ControlState.FoundNewDestination )
{
// get a new movement position
RaycastHit hit;
Ray ray = cam.ScreenPointToRay ( Input.mousePosition ); // Get the position
if ( Physics.Raycast (ray, out hit) )
{
// Found a new position, now is it a valid target?
float clickDist = ( transform.position - hit.point ).magnitude;
if (clickDist > minimumDistanceToMove )
{
Debug.Log ("Distance to Target:" + clickDist);
targetLocation = hit.point;
moving = true;
}
}
}
Vector3 moveDirection = Vector3.zero; // declares an empty movement vector
if ( moving )
{
if (character.isGrounded)
{
moveDirection = targetLocation - thisTransform.position;
moveDirection.y = 0;
moveDirection = thisTransform.TransformDirection(moveDirection);
moveDirection *= speed;
}
moveDirection.y -= gravityForce * Time.deltaTime;
character.Move ( moveDirection * Time.deltaTime );
}
FaceMovementDirection();
}
Any and all help would really be appreciated!
If you make sure you only change 'targetRotation' when the inputs are more than a certain amount, it'll stop your character from 'resetting' whenever you aren't moving.
Thanks for the input syclamoth! I did put in an 'if (tempVector.magnitude > 0.1)' call before setting the transform.rotation on the character... was that what you meant?
Another note: I worked through it in my head, and it appears that the calculations are always ending with the same character rotation they start with - the targetRotation seems to be constantly 'forward' on the original alignment.
Or, you could store a Vector3 'last$$anonymous$$ovement' which is a normalized version of the last non-zero input, and use that.
I stored a normalized last$$anonymous$$ovement Vector3, and I've tried about 6 different ways to get this working right with varying levels of ineffectiveness = )
I think the problem lies with my movement code, not the rotation, as the destination seems to always be 'front facing' no matter what I do.
Another strange thing is that whenever I do LookAt rotation calls (vector, quaternion, etc...) I get the model rotating and 'looking down' unless I zero out the X and Y coordinates of the last$$anonymous$$ovement or targetPosition vectors. I'm not entirely used to the system yet, but it seems strange.
Answer by Xcalibur · Oct 10, 2011 at 11:42 PM
My instinct above was right, the problem was with my movement code! I was modifying the moveDirection twice (once with the targetLocation - thisTransform.position, but AGAIN withthisTransform.TransformDirection(moveDirection) ). Once I removed the second moveDirection modification it all started to fall together.
I also added a magnitude check for the lastMovementDirection and a state to recognize when the character reached the destination. It now works 100%!
Thanks for the input syclamoth, much appreciated.