Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using NaughtyAttributes;
- [RequireComponent(typeof(Rigidbody2D))]
- public class Patrol2D : MonoBehaviour
- {
- public enum FacingType
- {
- DontChange,
- Snap,
- Smooth
- }
- public bool isPatrolling = true;
- [Header("Movement")]
- public float speed = 5f;
- [Header("Orientation")]
- public FacingType facingType = FacingType.DontChange;
- public float smoothFaceSpeed = 7f;
- public Directions lookAxis = Directions.Right;
- [Header("Stops")]
- [ReorderableList]
- public List<Vector2> waypoints;
- public bool waitAtEachStop = false;
- public float waitTime = 1f;
- protected float currentWaitTime = 0f;
- protected bool isWaiting = false;
- [Header("Preview")]
- public bool previewWaypoints = true;
- public float gizmoScale = 0.3f;
- public static event Action<GameObject> OnReachedWaypoint = delegate { };
- protected new Rigidbody2D rigidbody2D;
- protected Vector2[] newWaypoints;
- protected int currentTargetIndex;
- protected virtual void Awake()
- {
- rigidbody2D = GetComponent<Rigidbody2D>();
- }
- protected virtual void Start()
- {
- if(isPatrolling) InitializePatrol();
- }
- protected virtual void InitializePatrol()
- {
- currentTargetIndex = 0;
- newWaypoints = new Vector2[waypoints.Count + 1];
- int w = 0;
- for (int i = 0; i < waypoints.Count; i++)
- {
- newWaypoints[i] = waypoints[i];
- w = i;
- }
- //Add the starting position at the end, only if there is at least another point in the queue - otherwise it's on index 0
- int v = (newWaypoints.Length > 1) ? w + 1 : 0;
- newWaypoints[v] = transform.position;
- if (facingType== FacingType.Snap || facingType == FacingType.Smooth)
- {
- SetAxisTowards(lookAxis, transform, ((Vector3)newWaypoints[1] - transform.position).normalized);
- }
- }
- protected virtual void Update()
- {
- if (isPatrolling && waitAtEachStop && currentWaitTime > 0f)
- {
- currentWaitTime -= Time.deltaTime;
- isWaiting = true;
- return;
- }
- else
- {
- isWaiting = false;
- }
- }
- public virtual void FixedUpdate()
- {
- if (!isPatrolling) return;
- Vector2 currentTarget = newWaypoints[currentTargetIndex];
- Vector2 currentDirection;
- // Snap Rotate
- if (facingType == FacingType.Snap && facingType != FacingType.Smooth)
- {
- currentDirection = UpdateDirection(currentTarget);
- SetAxisTowards(lookAxis, transform, currentDirection);
- }
- // Smooth Rotate
- if (facingType == FacingType.Smooth)
- {
- currentDirection = UpdateDirection(currentTarget);
- float angle = Mathf.Atan2(currentDirection.y, currentDirection.x) * Mathf.Rad2Deg;
- transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.AngleAxis(angle, Vector3.forward), Time.deltaTime * smoothFaceSpeed);
- }
- if (isWaiting) return;
- // Move toward waypoint
- rigidbody2D.MovePosition(transform.position + ((Vector3)currentTarget - transform.position).normalized * speed * Time.fixedDeltaTime);
- if (Vector2.Distance(transform.position, currentTarget) <= .05f)
- {
- rigidbody2D.MovePosition((Vector3)currentTarget);
- //new waypoint has been reached
- OnReachedWaypoint.Invoke(gameObject);
- if(waitAtEachStop) currentWaitTime = waitTime;
- currentTargetIndex = (currentTargetIndex < newWaypoints.Length - 1) ? currentTargetIndex + 1 : 0;
- }
- }
- protected virtual Vector2 UpdateDirection(Vector2 currentTarget)
- {
- return ((Vector3)currentTarget - transform.position).normalized;
- }
- public virtual void Reset()
- {
- waypoints.Clear();
- Vector2 thisPosition = transform.position;
- waypoints[0] = new Vector2(2f, .5f) + thisPosition;
- }
- protected void SetAxisTowards(Directions axis, Transform t, Vector2 direction)
- {
- switch (axis)
- {
- case Directions.Up:
- t.up = direction;
- break;
- case Directions.Down:
- t.up = -direction;
- break;
- case Directions.Right:
- t.right = direction;
- break;
- case Directions.Left:
- t.right = -direction;
- break;
- }
- }
- public enum Directions
- {
- Up,
- Right,
- Down,
- Left,
- }
- protected virtual void OnDrawGizmosSelected()
- {
- if (!previewWaypoints) return;
- for (int i = 0; i < waypoints.Count; i++)
- {
- Gizmos.color = Color.yellow;
- Gizmos.DrawSphere(new Vector3(waypoints[i].x, waypoints[i].y, transform.position.z), gizmoScale);
- Gizmos.color = Color.green;
- if (i == 0)
- {
- Gizmos.DrawLine(waypoints[i], transform.position);
- }
- else
- {
- Gizmos.DrawLine(waypoints[i], waypoints[i-1]);
- }
- }
- }
- [ContextMenu("Start Patrolling")]
- public virtual void StartPatrolling()
- {
- isPatrolling = true;
- InitializePatrol();
- }
- [ContextMenu("Stop Patrolling")]
- public virtual void StopPatrolling()
- {
- isPatrolling = false;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement