| | | 1 | | using System; |
| | | 2 | | using UnityEngine; |
| | | 3 | | |
| | | 4 | | // Hierarchy node owned by an agent. |
| | | 5 | | // |
| | | 6 | | // Since agents cannot inherit from both HierarchicalBase and MonoBehaviour, agents use composition |
| | | 7 | | // to know their position within the hierarchical strategy. |
| | | 8 | | [Serializable] |
| | | 9 | | public class HierarchicalAgent : HierarchicalBase { |
| | | 10 | | // Agent to which this hierarchical node belongs. |
| | 57 | 11 | | public IAgent Agent { get; init; } |
| | | 12 | | |
| | 0 | 13 | | public override Vector3 Position => Agent.Position; |
| | 0 | 14 | | public override Vector3 Velocity => Agent.Velocity; |
| | 0 | 15 | | public override Vector3 Acceleration => Agent.Acceleration; |
| | 0 | 16 | | public override bool IsTerminated => Agent.IsTerminated; |
| | | 17 | | |
| | | 18 | | public override IHierarchical Target { |
| | 0 | 19 | | get { return base.Target; } |
| | 0 | 20 | | set { |
| | 0 | 21 | | if (base.Target != null) { |
| | 0 | 22 | | if (Agent.IsPursuer) { |
| | | 23 | | // Remove the interceptor as a pursuer from all target sub-hierarchical objects. |
| | 0 | 24 | | void RemovePursuerFromHierarchical(IHierarchical target) { |
| | 0 | 25 | | target.RemovePursuer(this); |
| | 0 | 26 | | foreach (var subHierarchical in target.SubHierarchicals) { |
| | 0 | 27 | | RemovePursuerFromHierarchical(subHierarchical); |
| | 0 | 28 | | } |
| | 0 | 29 | | } |
| | 0 | 30 | | RemovePursuerFromHierarchical(base.Target); |
| | 0 | 31 | | } else { |
| | | 32 | | // For non-pursuable agents, such as launchers, only remove from the top-level target. |
| | 0 | 33 | | base.Target.RemovePursuer(this); |
| | 0 | 34 | | } |
| | 0 | 35 | | ClearSubHierarchicals(); |
| | 0 | 36 | | Agent.DestroyTargetModel(); |
| | 0 | 37 | | } |
| | 0 | 38 | | base.Target = value; |
| | 0 | 39 | | if (base.Target != null) { |
| | | 40 | | // Threats also set their target to the asset, so we should also track the threats pursuing |
| | | 41 | | // the asset. |
| | 0 | 42 | | base.Target.AddPursuer(this); |
| | 0 | 43 | | if (Agent is IInterceptor interceptor) { |
| | | 44 | | // Subscribe to the target events. |
| | 0 | 45 | | foreach (var targetHierarchical in Target.ActiveSubHierarchicals) { |
| | 0 | 46 | | if (targetHierarchical is HierarchicalAgent targetAgent) { |
| | 0 | 47 | | targetAgent.Agent.OnTerminated += (IAgent agent) => |
| | 0 | 48 | | agent.HierarchicalAgent.RemoveTargetHierarchical(targetHierarchical); |
| | 0 | 49 | | } |
| | 0 | 50 | | } |
| | | 51 | | |
| | | 52 | | // Perform recursive clustering on the new targets. |
| | 0 | 53 | | RecursiveCluster(maxClusterSize: interceptor.CapacityPerSubInterceptor); |
| | | 54 | | |
| | 0 | 55 | | if (Agent.IsPursuer) { |
| | | 56 | | // Add the interceptor as a pursuer to all target sub-hierarchical objects. |
| | 0 | 57 | | void AddPursuerToHierarchical(IHierarchical target) { |
| | 0 | 58 | | target.AddPursuer(this); |
| | 0 | 59 | | foreach (var subHierarchical in target.SubHierarchicals) { |
| | 0 | 60 | | AddPursuerToHierarchical(subHierarchical); |
| | 0 | 61 | | } |
| | 0 | 62 | | } |
| | 0 | 63 | | AddPursuerToHierarchical(base.Target); |
| | 0 | 64 | | } |
| | 0 | 65 | | } |
| | 0 | 66 | | Agent.CreateTargetModel(base.Target); |
| | 0 | 67 | | } |
| | 0 | 68 | | } |
| | | 69 | | } |
| | | 70 | | |
| | 52 | 71 | | public HierarchicalAgent(IAgent agent) { |
| | 26 | 72 | | Agent = agent; |
| | 26 | 73 | | } |
| | | 74 | | } |