A game about forced loneliness, made by TACStudios
1using System;
2using System.Linq;
3using UnityEngine;
4
5namespace Unity.VisualScripting
6{
7 [UnitCategory("Graphs/Graph Nodes")]
8 public abstract class HasGraph<TGraph, TMacro, TMachine> : Unit
9 where TGraph : class, IGraph, new()
10 where TMacro : Macro<TGraph>
11 where TMachine : Machine<TGraph, TMacro>
12 {
13 /// <summary>
14 /// The entry point for the node.
15 /// </summary>
16 [DoNotSerialize]
17 [PortLabelHidden]
18 public ControlInput enter { get; private set; }
19
20 /// <summary>
21 /// The GameObject or the Machine where to look for the graph.
22 /// </summary>
23 [DoNotSerialize]
24 [PortLabelHidden]
25 [NullMeansSelf]
26 public ValueInput target { get; private set; }
27
28 /// <summary>
29 /// The Graph to look for.
30 /// </summary>
31 [DoNotSerialize]
32 [PortLabel("Graph")]
33 [PortLabelHidden]
34 public ValueInput graphInput { get; private set; }
35
36 /// <summary>
37 /// True if a Graph if found.
38 /// </summary>
39 [DoNotSerialize]
40 [PortLabel("Has Graph")]
41 [PortLabelHidden]
42 public ValueOutput hasGraphOutput { get; private set; }
43
44 /// <summary>
45 /// The action to execute once the graph has been set.
46 /// </summary>
47 [DoNotSerialize]
48 [PortLabelHidden]
49 public ControlOutput exit { get; private set; }
50
51 protected abstract bool isGameObject { get; }
52 Type targetType => isGameObject ? typeof(GameObject) : typeof(TMachine);
53
54 protected override void Definition()
55 {
56 enter = ControlInput(nameof(enter), TriggerHasGraph);
57 target = ValueInput(targetType, nameof(target)).NullMeansSelf();
58 target.SetDefaultValue(targetType.PseudoDefault());
59
60 graphInput = ValueInput<TMacro>(nameof(graphInput), null);
61 hasGraphOutput = ValueOutput(nameof(hasGraphOutput), OutputHasGraph);
62 exit = ControlOutput(nameof(exit));
63
64 Requirement(graphInput, enter);
65 Assignment(enter, hasGraphOutput);
66 Succession(enter, exit);
67 }
68
69 ControlOutput TriggerHasGraph(Flow flow)
70 {
71 flow.SetValue(hasGraphOutput, OutputHasGraph(flow));
72 return exit;
73 }
74
75 bool OutputHasGraph(Flow flow)
76 {
77 var macro = flow.GetValue<TMacro>(graphInput);
78 var targetValue = flow.GetValue(target, targetType);
79
80 if (targetValue is GameObject gameObject)
81 {
82 if (gameObject != null)
83 {
84 var stateMachines = gameObject.GetComponents<TMachine>();
85 macro = flow.GetValue<TMacro>(graphInput);
86
87 return stateMachines
88 .Where(currentMachine => currentMachine != null)
89 .Any(currentMachine => currentMachine.graph != null && currentMachine.graph.Equals(macro.graph));
90 }
91 }
92 else
93 {
94 TMachine machine = flow.GetValue<TMachine>(target);
95
96 if (machine.graph != null && machine.graph.Equals(macro.graph))
97 {
98 return true;
99 }
100 }
101
102 return false;
103 }
104 }
105}