Advertisement
Guest User

RigidbodyFirstPersonController.cs

a guest
Jun 30th, 2015
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.82 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using UnityStandardAssets.CrossPlatformInput;
  4.  
  5. namespace UnityStandardAssets.Characters.FirstPerson
  6. {
  7.     [RequireComponent(typeof (Rigidbody))]
  8.     [RequireComponent(typeof (CapsuleCollider))]
  9.     public class RigidbodyFirstPersonController : MonoBehaviour
  10.     {
  11.         [Serializable]
  12.         public class MovementSettings
  13.         {
  14.             public float ForwardSpeed = 8.0f;   // Speed when walking forward
  15.             public float BackwardSpeed = 4.0f;  // Speed when walking backwards
  16.             public float StrafeSpeed = 4.0f;    // Speed when walking sideways
  17.             public float RunMultiplier = 2.0f;   // Speed when sprinting
  18.             public KeyCode RunKey = KeyCode.LeftShift;
  19.             public float JumpForce = 30f;
  20.             public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
  21.             [HideInInspector] public float CurrentTargetSpeed = 8f;
  22.  
  23. #if !MOBILE_INPUT
  24.             private bool m_Running;
  25. #endif
  26.  
  27.             public void UpdateDesiredTargetSpeed(Vector2 input)
  28.             {
  29.                 if (input == Vector2.zero) return;
  30.                 if (input.x > 0 || input.x < 0)
  31.                 {
  32.                     //strafe
  33.                     CurrentTargetSpeed = StrafeSpeed;
  34.                 }
  35.                 if (input.y < 0)
  36.                 {
  37.                     //backwards
  38.                     CurrentTargetSpeed = BackwardSpeed;
  39.                 }
  40.                 if (input.y > 0)
  41.                 {
  42.                     //forwards
  43.                     //handled last as if strafing and moving forward at the same time forwards speed should take precedence
  44.                     CurrentTargetSpeed = ForwardSpeed;
  45.                 }
  46. #if !MOBILE_INPUT
  47.                 if (Input.GetKey(RunKey))
  48.                 {
  49.                     CurrentTargetSpeed *= RunMultiplier;
  50.                     m_Running = true;
  51.                 }
  52.                 else
  53.                 {
  54.                     m_Running = false;
  55.                 }
  56. #endif
  57.             }
  58.  
  59. #if !MOBILE_INPUT
  60.             public bool Running
  61.             {
  62.                 get { return m_Running; }
  63.             }
  64. #endif
  65.         }
  66.  
  67.  
  68.         [Serializable]
  69.         public class AdvancedSettings
  70.         {
  71.             public float groundCheckDistance = 0.01f; // distance for checking if the controller is grounded ( 0.01f seems to work best for this )
  72.             public float stickToGroundHelperDistance = 0.5f; // stops the character
  73.             public float slowDownRate = 20f; // rate at which the controller comes to a stop when there is no input
  74.             public bool airControl; // can the user control the direction that is being moved in the air
  75.         }
  76.  
  77.  
  78.         public Camera cam;
  79.         public MovementSettings movementSettings = new MovementSettings();
  80.         public MouseLook mouseLook = new MouseLook();
  81.         public AdvancedSettings advancedSettings = new AdvancedSettings();
  82.  
  83.  
  84.         private Rigidbody m_RigidBody;
  85.         private CapsuleCollider m_Capsule;
  86.         private float m_YRotation;
  87.         private Vector3 m_GroundContactNormal;
  88.         private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsGrounded;
  89.  
  90.  
  91.         public Vector3 Velocity
  92.         {
  93.             get { return m_RigidBody.velocity; }
  94.         }
  95.  
  96.         public bool Grounded
  97.         {
  98.             get { return m_IsGrounded; }
  99.         }
  100.  
  101.         public bool Jumping
  102.         {
  103.             get { return m_Jumping; }
  104.         }
  105.  
  106.         public bool Running
  107.         {
  108.             get
  109.             {
  110.  #if !MOBILE_INPUT
  111.                 return movementSettings.Running;
  112. #else
  113.                 return false;
  114. #endif
  115.             }
  116.         }
  117.  
  118.  
  119.         private void Start()
  120.         {
  121.             m_RigidBody = GetComponent<Rigidbody>();
  122.             m_Capsule = GetComponent<CapsuleCollider>();
  123.             mouseLook.Init (transform, cam.transform);
  124.         }
  125.  
  126.  
  127.         private void Update()
  128.         {
  129.             RotateView();
  130.  
  131.             if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
  132.             {
  133.                 m_Jump = true;
  134.             }
  135.         }
  136.  
  137.  
  138.         private void FixedUpdate()
  139.         {
  140.             GroundCheck();
  141.             Vector2 input = GetInput();
  142.  
  143.             if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
  144.             {
  145.                 // always move along the camera forward as it is the direction that it being aimed at
  146.                 Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
  147.                 desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;
  148.  
  149.                 desiredMove.x = desiredMove.x*movementSettings.CurrentTargetSpeed;
  150.                 desiredMove.z = desiredMove.z*movementSettings.CurrentTargetSpeed;
  151.                 desiredMove.y = desiredMove.y*movementSettings.CurrentTargetSpeed;
  152.                 if (m_RigidBody.velocity.sqrMagnitude <
  153.                     (movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
  154.                 {
  155.                     m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
  156.                 }
  157.             }
  158.  
  159.             if (m_IsGrounded)
  160.             {
  161.                 m_RigidBody.drag = 5f;
  162.  
  163.                 if (m_Jump)
  164.                 {
  165.                     m_RigidBody.drag = 0f;
  166.                     m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
  167.                     m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
  168.                     m_Jumping = true;
  169.                 }
  170.  
  171.                 if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
  172.                 {
  173.                     m_RigidBody.Sleep();
  174.                 }
  175.             }
  176.             else
  177.             {
  178.                 m_RigidBody.drag = 0f;
  179.                 if (m_PreviouslyGrounded && !m_Jumping)
  180.                 {
  181.                     StickToGroundHelper();
  182.                 }
  183.             }
  184.             m_Jump = false;
  185.         }
  186.  
  187.  
  188.         private float SlopeMultiplier()
  189.         {
  190.             float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
  191.             return movementSettings.SlopeCurveModifier.Evaluate(angle);
  192.         }
  193.  
  194.  
  195.         private void StickToGroundHelper()
  196.         {
  197.             RaycastHit hitInfo;
  198.             if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
  199.                                    ((m_Capsule.height/2f) - m_Capsule.radius) +
  200.                                    advancedSettings.stickToGroundHelperDistance))
  201.             {
  202.                 if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f)
  203.                 {
  204.                     m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
  205.                 }
  206.             }
  207.         }
  208.  
  209.  
  210.         private Vector2 GetInput()
  211.         {
  212.            
  213.             Vector2 input = new Vector2
  214.                 {
  215.                     x = CrossPlatformInputManager.GetAxis("Horizontal"),
  216.                     y = CrossPlatformInputManager.GetAxis("Vertical")
  217.                 };
  218.             movementSettings.UpdateDesiredTargetSpeed(input);
  219.             return input;
  220.         }
  221.  
  222.  
  223.         private void RotateView()
  224.         {
  225.             //avoids the mouse looking if the game is effectively paused
  226.             if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;
  227.  
  228.             // get the rotation before it's changed
  229.             float oldYRotation = transform.eulerAngles.y;
  230.  
  231.             mouseLook.LookRotation (transform, cam.transform);
  232.  
  233.             if (m_IsGrounded || advancedSettings.airControl)
  234.             {
  235.                 // Rotate the rigidbody velocity to match the new direction that the character is looking
  236.                 Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
  237.                 m_RigidBody.velocity = velRotation*m_RigidBody.velocity;
  238.             }
  239.         }
  240.  
  241.  
  242.         /// sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
  243.         private void GroundCheck()
  244.         {
  245.             m_PreviouslyGrounded = m_IsGrounded;
  246.             RaycastHit hitInfo;
  247.             if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
  248.                                    ((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance))
  249.             {
  250.                 m_IsGrounded = true;
  251.                 m_GroundContactNormal = hitInfo.normal;
  252.             }
  253.             else
  254.             {
  255.                 m_IsGrounded = false;
  256.                 m_GroundContactNormal = Vector3.up;
  257.             }
  258.             if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
  259.             {
  260.                 m_Jumping = false;
  261.             }
  262.         }
  263.     }
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement