BasicPlatformerController.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /******************************************************************************
  2. * Spine Runtimes Software License
  3. * Version 2.1
  4. *
  5. * Copyright (c) 2013, Esoteric Software
  6. * All rights reserved.
  7. *
  8. * You are granted a perpetual, non-exclusive, non-sublicensable and
  9. * non-transferable license to install, execute and perform the Spine Runtimes
  10. * Software (the "Software") solely for internal use. Without the written
  11. * permission of Esoteric Software (typically granted by licensing Spine), you
  12. * may not (a) modify, translate, adapt or otherwise create derivative works,
  13. * improvements of the Software or develop new applications using the Software
  14. * or (b) remove, delete, alter or obscure any trademarks or any copyright,
  15. * trademark, patent or other intellectual property or proprietary rights
  16. * notices on or in the Software, including any copy thereof. Redistributions
  17. * in binary or source form must include this license and terms.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *****************************************************************************/
  30. /*****************************************************************************
  31. * Basic Platformer Controller created by Mitch Thompson
  32. * Full irrevocable rights and permissions granted to Esoteric Software
  33. *****************************************************************************/
  34. using UnityEngine;
  35. using System.Collections;
  36. [RequireComponent(typeof(CharacterController))]
  37. public class BasicPlatformerController : MonoBehaviour {
  38. #if UNITY_4_5
  39. [Header("Controls")]
  40. #endif
  41. public string XAxis = "Horizontal";
  42. public string YAxis = "Vertical";
  43. public string JumpButton = "Jump";
  44. #if UNITY_4_5
  45. [Header("Moving")]
  46. #endif
  47. public float walkSpeed = 4;
  48. public float runSpeed = 10;
  49. public float gravity = 65;
  50. #if UNITY_4_5
  51. [Header("Jumping")]
  52. #endif
  53. public float jumpSpeed = 25;
  54. public float jumpDuration = 0.5f;
  55. public float jumpInterruptFactor = 100;
  56. public float forceCrouchVelocity = 25;
  57. public float forceCrouchDuration = 0.5f;
  58. #if UNITY_4_5
  59. [Header("Graphics")]
  60. #endif
  61. public Transform graphicsRoot;
  62. public SkeletonAnimation skeletonAnimation;
  63. #if UNITY_4_5
  64. [Header("Animation")]
  65. #endif
  66. public string walkName = "Walk";
  67. public string runName = "Run";
  68. public string idleName = "Idle";
  69. public string jumpName = "Jump";
  70. public string fallName = "Fall";
  71. public string crouchName = "Crouch";
  72. #if UNITY_4_5
  73. [Header("Audio")]
  74. #endif
  75. public AudioSource jumpAudioSource;
  76. public AudioSource hardfallAudioSource;
  77. public AudioSource footstepAudioSource;
  78. public string footstepEventName = "Footstep";
  79. CharacterController controller;
  80. Vector2 velocity = Vector2.zero;
  81. Vector2 lastVelocity = Vector2.zero;
  82. bool lastGrounded = false;
  83. float jumpEndTime = 0;
  84. bool jumpInterrupt = false;
  85. float forceCrouchEndTime;
  86. Quaternion flippedRotation = Quaternion.Euler(0, 180, 0);
  87. void Awake () {
  88. controller = GetComponent<CharacterController>();
  89. }
  90. void Start () {
  91. //register a callback for Spine Events (in this case, Footstep)
  92. skeletonAnimation.state.Event += HandleEvent;
  93. }
  94. void HandleEvent (Spine.AnimationState state, int trackIndex, Spine.Event e) {
  95. //play some sound if footstep event fired
  96. if (e.Data.Name == footstepEventName) {
  97. footstepAudioSource.Stop();
  98. footstepAudioSource.Play();
  99. }
  100. }
  101. void Update () {
  102. //control inputs
  103. float x = Input.GetAxis(XAxis);
  104. float y = Input.GetAxis(YAxis);
  105. //check for force crouch
  106. bool crouching = (controller.isGrounded && y < -0.5f) || (forceCrouchEndTime > Time.time);
  107. velocity.x = 0;
  108. //Calculate control velocity
  109. if (!crouching) {
  110. if (Input.GetButtonDown(JumpButton) && controller.isGrounded) {
  111. //jump
  112. jumpAudioSource.Stop();
  113. jumpAudioSource.Play();
  114. velocity.y = jumpSpeed;
  115. jumpEndTime = Time.time + jumpDuration;
  116. } else if (Time.time < jumpEndTime && Input.GetButtonUp(JumpButton)) {
  117. jumpInterrupt = true;
  118. }
  119. if (x != 0) {
  120. //walk or run
  121. velocity.x = Mathf.Abs(x) > 0.6f ? runSpeed : walkSpeed;
  122. velocity.x *= Mathf.Sign(x);
  123. }
  124. if (jumpInterrupt) {
  125. //interrupt jump and smoothly cut Y velocity
  126. if (velocity.y > 0) {
  127. velocity.y = Mathf.MoveTowards(velocity.y, 0, Time.deltaTime * 100);
  128. } else {
  129. jumpInterrupt = false;
  130. }
  131. }
  132. }
  133. //apply gravity F = mA (Learn it, love it, live it)
  134. velocity.y -= gravity * Time.deltaTime;
  135. //move
  136. controller.Move(new Vector3(velocity.x, velocity.y, 0) * Time.deltaTime);
  137. if (controller.isGrounded) {
  138. //cancel out Y velocity if on ground
  139. velocity.y = -gravity * Time.deltaTime;
  140. jumpInterrupt = false;
  141. }
  142. Vector2 deltaVelocity = lastVelocity - velocity;
  143. if (!lastGrounded && controller.isGrounded) {
  144. //detect hard fall
  145. if ((gravity * Time.deltaTime) - deltaVelocity.y > forceCrouchVelocity) {
  146. forceCrouchEndTime = Time.time + forceCrouchDuration;
  147. hardfallAudioSource.Play();
  148. } else {
  149. //play footstep audio if light fall because why not
  150. footstepAudioSource.Play();
  151. }
  152. }
  153. //graphics updates
  154. if (controller.isGrounded) {
  155. if (crouching) { //crouch
  156. skeletonAnimation.AnimationName = crouchName;
  157. } else {
  158. if (x == 0) //idle
  159. skeletonAnimation.AnimationName = idleName;
  160. else //move
  161. skeletonAnimation.AnimationName = Mathf.Abs(x) > 0.6f ? runName : walkName;
  162. }
  163. } else {
  164. if (velocity.y > 0) //jump
  165. skeletonAnimation.AnimationName = jumpName;
  166. else //fall
  167. skeletonAnimation.AnimationName = fallName;
  168. }
  169. //flip left or right
  170. if (x > 0)
  171. graphicsRoot.localRotation = Quaternion.identity;
  172. else if (x < 0)
  173. graphicsRoot.localRotation = flippedRotation;
  174. //store previous state
  175. lastVelocity = velocity;
  176. lastGrounded = controller.isGrounded;
  177. }
  178. }