Advertisement
SvOzMaS

CharacterAnimBasedMovement.cs

Mar 30th, 2019
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.50 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. [RequireComponent(typeof(CharacterController))]
  4. [RequireComponent(typeof(Animator))]
  5. public class CharacterAnimBasedMovement : MonoBehaviour {
  6.  
  7.     public float rotationSpeed = 4f;
  8.     public float rotationThreshold = 0.3f;
  9.     [Range(0, 180f)]
  10.     public float degreesToTurn = 160f;
  11.  
  12.     [Header("Animator Parameters")]
  13.     public string motionParam = "motion";
  14.     public string mirrorIdleParam = "mirrorIdle";
  15.     public string turn180Param = "turn180";
  16.  
  17.     [Header("Animation Smoothing")]
  18.     [Range(0, 1f)]
  19.     public float StartAnimTime = 0.3f;
  20.     [Range(0, 1f)]
  21.     public float StopAnimTime = 0.15f;
  22.  
  23.     [Header("Wall Detection")]
  24.     public LayerMask obstacleLayers;
  25.     public float wallStopThreshold = 30f;
  26.     public float wallStopDistance = 0.9f;
  27.     public float rayHeight = 0.5f;
  28.  
  29.     private Ray wallRay = new Ray();
  30.     private float Speed;
  31.     private Vector3 desiredMoveDirection;
  32.     private CharacterController characterController;
  33.     private Animator animator;
  34.     private bool mirrorIdle;
  35.     private bool turn180;
  36.  
  37.  
  38.     void Start() {
  39.         characterController = GetComponent<CharacterController>();
  40.         animator = GetComponent<Animator>();
  41.     }
  42.  
  43.  
  44.     public void moveCharacter(float hInput, float vInput, Camera cam, bool jump, bool dash) {
  45.  
  46.         //Calculate the Input Magnitude
  47.         Speed = new Vector2(hInput, vInput).normalized.sqrMagnitude;
  48.  
  49.         // Dash only if character has reached maxSpeed (animator parameter value)
  50.         if (Speed >= Speed - rotationThreshold && dash) {
  51.             Speed =  1.5f;
  52.         }
  53.  
  54.         //Physically move player
  55.         if (Speed > rotationThreshold) {
  56.            
  57.             Vector3 forward = cam.transform.forward;
  58.             Vector3 right = cam.transform.right;
  59.  
  60.             forward.y = 0f;
  61.             right.y = 0f;
  62.  
  63.             forward.Normalize();
  64.             right.Normalize();
  65.  
  66.             // Rotate the character towards desired move direction based on player input and camera position
  67.             desiredMoveDirection = forward * vInput + right * hInput;
  68.  
  69.             if (Vector3.Angle(transform.forward, desiredMoveDirection) >= degreesToTurn) {
  70.                 turn180 = true;
  71.             }
  72.             else {
  73.                 turn180 = false;
  74.                 transform.rotation = Quaternion.Slerp(transform.rotation,
  75.                                                   Quaternion.LookRotation(desiredMoveDirection),
  76.                                                   rotationSpeed * Time.deltaTime);
  77.             }
  78.  
  79.             // 180 turning
  80.             animator.SetBool(turn180Param, turn180);
  81.  
  82.             // Wall Detection
  83.             Vector3 rayOriging = transform.position;
  84.             rayOriging.y += rayHeight;
  85.  
  86.             wallRay.origin = rayOriging;
  87.             wallRay.direction = transform.forward;
  88.  
  89.             bool wallDetected = Vector3.Angle(transform.forward, desiredMoveDirection) < wallStopThreshold &&
  90.                            Physics.Raycast(wallRay, wallStopDistance, obstacleLayers);
  91.  
  92.             Debug.DrawRay(rayOriging, transform.forward, Color.red);
  93.  
  94.             if (wallDetected) {
  95.                 // Simple foot IK for idle animation
  96.                 animator.SetBool(mirrorIdleParam, mirrorIdle);
  97.                 // Stop the character
  98.                 animator.SetFloat(motionParam, 0f, StopAnimTime, Time.deltaTime);
  99.                 Debug.DrawRay(rayOriging, transform.forward, Color.yellow);
  100.             }
  101.             else
  102.                 // Move the character
  103.                 animator.SetFloat(motionParam, Speed, StartAnimTime, Time.deltaTime);
  104.  
  105.         }
  106.         else if (Speed < rotationThreshold) {
  107.  
  108.             // Simple foot IK for idle animation
  109.             animator.SetBool(mirrorIdleParam, mirrorIdle);
  110.             // Stop the character
  111.             animator.SetFloat(motionParam, 0f, StopAnimTime, Time.deltaTime);
  112.         }
  113.     }
  114.  
  115.    
  116.     private void OnAnimatorIK(int layerIndex) {
  117.  
  118.         if (Speed < rotationThreshold)
  119.             return;
  120.      
  121.         float distanceToLeftFoot = Vector3.Distance(transform.position, animator.GetIKPosition(AvatarIKGoal.LeftFoot));
  122.         float distanceToRightFoot = Vector3.Distance(transform.position, animator.GetIKPosition(AvatarIKGoal.RightFoot));
  123.  
  124.         // Right foot in front
  125.         if (distanceToRightFoot > distanceToLeftFoot) {
  126.             mirrorIdle = true;
  127.  
  128.         // Right foot behind
  129.         } else {
  130.             mirrorIdle = false;
  131.         }
  132.     }
  133.  
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement