Events
Warning: API is not final and is subject to change.
Creating an Event
To dispatch or receive an Event from a Scripting Graph or from a Job the Event has to be a struct inheriting from IVisualScriptingEvent
(previously IDotsEvent
in drop 8).
[EventNode]
public struct MyEvent : IVisualScriptingEvent { }
Once created, On My Event and Send My Event nodes will appear in the Searcher. You can now use them in you graph.
The EventNode
Attribute defines the event access mode in a graph. You can specify it using the EventAccessFlags
enum.
[EventNode] // By default the event can be dispatched and received.
[EventNode(EventAccessFlags.Receiver | EventAccessFlags.Dispatcher)] // Same but explicit
[EventNode(EventAccessFlags.Receiver)] // Only the SendEvent node will be accessible
[EventNode(EventAccessFlags.Dispatcher)] // Only the OnEvent node will be accessible
If you don't add the EventNode
attribute on your Event, you won't be able to add the related Event nodes in your graphs.
Supported Events data types
Here is the list of the supported types in an Event:
- bool
- int
- float
- float2
- float3
- float4
- quaternion (from
Unity.Mathematics
, not fromUnityEngine
) - Entity
- NativeString128 (other types of NativeString will be available in a further version)
Example:
[EventNode]
public struct MyEvent : IVisualScriptingEvent
{
public int MyInt;
public float2 MyFloat2;
}
Dispatching an Event from the code
public class DispatchEventSystem : SystemBase
{
VisualScriptingEventSystem m_EventSystem;
protected override void OnCreate()
{
m_EventSystem = World.GetOrCreateSystem<VisualScriptingEventSystem>();
}
protected override void OnUpdate()
{
var writer = m_EventSystem.CreateEventWriter(1); // 1 is the NativeStream.Writer forEachCount
writer.BeginForEachIndex(0);
writer.Write(new MyEvent { MyInt = 1, MyFloat = 42.5f });
writer.EndForEachIndex();
}
}
For more information about
NativeStream.Writer
please see the API documentation
Once written in the NativeStream
, the event will be dispatched and can be received in your graph with the On My Event node or from the code.
Receiving an Event from the code
Here is how you can catch an event that has been dispatched from the Send My Event node or from the code.
public class ReceiveEventSystem : SystemBase
{
VisualScriptingEventSystem m_EventSystem;
protected override void OnCreate()
{
m_EventSystem = World.GetOrCreateSystem<VisualScriptingEventSystem>();
}
protected override void OnUpdate()
{
new CollectMyEventJob()
.Schedule<CollectMyEventJob, MyEvent>(m_EventSystem)
.Complete();
}
[BurstCompile]
struct CollectMyEventJob : IVisualScriptingEventReceiverJob<MyEvent>
{
public void Execute(MyEvent myEvent)
{
// Do stuff with your event
}
}
}
Target and Source entities
Target
Using the Target
Attribute on an Entity
field of your event you can specify the Entity with a ScriptingGraphInstance
Component that will receive the event.
[EventNode]
public struct MyEvent : IVisualScriptingEvent
{
public int MyInt;
[Target]
public Entity Target;
}
From the graph
From the code
public struct Receiver : IComponentData { }
public class TestSystem : ComponentSystem
{
VisualScriptingEventSystem m_EventSystem;
EntityQuery m_Query;
protected override void OnCreate()
{
m_EventSystem = World.GetOrCreateSystem<VisualScriptingEventSystem>();
// The event will be dispatched to all the entities that have a ScriptingGraphInstance and a Receiver components.
m_Query = GetEntityQuery(typeof(ScriptingGraphInstance), typeof(Receiver));
}
protected override void OnUpdate()
{
var count = m_Query.CalculateEntityCount();
var writer = m_EventSystem.CreateEventWriter(count);
var index = 0;
Entities.With(m_Query).ForEach(entity =>
{
writer.BeginForEachIndex(index++);
writer.Write(new TestEvent { I = index, Target = entity });
writer.EndForEachIndex();
});
}
}
This will send the event to the following graph as the converted GameObject (MyReceiver) has a ScriptingGraphInstance
and a Receiver
component.
Note: The Receiver component is not mandatory, it's just an example to identify the Target. You can rely on whatever you want to identity your targeted entity. Note 2: As you can see there is no Target port on the On My Event node, it's implicit.
Source
You can know which graph entity sends the event by adding a Source
Attribute to an Entity
field in your event.
[EventNode]
public struct MyEvent : IVisualScriptingEvent
{
public int MyInt;
[Source]
public Entity Source;
}
This will add a source output port in the On My Event node.
Example : This will log the entity that sent the event, MySender in this case.
Note: The Source input port is hidden in the SendEvent node as it's automatically set by the node itself.
Debug
If you change an existing event (by removing or adding new fields for example), you'll see the following warning in the console:
As explained, you need to rebuild all your graphs by clicking the Build All button located in the cog menu (top right corner of your graph).
Know issues or missing features
- To manage strings, only
NativeString128
are allowed yet in the Event data types. - You must call
Complete()
on theJobHandle
that receives event. - There is no Parallel writing for the events yet (so no
ScheduleParallel()
).