kriNon

Untitled

Nov 11th, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.23 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. namespace UnityStandardAssets.Characters.ThirdPerson
  4. {
  5. [RequireComponent(typeof(Rigidbody))]
  6. [RequireComponent(typeof(CapsuleCollider))]
  7. [RequireComponent(typeof(Animator))]
  8. public class ThirdPersonCharacter : MonoBehaviour
  9. {
  10. [SerializeField] float m_MovingTurnSpeed = 360;
  11. [SerializeField] float m_StationaryTurnSpeed = 180;
  12. [SerializeField] float m_JumpPower = 12f;
  13. [Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
  14. [SerializeField] float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others
  15. [SerializeField] float m_MoveSpeedMultiplier = 1f;
  16. [SerializeField] float m_AnimSpeedMultiplier = 1f;
  17. [SerializeField] float m_GroundCheckDistance = 0.1f;
  18.  
  19. Rigidbody m_Rigidbody;
  20. Animator m_Animator;
  21. bool m_IsGrounded = true;
  22. float m_OrigGroundCheckDistance;
  23. const float k_Half = 0.5f;
  24. float m_TurnAmount;
  25. float m_ForwardAmount;
  26. Vector3 m_GroundNormal;
  27. float m_CapsuleHeight;
  28. Vector3 m_CapsuleCenter;
  29. CapsuleCollider m_Capsule;
  30. bool m_Crouching;
  31.  
  32.  
  33. void Start()
  34. {
  35. m_Animator = GetComponent<Animator>();
  36. m_Rigidbody = GetComponent<Rigidbody>();
  37. m_Capsule = GetComponent<CapsuleCollider>();
  38. m_CapsuleHeight = m_Capsule.height;
  39. m_CapsuleCenter = m_Capsule.center;
  40.  
  41. m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
  42. m_OrigGroundCheckDistance = m_GroundCheckDistance;
  43. }
  44.  
  45.  
  46. public void Move(Vector3 move, bool crouch, bool jump)
  47. {
  48.  
  49. // convert the world relative moveInput vector into a local-relative
  50. // turn amount and forward amount required to head in the desired
  51. // direction.
  52. if (move.magnitude > 1f) move.Normalize();
  53. move = transform.InverseTransformDirection(move);
  54. CheckGroundStatus();
  55. move = Vector3.ProjectOnPlane(move, m_GroundNormal);
  56. m_TurnAmount = Mathf.Atan2(move.x, move.z);
  57. m_ForwardAmount = move.z;
  58.  
  59. ApplyExtraTurnRotation();
  60.  
  61. // control and velocity handling is different when grounded and airborne:
  62. if (m_IsGrounded)
  63. {
  64. HandleGroundedMovement(crouch, jump);
  65. }
  66. else
  67. {
  68. HandleAirborneMovement();
  69. }
  70.  
  71. ScaleCapsuleForCrouching(crouch);
  72. PreventStandingInLowHeadroom();
  73.  
  74. // send input and other state parameters to the animator
  75. UpdateAnimator(move);
  76. }
  77.  
  78.  
  79. void ScaleCapsuleForCrouching(bool crouch)
  80. {
  81. if (m_IsGrounded && crouch)
  82. {
  83. if (m_Crouching) return;
  84. m_Capsule.height = m_Capsule.height / 2f;
  85. m_Capsule.center = m_Capsule.center / 2f;
  86. m_Crouching = true;
  87. }
  88. else
  89. {
  90. Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
  91. float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
  92. if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
  93. {
  94. m_Crouching = true;
  95. return;
  96. }
  97. m_Capsule.height = m_CapsuleHeight;
  98. m_Capsule.center = m_CapsuleCenter;
  99. m_Crouching = false;
  100. }
  101. }
  102.  
  103. void PreventStandingInLowHeadroom()
  104. {
  105. // prevent standing up in crouch-only zones
  106. if (!m_Crouching)
  107. {
  108. Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
  109. float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
  110. if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
  111. {
  112. m_Crouching = true;
  113. }
  114. }
  115. }
  116.  
  117.  
  118. void UpdateAnimator(Vector3 move)
  119. {
  120. // update the animator parameters
  121. m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
  122. m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
  123. m_Animator.SetBool("Crouch", m_Crouching);
  124. m_Animator.SetBool("OnGround", m_IsGrounded);
  125. if (!m_IsGrounded)
  126. {
  127. m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
  128. }
  129.  
  130. // calculate which leg is behind, so as to leave that leg trailing in the jump animation
  131. // (This code is reliant on the specific run cycle offset in our animations,
  132. // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
  133. float runCycle =
  134. Mathf.Repeat(
  135. m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
  136. float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
  137. if (m_IsGrounded)
  138. {
  139. m_Animator.SetFloat("JumpLeg", jumpLeg);
  140. }
  141.  
  142. // the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,
  143. // which affects the movement speed because of the root motion.
  144. if (m_IsGrounded && move.magnitude > 0)
  145. {
  146. m_Animator.speed = m_AnimSpeedMultiplier;
  147. }
  148. else
  149. {
  150. // don't use that while airborne
  151. m_Animator.speed = 1;
  152. }
  153. }
  154.  
  155.  
  156. void HandleAirborneMovement()
  157. {
  158. // apply extra gravity from multiplier:
  159. Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity;
  160. m_Rigidbody.AddForce(extraGravityForce);
  161.  
  162. m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
  163. }
  164.  
  165.  
  166. void HandleGroundedMovement(bool crouch, bool jump)
  167. {
  168. // check whether conditions are right to allow a jump:
  169. if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
  170. {
  171. // jump!
  172. m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
  173. m_IsGrounded = false;
  174. m_Animator.applyRootMotion = false;
  175. m_GroundCheckDistance = 0.1f;
  176. }
  177. }
  178.  
  179. void ApplyExtraTurnRotation()
  180. {
  181. // help the character turn faster (this is in addition to root rotation in the animation)
  182. float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
  183. transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
  184. }
  185.  
  186.  
  187. public void OnAnimatorMove()
  188. {
  189. // we implement this function to override the default root motion.
  190. // this allows us to modify the positional speed before it's applied.
  191. if (m_IsGrounded && Time.deltaTime > 0)
  192. {
  193. Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime;
  194.  
  195. // we preserve the existing y part of the current velocity.
  196. v.y = m_Rigidbody.velocity.y;
  197. m_Rigidbody.velocity = v;
  198. }
  199. }
  200.  
  201.  
  202. void CheckGroundStatus()
  203. {
  204. RaycastHit hitInfo;
  205. #if UNITY_EDITOR
  206. // helper to visualise the ground check ray in the scene view
  207. Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
  208. #endif
  209. // 0.1f is a small offset to start the ray from inside the character
  210. // it is also good to note that the transform position in the sample assets is at the base of the character
  211. if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, 2))
  212. {
  213. m_GroundNormal = hitInfo.normal;
  214. m_Animator.applyRootMotion = true;
  215. //Debug.Log("Hi");
  216. }
  217. else
  218. {
  219. m_GroundNormal = Vector3.up;
  220. m_Animator.applyRootMotion = false;
  221. //Debug.Log("Hello");
  222. }
  223. }
  224. }
  225. }
Advertisement
Add Comment
Please, Sign In to add comment