using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using SiegeSong; namespace SiegeSong { public class Navigator : MonoBehaviour { public Vector3 CurrentWayPointPosition; public Vector3? NextWayPointPosition; public Motor Motor; public UnityEvent OnDestinationReached; public UnityEvent RequestNewDestination; public ThreatAwareness Awareness; float walkMagnitude = 0.5f; float runMagnitude = 1.0f; float sprintMagnitude = 1.5f; int rotationIterationDegrees = 20; int rotationIterations; float rotationSpeed = 0.01f; float rotationTimer; bool turning; void Start() { } void Update() { } public void MoveToWayPoint(bool run = false, bool sprint = false) { if (Vector3.Distance(CurrentWayPointPosition, gameObject.transform.position) > Awareness.MaxNearDistance) { if (Vector3.Distance(CurrentWayPointPosition, gameObject.transform.position) > Awareness.MaxMediumDistance) { var inputMagnitude = walkMagnitude; if (run) inputMagnitude = runMagnitude; if (sprint) inputMagnitude = sprintMagnitude; Motor.Run(inputMagnitude); if (!turning) { Motor.RotateToDirection(Quaternion.Lerp(gameObject.transform.rotation, Quaternion.LookRotation(CurrentWayPointPosition - gameObject.transform.position), rotationTimer * rotationSpeed).eulerAngles); rotationTimer += Time.deltaTime; } } RaycastHit hit; if (Physics.Linecast(gameObject.transform.position, gameObject.transform.forward, out hit)) { if (Vector3.Distance(gameObject.transform.position, hit.transform.position) < Awareness.MaxNearDistance) { turning = true; Motor.RotateToDirection(Quaternion.Lerp(gameObject.transform.rotation, Quaternion.Euler(new Vector3(gameObject.transform.rotation.x, gameObject.transform.rotation.y + (rotationIterationDegrees * rotationIterations), gameObject.transform.rotation.z)), rotationTimer * rotationSpeed).eulerAngles); rotationTimer += Time.deltaTime; rotationIterations += rotationIterations > 0 ? 1 : -1; } else { turning = false; rotationTimer = 0.0f; if (Vector3.Distance(gameObject.transform.position, hit.transform.position) < Awareness.MaxMediumDistance) { turning = true; rotationIterations = -rotationIterations; } } } else { turning = false; rotationTimer = 0.0f; } } else { turning = false; rotationTimer = 0.0f; if (NextWayPointPosition.HasValue) { CurrentWayPointPosition = NextWayPointPosition.Value; NextWayPointPosition = null; } else { if (OnDestinationReached != null) { OnDestinationReached.Invoke(); } else { if (Awareness.HostilityLevel == AIHostility.SearchingHostile) { RequestNewDestination.Invoke(); } } } } } } }