You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
4.1 KiB
C#

3 years ago
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();
}
}
}
}
}
}
}