Advertisement
msbranin

CharacterController2D.cs

Jul 6th, 2014
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.08 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class CharacterController2D : MonoBehaviour
  5. {
  6. private const float SkinWidth = .02f;
  7. private const int TotalHorizontalRays = 8;
  8. private const int TotalVerticalRays = 4;
  9.  
  10. private static readonly float SlopeLimitTangant = Mathf.Tan (75f* Mathf.Deg2Rad);
  11.  
  12. public LayerMask PlatformMask;
  13. public ControllerParameters2D DefaultParameters;
  14.  
  15. public ControllerState2D State { get; private set; }
  16. public Vector2 Velocity { get { return _velocity; } }
  17. public bool HandleCollisions { get; set; }
  18. public ControllerParameters2D Parameters { get { return _overrideParameters ?? DefaultParameters; } }
  19. public GameObject StandingOn { get; private set; }
  20. public bool CanJump
  21. {
  22. get
  23. {
  24. if (Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpAnywhere)
  25. return _jumpIn <= 0;
  26.  
  27. if (Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpOnGround)
  28. return State.IsGrounded;
  29.  
  30. return false;
  31. }
  32. }
  33.  
  34. private Vector2 _velocity;
  35. private Transform _transform;
  36. private Vector3 _localScale;
  37. private BoxCollider2D _boxCollider;
  38. private ControllerParameters2D _overrideParameters;
  39. private float _jumpIn;
  40.  
  41. private Vector3
  42. _raycastTopLeft,
  43. _raycastBottomRight,
  44. _raycastBottomLeft;
  45.  
  46. private float
  47. _verticalDistanceBetweenRays,
  48. _horizontalDistanceBetweenRays;
  49.  
  50. public void Awake()
  51. {
  52. HandleCollisions = true;
  53. State = new ControllerState2D();
  54. _transform = transform;
  55. _localScale = transform.localScale;
  56. _boxCollider = GetComponent<BoxCollider2D>();
  57.  
  58. var colliderWidth = _boxCollider.size.x * Mathf.Abs (transform.localScale.x) - (2 * SkinWidth);
  59. _horizontalDistanceBetweenRays = colliderWidth / (TotalVerticalRays - 1);
  60.  
  61. var ColliderHeight = _boxCollider.size.y * Mathf.Abs(transform.localScale.y) - (2 * SkinWidth);
  62. _verticalDistanceBetweenRays = ColliderHeight / (TotalHorizontalRays - 1);
  63. }
  64.  
  65. public void AddForce(Vector2 force)
  66. {
  67. _velocity += force;
  68. }
  69.  
  70. public void SetForce(Vector2 force)
  71. {
  72. _velocity = force;
  73. }
  74.  
  75. public void SetHorizontalForce(float x)
  76. {
  77. _velocity.x = x;
  78. }
  79.  
  80. public void SetVerticalForce (float y)
  81. {
  82. _velocity.y = y;
  83. }
  84.  
  85. public void Jump()
  86. {
  87. // TODO: Moving platform Support
  88. AddForce(new Vector2(0, Parameters.JumpMagnitude));
  89. _jumpIn = Parameters.JumpFrequency;
  90. }
  91.  
  92. public void LateUpdate()
  93. {
  94. _jumpIn -= Time.deltaTime;
  95. _velocity.y += Parameters.Gravity * Time.deltaTime;
  96. Move(Velocity * Time.deltaTime);
  97.  
  98. }
  99.  
  100. private void Move(Vector2 deltaMovement)
  101. {
  102. var wasGrounded = State.IsCollidingBelow;
  103. State.Reset();
  104.  
  105. if (HandleCollisions)
  106. {
  107. HandlePlatforms();
  108. CalculateRayOrigins();
  109.  
  110. if (deltaMovement.y < 0 && wasGrounded)
  111. HandleVerticalSlope(ref deltaMovement);
  112.  
  113. if (Mathf.Abs(deltaMovement.x) > .001f)
  114. MoveHorizontally(ref deltaMovement);
  115.  
  116. MoveVertically(ref deltaMovement);
  117. }
  118.  
  119. _transform.Translate(deltaMovement, Space.World);
  120.  
  121. // TODO: Additional moving platform code
  122.  
  123. if (Time.deltaTime > 0)
  124. _velocity = deltaMovement / Time.deltaTime;
  125.  
  126. _velocity.x = Mathf.Min(_velocity.x, Parameters.MaxVelocity.x);
  127. _velocity.y = Mathf.Min(_velocity.y, Parameters.MaxVelocity.y);
  128.  
  129. if (State.IsMovingUpSlope)
  130. _velocity.y = 0;
  131. }
  132.  
  133. private void HandlePlatforms()
  134. {
  135.  
  136. }
  137.  
  138. private void CalculateRayOrigins()
  139. {
  140. var size = new Vector2(_boxCollider.size.x * Mathf.Abs(_localScale.x), _boxCollider.size.y * Mathf.Abs(_localScale.y)) / 2;
  141. var center = new Vector2(_boxCollider.center.x * _localScale.x, _boxCollider.center.y * _localScale.y);
  142.  
  143. _raycastTopLeft = _transform.position + new Vector3(center.x - size.x + SkinWidth, center.y + size.y - SkinWidth);
  144. _raycastBottomRight = _transform.position + new Vector3(center.x + size.x - SkinWidth, center.y - size.y + SkinWidth);
  145. _raycastBottomLeft = _transform.position + new Vector3(center.x - size.x + SkinWidth, center.y - size.y + SkinWidth);
  146. }
  147.  
  148. private void MoveHorizontally(ref Vector2 deltaMovement)
  149. {
  150. var isGoingRight = deltaMovement.x > 0;
  151. var rayDistance = Mathf.Abs(deltaMovement.x) + SkinWidth;
  152. var rayDirection = isGoingRight ? Vector2.right : -Vector2.right;
  153. var rayOrigin = isGoingRight ? _raycastBottomRight : _raycastBottomLeft;
  154.  
  155. for (var i = 0; i < TotalHorizontalRays; i++)
  156. {
  157. var rayVector = new Vector2(rayOrigin.x, rayOrigin.y + (i * _verticalDistanceBetweenRays));
  158. Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
  159.  
  160. var rayCastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
  161. if (!rayCastHit)
  162. continue;
  163.  
  164.  
  165. if (i == 0 && HandleHorizontalSlope(ref deltaMovement, Vector2.Angle(rayCastHit.normal, Vector2.up), isGoingRight))
  166. break;
  167.  
  168. deltaMovement.x = rayCastHit.point.x - rayVector.x;
  169. rayDistance = Mathf.Abs(deltaMovement.x);
  170.  
  171. if (isGoingRight)
  172. {
  173. deltaMovement.x -= SkinWidth;
  174. State.IsCollidingRight = true;
  175. }
  176. else
  177. {
  178. deltaMovement.x += SkinWidth;
  179. State.IsCollidingLeft = true;
  180. }
  181.  
  182. if (rayDistance < SkinWidth + .0001f)
  183. break;
  184. }
  185. }
  186.  
  187. private void MoveVertically(ref Vector2 deltaMovement)
  188. {
  189. var isGoingUp = deltaMovement.y > 0;
  190. var rayDistance = Mathf.Abs(deltaMovement.y) + SkinWidth;
  191. var rayDirection = isGoingUp ? Vector2.up : -Vector2.up;
  192. var rayOrigin = isGoingUp ? _raycastTopLeft : _raycastBottomLeft;
  193.  
  194. rayOrigin.x += deltaMovement.x;
  195.  
  196. var standingOnDistance = float.MaxValue;
  197. for (var i = 0; i < TotalVerticalRays; i++)
  198. {
  199. var rayVector = new Vector2(rayOrigin.x + (i * _horizontalDistanceBetweenRays), rayOrigin.y);
  200. Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
  201.  
  202. var raycastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
  203. if (!raycastHit)
  204. continue;
  205.  
  206. if (!isGoingUp)
  207. {
  208. var verticalDistanceToHit = _transform.position.y - raycastHit.point.y;
  209. if (verticalDistanceToHit < standingOnDistance)
  210. {
  211. standingOnDistance = verticalDistanceToHit;
  212. StandingOn = raycastHit.collider.gameObject;
  213. }
  214. }
  215.  
  216. deltaMovement.y = raycastHit.point.y - rayVector.y;
  217. rayDistance = Mathf.Abs(deltaMovement.y);
  218.  
  219. if (isGoingUp)
  220. {
  221. deltaMovement.y -= SkinWidth;
  222. State.IsCollidingAbove = true;
  223. }
  224. else
  225. {
  226. deltaMovement.y += SkinWidth;
  227. State.IsCollidingBelow = true;
  228. }
  229.  
  230. if (!isGoingUp && deltaMovement.y > .0001f)
  231. State.IsMovingUpSlope = true;
  232.  
  233. if (rayDistance < SkinWidth + .0001f)
  234. break;
  235.  
  236. }
  237.  
  238. }
  239.  
  240. private void HandleVerticalSlope(ref Vector2 deltaMovement)
  241. {
  242. var center = (_raycastBottomLeft.x + _raycastBottomRight.x) / 2;
  243. var direction = -Vector2.up;
  244.  
  245. var slopeDistance = SlopeLimitTangant * (_raycastBottomRight.x - center);
  246. var slopeRayVector = new Vector2(center, _raycastBottomLeft.x);
  247.  
  248. Debug.DrawRay(slopeRayVector, direction * slopeDistance, Color.yellow);
  249. }
  250.  
  251. private bool HandleHorizontalSlope(ref Vector2 deltaMovement, float angle, bool isGoingRight)
  252. {
  253. return false;
  254. }
  255.  
  256. public void OnTriggerEnter2D(Collider2D other)
  257. {
  258.  
  259. }
  260.  
  261. public void OnTriggerExit2D(Collider2D other)
  262. {
  263.  
  264. }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement