using System; using UnityEngine; namespace Unity.VisualScripting { [UnitCategory("Graphs/Graph Nodes")] public abstract class SetGraph : Unit where TGraph : class, IGraph, new() where TMacro : Macro where TMachine : Machine { /// /// The entry point for the node. /// [DoNotSerialize] [PortLabelHidden] public ControlInput enter { get; protected set; } /// /// The GameObject or the ScriptMachine where the graph will be set. /// [DoNotSerialize] [PortLabelHidden] [NullMeansSelf] public ValueInput target { get; protected set; } /// /// The script graph. /// [DoNotSerialize] [PortLabel("Graph")] [PortLabelHidden] public ValueInput graphInput { get; protected set; } /// /// The graph that has been set to the ScriptMachine. /// [DoNotSerialize] [PortLabel("Graph")] [PortLabelHidden] public ValueOutput graphOutput { get; protected set; } /// /// The action to execute once the graph has been set. /// [DoNotSerialize] [PortLabelHidden] public ControlOutput exit { get; protected set; } protected abstract bool isGameObject { get; } Type targetType => isGameObject ? typeof(GameObject) : typeof(TMachine); protected override void Definition() { enter = ControlInput(nameof(enter), SetMacro); target = ValueInput(targetType, nameof(target)).NullMeansSelf(); target.SetDefaultValue(targetType.PseudoDefault()); graphInput = ValueInput(nameof(graphInput), null); graphOutput = ValueOutput(nameof(graphOutput)); exit = ControlOutput(nameof(exit)); Requirement(graphInput, enter); Assignment(enter, graphOutput); Succession(enter, exit); } ControlOutput SetMacro(Flow flow) { var macro = flow.GetValue(graphInput); var targetValue = flow.GetValue(target, targetType); if (targetValue is GameObject go) { go.GetComponent().nest.SwitchToMacro(macro); } else { ((TMachine)targetValue).nest.SwitchToMacro(macro); } flow.SetValue(graphOutput, macro); return exit; } } }