- Home /
Root motion makes my character unable to turn.
I am currently working on a third person game that uses root motion to move the character. My problem is that the character does not turn around anymore and just moves forward in a certain direction. It should face forward relative to the camera when I press the forward key, and it should turn right relative to the camera when I press the "d" key, but it just moves forward. I am using a model imported from a Blender project file.
Here is my character movement script, note that the speed variables are set to 0 in the editor so the character only moves using it's animations. The reason I add some force to the rigidbody is because it fixed a bug where the model began vibrating after walking into corners.
using UnityEngine;
using System.Collections;
public class CharacterMovement : MonoBehaviour {
public float runSpeed = 0.5f;
public float sprintSpeed = 1.0f;
public float turnSmoothing = 3.0f;
public float speedDampTime = 0.1f;
public float speed;
private Vector3 lastDirection;
private Animator anim;
private int speedFloat;
private int groundedBool;
private Transform cameraTransform;
private float h;
private float v;
private bool run;
private bool sprint;
private bool isMoving;
private float distToGround;
Rigidbody rb;
void Awake()
{
anim = GetComponent<Animator>();
cameraTransform = Camera.main.transform;
speedFloat = Animator.StringToHash("Speed");
// fly
groundedBool = Animator.StringToHash("Grounded");
//distToGround = GetComponent<Collider>().bounds.extents.y;
rb = GetComponent<Rigidbody>();
}
bool IsGrounded()
{
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
}
void Update()
{
h = Input.GetAxis("Horizontal");
v = Input.GetAxis("Vertical");
run = Input.GetButton("Run");
sprint = Input.GetButton("Sprint");
isMoving = Mathf.Abs(h) > 0.1 || Mathf.Abs(v) > 0.1;
MovementManagement(h, v, run, sprint);
Moving();
}
void FixedUpdate()
{
//Rigidbody rb = GetComponent<Rigidbody>();
//rb.MovePosition(transform.position + transform.forward * speed);
//rb.velocity = Vector3.forward * speed;
}
void MovementManagement(float horizontal, float vertical, bool running, bool sprinting)
{
Rotating(horizontal, vertical);
if (isMoving)
{
if (sprinting)
{
speed = sprintSpeed;
anim.SetBool("isSprinting", true);
}
else
{
speed = runSpeed;
anim.SetBool("isRunning", true);
anim.SetBool("isSprinting", false);
}
}
else
{
speed = 0f;
anim.SetBool("isRunning", false);
anim.SetBool("isSprinting", false);
}
}
// Abracababra begins
Vector3 Rotating(float horizontal, float vertical)
{
Vector3 forward = cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0.0f;
forward = forward.normalized;
Vector3 right = new Vector3(forward.z, 0, -forward.x);
Vector3 targetDirection;
float finalTurnSmoothing;
targetDirection = forward * vertical + right * horizontal;
finalTurnSmoothing = turnSmoothing;
if ((isMoving && targetDirection != Vector3.zero))
{
Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
Quaternion newRotation = Quaternion.Slerp(GetComponent<Rigidbody>().rotation, targetRotation, finalTurnSmoothing * Time.deltaTime);
GetComponent<Rigidbody>().MoveRotation(newRotation);
lastDirection = targetDirection;
}
if (!(Mathf.Abs(h) > 0.9 || Mathf.Abs(v) > 0.9))
{
Repositioning();
}
return targetDirection;
}
private void Repositioning()
{
Vector3 repositioning = lastDirection;
if (repositioning != Vector3.zero)
{
repositioning.y = 0;
Quaternion targetRotation = Quaternion.LookRotation(repositioning, Vector3.up);
Quaternion newRotation = Quaternion.Slerp(GetComponent<Rigidbody>().rotation, targetRotation, turnSmoothing * Time.deltaTime);
GetComponent<Rigidbody>().MoveRotation(newRotation);
}
}
// Abracadabra ends
private void Moving()
{
//transform.position += transform.forward * Time.deltaTime * speed;
//Vector3 movement = new Vector3(h, 0.0f, v);
//GetComponent<Rigidbody>().velocity = transform.forward * speed;
transform.position += transform.forward * Time.deltaTime * speed;
rb.AddForce(transform.forward);
}
}
I hope I gave enough information, please tell me if I didn't. Thanks for helping.
Greetings,
Thijs
Answer by Thijsx7 · Dec 17, 2016 at 03:34 PM
I solved the problem myself. It seemed that the root motion blocked the rotation of the rigidbody. I don't understand why but changing:
GetComponent<Rigidbody>().MoveRotation(newRotation);
To:
transform.rotation = newRotation;
worked. My character is now able to turn again. I am just leaving this here so people who have the same problem as me might be able to fix it too.
Greetings,
Thijs