using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.MLAgents; using UnityEngine; [ExecuteInEditMode] public class WaypointManager : MonoBehaviour { [SerializeField] public List m_WaypointList; [SerializeField] public Waypoint[] m_WaypointArray; [SerializeField] public Transform m_Target; private Vector3 m_StartingPosition; [SerializeField] public Waypoint m_CurrentWaypoint; public Transform m_Agent; private bool m_IsMoved; public delegate void SwapModelOnReachingWaypoint(string modelName); public static event SwapModelOnReachingWaypoint SwapModelOnWaypointReached; public delegate void OverrideWaypoint(string modelName); public static event OverrideWaypoint OnOverrideWaypoint; private void OnEnable() { m_WaypointList = new List(); Waypoint.OnWaypointReached += SetNextWaypoint; } private void OnDisable() { Waypoint.OnWaypointReached -= SetNextWaypoint; } private void Start() { SortWaypointInChildrenArray(); m_CurrentWaypoint = m_WaypointList[0]; MoveTargetToWaypoint(); } private void FixedUpdate() { if(!m_IsMoved) { MoveAgentToStartPosition(); m_IsMoved = true; } CheckOverride(); MoveTargetToWaypoint(); } private void MoveTargetToWaypoint() { Vector3 wpPosition = m_CurrentWaypoint.m_WaypointPosition.position; m_Target.position = wpPosition; } private void SetNextWaypoint(float index, string modelName) { if (index == m_CurrentWaypoint.m_Index) { Debug.Log($"Waypoint reached {index}"); MoveToNextWaypoint(index); SwapModelOnWaypointReached(modelName); } else { Debug.Log($"Wrong Waypoint reached {index} Current {m_CurrentWaypoint.m_Index}"); } } private void SetNextWaypointOverride(float index) { if (index == m_CurrentWaypoint.m_Index) { Debug.Log($"Waypoint reached {index}"); MoveToNextWaypoint(index); } else { Debug.Log($"Wrong Waypoint reached {index} Current {m_CurrentWaypoint.m_Index}"); } } private void MoveToNextWaypoint(float index) { StartCoroutine(WaypointTimeout(m_CurrentWaypoint.m_WaitTime, index)); } IEnumerator WaypointTimeout(float seconds, float index) { yield return new WaitForSeconds(seconds); if (m_CurrentWaypoint.m_Index < m_WaypointList.Count - 1) { m_CurrentWaypoint = m_WaypointList[(int)index + 1]; MoveTargetToWaypoint(); } else { Debug.Log($"Reached Last Position {m_CurrentWaypoint.m_Index}"); } } private void SortWaypointsInChildren() { foreach (Transform t in transform) { m_WaypointList.Add(t.GetComponent()); } m_WaypointList = m_WaypointList.OrderBy(waypoint => waypoint.m_Index).ToList(); } private void SortWaypointInChildrenArray() { m_WaypointArray = GetComponentsInChildren(); foreach (Waypoint wp in m_WaypointArray) { if ( wp.isActiveAndEnabled ) { m_WaypointList.Add(wp); if (wp.m_StartingPosition) m_StartingPosition = wp.transform.position; } } m_WaypointList = m_WaypointList.OrderBy(waypoint => waypoint.m_Index).ToList(); } private void MoveAgentToStartPosition() { m_Agent.position = m_StartingPosition; Debug.Log($"Moved agent to {m_StartingPosition}"); } private void CheckOverride() { if(Input.GetKeyUp(KeyCode.F)) { SetNextWaypointOverride(m_CurrentWaypoint.m_Index); OnOverrideWaypoint(m_CurrentWaypoint.m_ModelName); } } void OnDrawGizmos() { #if UNITY_EDITOR Gizmos.color = Color.red; foreach (Waypoint waypoint in m_WaypointList) { Gizmos.DrawWireSphere(waypoint.m_WaypointPosition.position, 1f); } Gizmos.color = Color.red; for (int i = 0; i < m_WaypointList.Count - 1; i++) { Gizmos.DrawLine(m_WaypointList[i].m_WaypointPosition.position, m_WaypointList[i + 1].m_WaypointPosition.position); } #endif } }