using UnityEngine; using UnityEngine.AI; using HelpURL = BehaviorDesigner.Runtime.Tasks.HelpURLAttribute; namespace BehaviorDesigner.Runtime.Tactical.Tasks { /// /// Base class for all NavMeshAgent Tactical tasks. /// public abstract class NavMeshTacticalGroup : TacticalGroup { /// /// The NavMeshTacticalAgent class contains component references and variables for each NavMeshAgent. /// private class NavMeshTacticalAgent : TacticalAgent { private NavMeshAgent navMeshAgent; private bool destinationSet; /// /// Caches the component references and initialize default values. /// public NavMeshTacticalAgent(Transform agent) : base(agent) { navMeshAgent = agent.GetComponent(); if (navMeshAgent.hasPath) { navMeshAgent.ResetPath(); navMeshAgent.isStopped = true; } } /// /// Sets the destination. /// public override void SetDestination(Vector3 destination) { destinationSet = true; destination.y = navMeshAgent.destination.y; if (navMeshAgent.destination != destination) { navMeshAgent.SetDestination(destination); navMeshAgent.isStopped = false; } } /// /// Has the agent arrived at its destination? /// public override bool HasArrived() { return destinationSet && !navMeshAgent.pathPending && (transform.position - navMeshAgent.destination).magnitude <= navMeshAgent.stoppingDistance; } /// /// Rotates towards the target rotation. /// public override bool RotateTowards(Quaternion targetRotation) { if (navMeshAgent.updateRotation) { navMeshAgent.updateRotation = false; } transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, navMeshAgent.angularSpeed * Time.deltaTime); if (Quaternion.Angle(transform.rotation, targetRotation) < AttackAgent.AttackAngle()) { return true; } return false; } /// /// Returns the radius of the agent. /// public override float Radius() { return navMeshAgent.radius; } /// /// Starts or stops the rotation from updating. /// public override void UpdateRotation(bool update) { navMeshAgent.updateRotation = update; } /// /// Stops the agent from moving. /// public override void Stop() { if (navMeshAgent.hasPath) { navMeshAgent.isStopped = true; destinationSet = false; } } /// /// The task has ended. Perform any cleanup. /// public override void End() { Stop(); navMeshAgent.updateRotation = true; navMeshAgent.velocity = Vector3.zero; } } /// /// Adds the agent to the agent list. /// /// The agent to add. protected override void AddAgentToGroup(Behavior agent, int index) { base.AddAgentToGroup(agent, index); if (tacticalAgent == null && gameObject == agent.gameObject) { tacticalAgent = new NavMeshTacticalAgent(agent.transform); tacticalAgent.AttackOffset = attackOffset.Value; tacticalAgent.TargetOffset = targetOffset.Value; } } } }