Hello.
I have a custom node, that continues the flow when triggered by a delegate.
This is the node code
protected override void Definition()
{
listen = ControlInput(nameof(listen), Setup);
then = ControlOutput(nameof(then));
onRaised = ControlOutput(nameof(onRaised));
target = ValueInput<GameObject>(nameof(target), null);
events = ValueInput<List<ScriptableEvent<TArg>>>(nameof(events));
arg = ValueOutput<TArg>(nameof(arg));
}
private ControlOutput Setup(Flow flow)
{
GameObject go = flow.GetValue<GameObject>(target);
TComponent component = go.AddComponent<TComponent>();
flow.GetValue<List<ScriptableEvent<TArg>>>(events)
.ForEach(elem => component.AddEvent(elem));
component.AddRaisedCallback(value =>
{
flow.SetValue(arg, value);
flow.Invoke(onRaised);
});
return then;
}
This is the TComponent code (simplified)
private RaisedCallback<TArg> onRaised;
public void AddRaisedCallback(RaisedCallback<TArg> callback)
{
onRaised += callback;
}
public void OnRaised(TArg arg)
{
onRaised(arg);
}
This is the graph and the error.
Any ideas why is happening?
Thank you.
- Is the ScriptGraph from the image also on the Player GameObject?
- Have you checked if Get Object Variable node or the object variable itself doesn’t have a hidden space after the variable name?
The error does not appear to be related to your custom node. If that was the case, it would throw something out earlier and not related to TMP.
- Yes, the ScriptGraph is embeded on Player GameObject, I have the Player selected in screenshot.
- It doesn’t have a space. I dragged the variable.
After some reverse engineering in UVS.Timer nodes (Timer and Cooldown), i’ve manage to make it work with the following changes.
internal abstract class ListenerNode<TArg, TComponent> : Unit, IGraphElementWithData, IGraphEventListener {
private sealed class Data : IGraphElementData
{
public GraphReference reference;
public bool isListening;
public bool isPaused;
public TComponent component;
}
[DoNotSerialize] // No need to serialize ports.
public ControlInput listen { get; private set; }
[DoNotSerialize] // No need to serialize ports
public ValueInput target { get; private set; }
[DoNotSerialize] // No need to serialize ports.
public ControlOutput then { get; private set; }
[DoNotSerialize] // No need to serialize ports.
public ControlOutput onRaised { get; private set; }
[DoNotSerialize]
public ValueOutput arg { get; private set; }
protected override void Definition()
{
listen = ControlInput(nameof(listen), Setup);
target = ValueInput<GameObject>(nameof(target), null);
then = ControlOutput(nameof(then));
onRaised = ControlOutput(nameof(onRaised));
arg = ValueOutput<TArg>(nameof(arg));
Succession(listen, then);
}
public IGraphElementData CreateData()
{
return new Data();
}
public void StartListening(GraphStack stack)
{
Data data = stack.GetElementData<Data>(this);
if (data.isListening)
{
return;
}
data.isListening = true;
data.isPaused = true;
data.reference = stack.ToReference();
data.component = null;
}
public void StopListening(GraphStack stack)
{
Data data = stack.GetElementData<Data>(this);
if (!data.isListening)
{
return;
}
data.isListening = false;
}
private void TriggerOnRaised(GraphReference reference, TArg arg)
{
using (Flow flow = Flow.New(reference))
{
Update(flow, arg);
}
}
protected void Update(Flow flow, TArg arg)
{
Data data = flow.stack.GetElementData<Data>(this);
flow.SetValue(this.arg, arg);
flow.Invoke(onRaised);
}
private ControlOutput Setup(Flow flow)
{
Data data = flow.stack.GetElementData<Data>(this);
GameObject go = flow.GetValue<GameObject>(target);
bool isPaused = flow.GetValue<bool>(paused);
data.isPaused = isPaused;
TComponent component = go.AddComponent<TComponent>();
data.component = component;
component.RegisterOnRaised(arg =>
{
if (data.isPaused) return;
TriggerOnRaised(data.reference, arg);
});
return then;
}
}
*Note: i’ve extracted the code from the a bigger custom node that i’ve developed, i’m sorry if there are any errors, but i’m sure they can be easily fixed.
1 Like