Report Events Using Event Containers
This example shows how to report events in the Unreal Engine® simulation environment and access actor Properties during simulation using MATLAB®. You can report events in the 3D environment and use the events container to access the handles to the actors involved in the event. You can then access the actor properties.
You can report these actor events using the HitEventEnabled
, OverlapEventEnabled
, and Collisions
properties of the actor object:
Hit event
Begin overlap event
End overlap event
Click event
First, you create a 3D environment and build box actors and a plane actor with sim3d.World
and sim3d.Actor
objects and functions. Then, you set the properties of actor objects to simulate the actors and report events. Then, you add the actors to the world, set a view in the scene, and set up update and output callback functions. The update callback function accesses the actor properties when an event occurs during the simulation. The output callback function sets the actor properties for the events to occur one after the other and also creates annotation actors with sim3d.graphics.Text
and sim3d.graphics.Arrow
objects to indicate the start of click event. Finally, view the events in the Simulation 3D Viewer Window.
Unreal Engine® uses the physics engine to control actor motion and perform real-time physics calculations when the physics property of an actor is enabled.
Create 3D Environment
Create a 3D environment and set up communication with the Unreal Engine simulation environment using the output function OutputImpl
and the update function UpdateImpl
. The sim3d.World
object can send and receive data about a sim3d.Actor
object to and from the Unreal Engine at each simulation step using output and update functions, respectively. Before the Unreal Engine simulates, MATLAB calls the output function and sends data to the Unreal Engine. Then, the Unreal Engine executes at each time step and sends data to MATLAB in the update function. You can use the update function to read this data or change values after each simulation step. For this example, the output function increments the simulation step value after each simulation step and sets actor properties so that the events occur one after the other. The update function accesses the properties of actors involved in the events.
world = sim3d.World('Update',@UpdateImpl,'Output',@OutputImpl);
Enable Hit Event
Instantiate an actor named box1
. Set the position of the actor using the Translation
property. To simulate and report a hit event, set the Mobility
, Physics
, and HitEventEnabled
properties of the actor. The Collisions
property is true
by default. Use the createShape
function to build a box shape for the actor and set the size and color of the box. Add the actor to the world.
box1 = sim3d.Actor( ... ActorName='Box1', ... Translation=[8 -5 6], ... Mobility=sim3d.utils.MobilityTypes.Movable); box1.HitEventEnabled = true; createShape(box1,'box',[2 2 2]); box1.Color = [1 0 0]; box1.Physics = true; add(world,box1);
Instantiate an actor named box2
. Set the Translation
, Mobility
, Physics
, Color
, and HitEventEnabled
properties of the actor. Use the createShape
function to build a box shape for the actor and set the size of the box. Add the actor to the world.
box2 = sim3d.Actor( ... ActorName='Box2', ... Translation=[8 -5 3], ... Mobility=sim3d.utils.MobilityTypes.Movable); box2.HitEventEnabled = true; createShape(box2,'box',[2 2 2]); box2.Color = [0 0 1]; box2.Physics = true; add(world,box2);
When box1
and box2
hit each other, a hit event is reported, and handles to box1
and box2
are stored in the event container HitActors
.
Enable Overlap Event
Instantiate an actor named box3
. Set the position of the actor using the Translation
property. To simulate and report an overlap event, set the Mobility
, Physics
, OverlapEventEnabled
, and Collisions
properties of the actor. Use the createShape
function to build box shape for the actor and set the size and color of the box. Add the actor to the world.
box3 = sim3d.Actor( ... ActorName='Box3', ... Translation=[8 0 6], ... Mobility=sim3d.utils.MobilityTypes.Movable); box3.OverlapEventEnabled = true; createShape(box3,'box',[2 2 2]); box3.Color = [1 0 0]; box3.Physics = true; box3.Collisions = false; add(world,box3);
Instantiate an actor named box4
. Set the Translation
, Collisions
, OverlapEventEnabled
, and Color
properties of the actor. Use the createShape
function to build a box shape for the actor and set the size of the box. Add the actor to the world.
box4 = sim3d.Actor(ActorName='Box4',Translation=[8 0 2]); box4.OverlapEventEnabled = true; createShape(box4,'box',[2 2 2]); box4.Color = [1 0 0]; box4.Collisions = false; add(world,box4);
When box3
and box4
overlap, the overlap event is reported, and handles to box3
and box4
are stored in the event containers BeginOverlappedActors
and EndOverlappedActors
.
Enable Click Event
Instantiate an actor named box5
. Set the position of the actor using the Translation
property. To report a click event, click the actor. Use the createShape
function to build a box shape for the actor and set the size and color of the box. Add the actor to the world.
box5 = sim3d.Actor(ActorName='Box5',Translation=[8 6 6]); createShape(box5,'box',[2 2 2]); box5.Color = [1 0 0]; add(world,box5);
When you click box5
, a click event is reported, and the handle to box5
is stored in the event container ClickedActors
.
Build Plane Actor
Instantiate an actor named plane1
. Set the position of the actor using the Translation
property. Set the Mobility
and PreciseContacts
properties of the actor. The PreciseContacts
property precisely renders the collision of any actor with the plane actor. Use the createShape
function to build a plane shape for the actor and set the size of the plane. Add the actor to the world.
plane1 = sim3d.Actor( ... ActorName='Plane1', ... Mobility=sim3d.utils.MobilityTypes.Stationary); createShape(plane1,'plane',[100 100 0.01]); plane1.PreciseContacts = true; plane1.Translation = [0 0 -3]; add(world,plane1);
Using the UserData
property in the sim3d.World
object, create a user data structure with a field named Step
to store the simulation step. Initialize the user data structure to 1
. You will use this structure in the output function to increment the UserData.Step
value after each simulation step and to display the events one after the other.
world.UserData.Step = 1;
Set Viewer Window Point of View
If you do not create a viewport, then the the default view is set and you can use the keyboard shortcuts and mouse controls to navigate in the Simulation 3D Viewer window.
For this example, use the createViewport
function to create a viewport.
viewport = createViewport(world,Translation=[-15 0 0]);
Run Animation
Run the animation set for 20 seconds with a sample time of 0.01 seconds. The Simulation 3D Viewer Window displays five box actors and a plane actor. During simulation, box1
and box2
display the hit event. The color of box1
changes when it hits box2
. After the hit event, box3
starts to overlap box4
. During the overlap, box3
changes color. After the overlap event, the Simulation 3D Viewer displays, Click the box
and an arrow points at box5
. Click on box5
to report the click event. Upon each click, the color of box5
changes.
sampletime = 0.01; stoptime = 20; run(world,sampletime,stoptime)
Delete World
Delete the world object.
delete(world);
Read Update Function
Use the update function to read data from the Unreal Engine environment at each simulation step. For this example, the UpdateImpl
function checks if an event is reported for a box actor, accesses the handle to the actor, and changes the color of the actor at each time step.
function UpdateImpl(world) if (world.Actors.Box1.HitEvent) for i = 1:length(world.HitActors) if world.HitActors(i).Name == "Box1" world.HitActors(i).Color = [randi([0 1]) ... randi([0 1]) randi([0 1])]; end end end if (world.Actors.Box3.BeginOverlapEvent) for i = 1:length(world.BeginOverlappedActors) if world.BeginOverlappedActors(i).Name == "Box3" world.BeginOverlappedActors(i).Color = [randi([0 1]) ... randi([0 1]) randi([0 1])]; end end end if (world.Actors.Box3.EndOverlapEvent) for i = 1:length(world.EndOverlappedActors) if world.EndOverlappedActors(i).Name == "Box3" world.EndOverlappedActors(i).Color = [randi([0 1]) ... randi([0 1]) randi([0 1])]; end end end if (world.Actors.Box5.ClickEvent) for i = 1:length(world.ClickedActors) if world.ClickedActors(i).Name == "Box5" world.ClickedActors(i).Color = [randi([0 1]) ... randi([0 1]) randi([0 1])]; end end end end
Output Function
Use the output function to read data and set actor properties at a specified simulation step. For this example, the OutputImpl
function increments the simulation step in the UserData
structure and sets actor properties to enable Gravity
and Collisions
after each simulation step. This function uses the simulation step value in the UserData
structure to set the properties of Box1
and Box3
so that the box actors simulate and report events one after the other. To visualize click event, the function creates annotation actors, text
and arrow
using the objects sim3d.graphics.Text
and sim3d.graphics.Arrow
, respectively. The text
displays the message Click the box
and arrow
points at Box5
.
function OutputImpl(world) if world.UserData.Step == 100 world.Actors.Box1.Gravity = true; end if world.UserData.Step == 500 world.Actors.Box3.Gravity = true; end if world.UserData.Step == 625 world.Actors.Box3.Collisions = true; end if world.UserData.Step == 820 text = sim3d.graphics.Text( ... ActorName="Text", ... Translation=[0 1 5], ... String="Click the box", ... FontSize=4,Color=[1 1 0]); add(world,text,world.Actors.Box5); arrow = sim3d.graphics.Arrow( ... ActorName="Arrow", ... Translation=[0 2 4.5],... Rotation=[0 -pi/3 -pi/2], ... Scale=[1 1 1]*5, ... Length=0.5, ... Color=[0 0 1]); add(world,arrow,world.Actors.Box5); end world.UserData.Step = world.UserData.Step + 1; end
See Also
sim3d.Actor
| sim3d.World
| createShape
| add
| run