- Home /
Save my WEEK: Converting root motion controller script into jetpack controller script
This is driving me crazy:
I'm using this player controller that uses root motion to move and rotate the player (using single joystick). I'm struggling to convert this code into jetpack controller. Because while player is using jetpack I don't want it to have any animations. And since there's no animation player moves nowhere. If I disable root motion (locomotion system) or whatever it's called, I can use rigidbody velocity to move player forward and up but what I've been struggling for the past 4 days or so is how to change the rotation taken from animation into something that rotates player without animations. I think the problem is that when using animation to turn player will keep making this big circle instead of turning around own y-axis. I got this script by following youtube tutorial and I don't understand much about it. I just hope there's some guru that understands what I mean and can help me out.
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using System.Collections;
public class CharacterControllerLogic : MonoBehaviour {
[SerializeField]
private Animator animator;
[SerializeField]
private float directionDampTime = .25f;
[SerializeField]
private ThirdPersonCamera gamecam;
[SerializeField]
private float directionSpeed = 3.0f;
[SerializeField]
private float rotationDegreePerSecond = 120f;
// private global only
private float horizontal = 0.0f;
private float vertical = 0.0f;
private float speed = 0.0f;
private float direction = 0.0f;
private AnimatorStateInfo stateInfo;
private Rigidbody rb;
// jump
public bool grounded = true;
public float distToGrounded = .1f;
public float jumpSpeed;
public LayerMask ground;
RaycastHit hit = new RaycastHit();
public bool allowGrounding = false;
// hashes
private int m_LocomotionId = 0;
// Use this for initialization
void Start () {
if (GetComponent<Animator> ()) {
animator = GetComponent<Animator> ();
} else {
Debug.LogError ("Player needs an animator.");
}
if (animator.layerCount >= 2) {
animator.SetLayerWeight (1, 1);
}
if (GetComponent<Rigidbody> ()) {
rb = GetComponent<Rigidbody> ();
} else {
Debug.LogError ("Player needs to have a rigidbody.");
}
m_LocomotionId = Animator.StringToHash ("Base Layer.Locomotion");
}
// Update is called once per frame
void Update () {
horizontal = CrossPlatformInputManager.GetAxis ("Horizontal");
vertical = CrossPlatformInputManager.GetAxis ("Vertical");
if (grounded && CrossPlatformInputManager.GetButtonDown ("Jump") || grounded && Input.GetKeyDown (KeyCode.Space)) {
grounded = false;
rb.velocity = Vector3.up * jumpSpeed;
animator.SetBool ("Jump", true);
} else if (grounded) {
// MOVE ON GROUND
//rb.velocity = Vector3.up * 0;
animator.SetBool ("Jump", false);
stateInfo = animator.GetCurrentAnimatorStateInfo (0);
speed = new Vector2 (horizontal, vertical).sqrMagnitude;
// Translate controls stick coordinates into world/character space
StickToWorldSpace (this.transform, gamecam.transform, ref direction, ref speed);
animator.SetFloat ("Speed", speed);
animator.SetFloat ("Direction", direction, directionDampTime, Time.deltaTime);
} else if(!grounded) {
// FALLING / JUMP SUCCESSFULL
if (DistanceToGround () > distToGrounded) {
// if we are higher up from the ground than distToGrounded
allowGrounding = true;
}
if (allowGrounding) {
// player has jumped more than value of distToGrounded from the ground
// we can start checking when player lands
grounded = Grounded();
if (grounded) // allow player to jump and land again
allowGrounding = false;
}
}
}
void FixedUpdate(){
// if player is not using jetpack or car
if (IsInLocomotion () && ((direction >= 0 && horizontal >= 0) || (direction < 0 && horizontal < 0))) {
Vector3 rotationAmount = Vector3.Lerp (Vector3.zero, new Vector3 (0f, rotationDegreePerSecond * (horizontal < 0f ? -1f : 1f), 0f), Mathf.Abs (horizontal));
Quaternion deltaRotation = Quaternion.Euler (rotationAmount * Time.deltaTime);
this.transform.rotation = (this.transform.rotation * deltaRotation);
}
}
public void StickToWorldSpace(Transform root, Transform camera, ref float directionOut, ref float speedOut){
Vector3 rootDirection = root.forward;
Vector3 stickDirection = new Vector3 (horizontal, 0, vertical);
speedOut = stickDirection.sqrMagnitude;
// Get camera rotation
Vector3 CameraDirection = camera.forward;
CameraDirection.y = .0f;
Quaternion referentialShift = Quaternion.FromToRotation(Vector3.forward, CameraDirection);
// Convert joystick input in Worldspace coordinates
Vector3 moveDirection = referentialShift * stickDirection;
Vector3 axisSign = Vector3.Cross (moveDirection, rootDirection);
float angleRootToMove = Vector3.Angle (rootDirection, moveDirection) * (axisSign.y >= 0 ? -1f : 1f);
angleRootToMove /= 180f;
directionOut = angleRootToMove * directionSpeed;
}
public bool IsInLocomotion(){
return stateInfo.shortNameHash == m_LocomotionId;
}
public bool Grounded(){
return Physics.Raycast (transform.position, Vector3.down, distToGrounded, ground);
}
public float DistanceToGround(){
if(Physics.Raycast (transform.position, Vector3.down, out hit)) {
return hit.distance;
}
return 10.0f;
}
}