88 lines
3.3 KiB
C#
88 lines
3.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Schema;
|
|
using UnityEngine;
|
|
using VOID.Generic.Objects.Unit.Actions;
|
|
using VOID.Generic.Objects.Unit.Events;
|
|
|
|
namespace VOID.Generic.AI.Schema.Actions
|
|
{
|
|
[Description("This unit will patrol between given points")]
|
|
[Category(SchemaCategory.RealtimeThisUnit)]
|
|
public class UnitPatrol : Action
|
|
{
|
|
private class UnitPatrolMemory
|
|
{
|
|
public SchemaUnitEventWrapper<MoveEvent, UnitPatrolMemory> onMoveEnd;
|
|
public int nextStop = - 1;
|
|
public bool isMoving = false;
|
|
}
|
|
|
|
public override void OnNodeEnter(object nodeMemory, SchemaAgent agent)
|
|
{
|
|
var memory = (UnitPatrolMemory)nodeMemory;
|
|
var unitAgent = (UnitObjectSchemaAgent)agent;
|
|
var patrolPoints = unitAgent.unitAI.patrol;
|
|
var closestDistance = float.MaxValue;
|
|
|
|
for (var index = 0; index < patrolPoints.Count; index++)
|
|
{
|
|
var distance = Vector3.Distance(unitAgent.unit.transform.position, patrolPoints[index].position);
|
|
if (distance >= closestDistance) continue;
|
|
closestDistance = distance;
|
|
memory.nextStop = index;
|
|
}
|
|
|
|
memory.onMoveEnd = new SchemaUnitEventWrapper<MoveEvent, UnitPatrolMemory>(
|
|
unitAgent.unit.unitEvents.onMoveEnd, OnMoveEnd, unitAgent, memory);
|
|
memory.onMoveEnd.On();
|
|
}
|
|
|
|
public override NodeStatus Tick(object nodeMemory, SchemaAgent agent)
|
|
{
|
|
var memory = (UnitPatrolMemory)nodeMemory;
|
|
var unitAgent = (UnitObjectSchemaAgent)agent;
|
|
|
|
if (memory.nextStop == - 1) return NodeStatus.Failure;
|
|
if (memory.isMoving) return NodeStatus.Running;
|
|
|
|
// Get next patrol points in order to check
|
|
var orderedPatrolPoints = new List<Transform>();
|
|
orderedPatrolPoints.AddRange(unitAgent.unitAI.patrol.Skip(memory.nextStop+1));
|
|
orderedPatrolPoints.AddRange(unitAgent.unitAI.patrol.Take(memory.nextStop+1));
|
|
|
|
// Find next valid patrol point and order move to it
|
|
foreach (var point in orderedPatrolPoints)
|
|
{
|
|
var moveAction = new MoveAction(unitAgent.unit, point.position);
|
|
if (moveAction.CanDoItBoolean() == false) continue;
|
|
unitAgent.unit.Order(moveAction);
|
|
memory.isMoving = true;
|
|
return NodeStatus.Running;
|
|
}
|
|
|
|
// Next point cant be found - error!
|
|
return NodeStatus.Failure;
|
|
}
|
|
|
|
public override void OnNodeExit(object nodeMemory, SchemaAgent agent)
|
|
{
|
|
var memory = (UnitPatrolMemory)nodeMemory;
|
|
memory.onMoveEnd.Off();
|
|
memory.isMoving = false;
|
|
}
|
|
|
|
public override void OnNodeAbort(object nodeMemory, SchemaAgent agent)
|
|
{
|
|
var memory = (UnitPatrolMemory)nodeMemory;
|
|
memory.onMoveEnd.Off();
|
|
memory.isMoving = false;
|
|
}
|
|
|
|
private void OnMoveEnd(MoveEvent moveEvent, UnitPatrolMemory memory, UnitObjectSchemaAgent agent)
|
|
{
|
|
memory.nextStop = (memory.nextStop + 1) % agent.unitAI.patrol.Count;
|
|
memory.isMoving = false;
|
|
}
|
|
}
|
|
} |