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