In a 3d game it is often desirable to call events asynchronously when an entity such as the player, or other types of entities overlap with a specific bounding volume. How would I program this in C++ such that the Trigger Volume detects this actor/entity/whatever that overlapped it and can get a handle/pointer to it and execute an event on it. This is what Unreal Engine 4 does for example with its dozens of Volume
s for example TriggerBox
with OnBeginOverlap
UFunction
. But this isn't a ue question, this is barebones c++ implementation question.
I've thought about using my global message bus to send an event from the TriggerBox (which I also define as a subclass of Entity) to the overlapped entity.
But something tells me there should be a better more intuitive way to this.
Just to be clear. Say I've put a trigger volume/box in the world with its volume being: {xmin=0,xmax=2,ymin=0,ymax=4,zmin=-10,zmax=10}
Something like that in code:
struct Vol
{
Vec3 m_min;
Vec3 m_max;
Vol( const Vec3& min, const Vec3& max)
: m_min( min ),
m_max( max )
{}
};
class Volume // abstract class
: public Entity
{
bool m_enabled;
Vol m_volume;
RenderableEntity* m_currentActor;
RenderableEntity* m_parent;
public:
Volume( bool enabled, Vol vol )
: m_enabled{enabled},
m_volume(vol)
//…
};
class TriggerVolume
: public Volume
{
public:
TriggerVolume( Vol vol, enabled = true )
: Volume( enabled, vol )
{}
void onEnter( Actor* a );
void onExit( Actor* a );
void onHit( Projectile* a );
};
Actor
is a subclass of Entity too (RenderableEntity
in my engine), just to give you an idea of how I'm thinking about it.
[ I am not settled in inheriting from Entity is suitable for my non-renderable entities (eg. TriggerVolumes), maybe I'll inherit from an interface instead, but don't worry about these details now. ]
So when an actor enters the volume defined by this TriggerVolume
, the latter detects the actor, runs the onEnter
event function and does whatever it wants to do..
How would the TriggerVolume detect this actor? Do I run an update each frame on all my world's trigger volumes to test if any actors lie inside them? I have an Octree which can find entities given a bounding box as input. But that's what I want to potentially avoid. I'm thinking that it's kind of overkill and maybe there is a better way to go about it such that the trigger volume itself detects this specific actor that just started overlapping. Again, I'm inspired from UE4, but I've seen the trigger volume concept in every game engine I've tinkered with.
Examples:
- When an entity overlaps a volume the onEnter() of that volume calls the
actor→damage( 15 /*hit points*/)
- this is a "pain volume". - Another trigger volume when the player overlaps it, it checks if this actor is the player actor and if so starts a cutscene.
etc.
Opinions and your input are very appreciated!
Thank you.