Entity Helpers
Categories:
Overview
PhysicsTriggeringVolume is a base class that provides everything needed to process physics trigger overlaps and collision contacts. Inherit from it to create interactive volumes — damage zones, pickup areas, dialogue triggers, environmental hazards — without writing boilerplate physics code.
It handles entity tracking (so you only get one enter/exit per entity), supports both trigger overlaps and collision contacts, and provides optional hold/persist callbacks for continuous processing.
TypeId: {A0C4C982-1B31-4FD3-9386-AD1A57ABEF8E}
How It Works
- Your component inherits from
PhysicsTriggeringVolume(which itself inherits fromAZ::Component). - The base class connects to the physics trigger and collision buses automatically.
- When an entity enters/exits the volume, the base class tracks it and calls your override methods.
- Optionally enable hold updates for continuous processing while entities remain inside.
Entity Tracking
The base class maintains an internal m_entities list that tracks which entities are currently inside the volume. This ensures:
TriggerEnter/CollisionEnterfires only once per entity (not on every physics tick).TriggerExit/CollisionExitfires only when an entity that was previously inside leaves.
API Reference
Trigger Overlap Methods
Override these to react to PhysX trigger volume events.
| Method | Description |
|---|---|
TriggerEnter() | Called when a new entity enters the trigger volume. |
TriggerExit() | Called when an entity leaves the trigger volume. |
TriggerHold() | Called on each physics tick while an entity remains inside. Requires EnableTriggerHoldUpdate to be enabled. |
Collision Contact Methods
Override these to react to PhysX rigid body collision events.
| Method | Description |
|---|---|
CollisionEnter() | Called when a new entity begins colliding with this volume. |
CollisionExit() | Called when an entity stops colliding with this volume. |
CollisionHold() | Called on each physics tick while collision persists. Requires EnableTriggerHoldUpdate to be enabled via OnCollisionPersist. |
Configuration
| Property | Description |
|---|---|
EnableTriggerHoldUpdate | Enables the TriggerHold() / CollisionHold() callbacks on each physics tick. Disabled by default for performance. |
Extending Entity Helpers
public virtual to avoid double-inheritance issues with AZ::Component. Do not add a second AZ::Component inheritance in your class.Header (.h)
#pragma once
#include <GS_Core/Utilities/PhysicsTriggeringVolume.h>
namespace MyProject
{
class DamageZoneComponent
: public virtual GS_Core::PhysicsTriggeringVolume
{
public:
AZ_COMPONENT_DECL(DamageZoneComponent);
static void Reflect(AZ::ReflectContext* context);
protected:
// IMPORTANT: Call parent Activate/Deactivate
void Activate() override;
void Deactivate() override;
// Trigger overrides
void TriggerEnter() override;
void TriggerExit() override;
void TriggerHold() override;
private:
float m_damagePerSecond = 10.0f;
};
}
Implementation (.cpp)
#include "DamageZoneComponent.h"
#include <AzCore/Serialization/SerializeContext.h>
namespace MyProject
{
AZ_COMPONENT_IMPL(DamageZoneComponent, "DamageZoneComponent", "{YOUR-UUID-HERE}");
void DamageZoneComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<DamageZoneComponent, GS_Core::PhysicsTriggeringVolume>()
->Version(0)
->Field("DamagePerSecond", &DamageZoneComponent::m_damagePerSecond);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<DamageZoneComponent>(
"Damage Zone", "Deals damage to entities inside the trigger volume")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "MyProject")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default,
&DamageZoneComponent::m_damagePerSecond,
"Damage Per Second", "How much damage to deal per second while inside");
}
}
}
void DamageZoneComponent::Activate()
{
// IMPORTANT: Call parent to connect to physics buses
PhysicsTriggeringVolume::Activate();
// Enable hold updates for continuous damage
// EnableTriggerHoldUpdate = true;
}
void DamageZoneComponent::Deactivate()
{
// IMPORTANT: Call parent to disconnect from physics buses
PhysicsTriggeringVolume::Deactivate();
}
void DamageZoneComponent::TriggerEnter()
{
// An entity entered the damage zone
AZ_TracePrintf("DamageZone", "Entity entered damage zone");
}
void DamageZoneComponent::TriggerExit()
{
// An entity left the damage zone
AZ_TracePrintf("DamageZone", "Entity exited damage zone");
}
void DamageZoneComponent::TriggerHold()
{
// Called each physics tick while entity is inside
// Apply damage: m_damagePerSecond * deltaTime
}
}
Module Registration
m_descriptors.insert(m_descriptors.end(), {
MyProject::DamageZoneComponent::CreateDescriptor(),
});
Setup
- Create an entity with a PhysX Collider component (set as trigger).
- Attach your custom trigger volume component (e.g.,
DamageZoneComponent). - Configure the collider shape and your component’s properties.
- Entities with rigidbodies that enter the collider will trigger your callbacks.
See Also
- Core Utilities — Entity Helpers, curves, and other utility libraries
- GS_Core — Core gem overview