Advertisement
Guest User

Untitled

a guest
Jul 16th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.44 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using NaughtyAttributes;
  5.  
  6. [RequireComponent(typeof(Rigidbody2D))]
  7. public class Patrol2D : MonoBehaviour
  8. {
  9. public enum FacingType
  10. {
  11. DontChange,
  12. Snap,
  13. Smooth
  14. }
  15.  
  16. public bool isPatrolling = true;
  17.  
  18. [Header("Movement")]
  19. public float speed = 5f;
  20.  
  21. [Header("Orientation")]
  22. public FacingType facingType = FacingType.DontChange;
  23. public float smoothFaceSpeed = 7f;
  24. public Directions lookAxis = Directions.Right;
  25.  
  26. [Header("Stops")]
  27.  
  28. [ReorderableList]
  29. public List<Vector2> waypoints;
  30.  
  31. public bool waitAtEachStop = false;
  32. public float waitTime = 1f;
  33. protected float currentWaitTime = 0f;
  34. protected bool isWaiting = false;
  35.  
  36. [Header("Preview")]
  37. public bool previewWaypoints = true;
  38. public float gizmoScale = 0.3f;
  39.  
  40. public static event Action<GameObject> OnReachedWaypoint = delegate { };
  41.  
  42. protected new Rigidbody2D rigidbody2D;
  43. protected Vector2[] newWaypoints;
  44. protected int currentTargetIndex;
  45.  
  46. protected virtual void Awake()
  47. {
  48. rigidbody2D = GetComponent<Rigidbody2D>();
  49. }
  50.  
  51. protected virtual void Start()
  52. {
  53. if(isPatrolling) InitializePatrol();
  54. }
  55.  
  56. protected virtual void InitializePatrol()
  57. {
  58. currentTargetIndex = 0;
  59.  
  60. newWaypoints = new Vector2[waypoints.Count + 1];
  61. int w = 0;
  62. for (int i = 0; i < waypoints.Count; i++)
  63. {
  64. newWaypoints[i] = waypoints[i];
  65. w = i;
  66. }
  67.  
  68. //Add the starting position at the end, only if there is at least another point in the queue - otherwise it's on index 0
  69. int v = (newWaypoints.Length > 1) ? w + 1 : 0;
  70. newWaypoints[v] = transform.position;
  71.  
  72. if (facingType== FacingType.Snap || facingType == FacingType.Smooth)
  73. {
  74. SetAxisTowards(lookAxis, transform, ((Vector3)newWaypoints[1] - transform.position).normalized);
  75. }
  76. }
  77.  
  78. protected virtual void Update()
  79. {
  80. if (isPatrolling && waitAtEachStop && currentWaitTime > 0f)
  81. {
  82. currentWaitTime -= Time.deltaTime;
  83. isWaiting = true;
  84. return;
  85. }
  86. else
  87. {
  88. isWaiting = false;
  89. }
  90. }
  91.  
  92. public virtual void FixedUpdate()
  93. {
  94. if (!isPatrolling) return;
  95.  
  96. Vector2 currentTarget = newWaypoints[currentTargetIndex];
  97. Vector2 currentDirection;
  98.  
  99. // Snap Rotate
  100. if (facingType == FacingType.Snap && facingType != FacingType.Smooth)
  101. {
  102. currentDirection = UpdateDirection(currentTarget);
  103. SetAxisTowards(lookAxis, transform, currentDirection);
  104. }
  105.  
  106. // Smooth Rotate
  107. if (facingType == FacingType.Smooth)
  108. {
  109. currentDirection = UpdateDirection(currentTarget);
  110. float angle = Mathf.Atan2(currentDirection.y, currentDirection.x) * Mathf.Rad2Deg;
  111. transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.AngleAxis(angle, Vector3.forward), Time.deltaTime * smoothFaceSpeed);
  112. }
  113.  
  114. if (isWaiting) return;
  115.  
  116. // Move toward waypoint
  117. rigidbody2D.MovePosition(transform.position + ((Vector3)currentTarget - transform.position).normalized * speed * Time.fixedDeltaTime);
  118.  
  119. if (Vector2.Distance(transform.position, currentTarget) <= .05f)
  120. {
  121. rigidbody2D.MovePosition((Vector3)currentTarget);
  122.  
  123. //new waypoint has been reached
  124. OnReachedWaypoint.Invoke(gameObject);
  125. if(waitAtEachStop) currentWaitTime = waitTime;
  126. currentTargetIndex = (currentTargetIndex < newWaypoints.Length - 1) ? currentTargetIndex + 1 : 0;
  127. }
  128. }
  129.  
  130. protected virtual Vector2 UpdateDirection(Vector2 currentTarget)
  131. {
  132. return ((Vector3)currentTarget - transform.position).normalized;
  133. }
  134.  
  135. public virtual void Reset()
  136. {
  137. waypoints.Clear();
  138. Vector2 thisPosition = transform.position;
  139. waypoints[0] = new Vector2(2f, .5f) + thisPosition;
  140. }
  141.  
  142. protected void SetAxisTowards(Directions axis, Transform t, Vector2 direction)
  143. {
  144. switch (axis)
  145. {
  146. case Directions.Up:
  147. t.up = direction;
  148. break;
  149. case Directions.Down:
  150. t.up = -direction;
  151. break;
  152. case Directions.Right:
  153. t.right = direction;
  154. break;
  155. case Directions.Left:
  156. t.right = -direction;
  157. break;
  158. }
  159. }
  160.  
  161. public enum Directions
  162. {
  163. Up,
  164. Right,
  165. Down,
  166. Left,
  167. }
  168.  
  169. protected virtual void OnDrawGizmosSelected()
  170. {
  171. if (!previewWaypoints) return;
  172.  
  173. for (int i = 0; i < waypoints.Count; i++)
  174. {
  175. Gizmos.color = Color.yellow;
  176. Gizmos.DrawSphere(new Vector3(waypoints[i].x, waypoints[i].y, transform.position.z), gizmoScale);
  177.  
  178. Gizmos.color = Color.green;
  179. if (i == 0)
  180. {
  181. Gizmos.DrawLine(waypoints[i], transform.position);
  182. }
  183. else
  184. {
  185. Gizmos.DrawLine(waypoints[i], waypoints[i-1]);
  186. }
  187. }
  188. }
  189.  
  190. [ContextMenu("Start Patrolling")]
  191. public virtual void StartPatrolling()
  192. {
  193. isPatrolling = true;
  194. InitializePatrol();
  195. }
  196.  
  197. [ContextMenu("Stop Patrolling")]
  198. public virtual void StopPatrolling()
  199. {
  200. isPatrolling = false;
  201. }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement