Open AMZN-alexpete opened 1 year ago
Testing this now, so I decided to leave here some feedback and the steps I used. The OnPhysicsEnabled() is the best solution so far!
Tried calling the triggers in three different functions: OnActivate(), OnTick() and OnPhysicsEnabled():
local T =
{
Properties =
{
FromEntity1 =
{
default = EntityId(),
description = "Just an entity with collider and trigger on"
}
}
}
function T:OnActivate()
-- -- Expose OnTick function:
self.tickBusHandler = TickBus.Connect(self); --, self.entityId)
-- -- Expose OnPhysicsEnabled, OnPhysicsDisabled
self.rigidBodyHandler = RigidBodyNotificationBus.Connect(self, self.Properties.FromEntity[1]);
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function T:OnDeactivate()
-- -- IMPORTANT NOTE: When you add handlers, disconnect them!
-- -- TODO: add more here!
-- -- clean/reset memory
if (self.tickBusHandler ~= nil) then
self.tickBusHandler:Disconnect();
-- self.tickBusHandler = nil;
end
-- -- physics:
if (self.rigidBodyHandler ~= nil) then
self.rigidBodyHandler:Disconnect();
end
if (self.triggerHandlerExit ~= nil) then
self.triggerHandlerExit:Disconnect();
self.triggerEventExit = nil;
end
if (self.triggerHandlerEnter ~= nil) then
self.triggerHandlerEnter:Disconnect();
self.triggerEventEnter = nil;
end
self.Properties = nil;
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- NOT RECOMMENDED USE-CASE
function T:OnTick(deltaTime)
-- -- Trigger event requires "Trigger ON"
-- T:TriggerEnter(self, self.Properties.FromEntity1);
-- T:TriggerExit(self, self.Properties.FromEntity1);
-- -- TODO: add more here, and comment the ones you are not testing!
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- RECOMMENDED USE-CASE
function T:OnPhysicsEnabled(entityId)
--- -- Trigger event requires "Trigger ON"
T:TriggerEnter(self, self.Properties.FromEntity1);
T:TriggerExit(self, self.Properties.FromEntity1);
-- -- TODO: add more here, and comment the ones you are not testing!
Debug.Log("Physics Enabled");
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- When a colider enters, this activates
function T:TriggerEnter(selfId, triggerSourceId)
selfId.triggerEventEnter = SimulatedBody.GetOnTriggerEnterEvent(triggerSourceId);
if selfId.triggerEventEnter ~= nil then
selfId.triggerHandlerEnter = selfId.triggerEventEnter:Connect(
function()
Debug:Log("Enter trigger")
end);
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- When a colider exits, this activates
function T:TriggerExit(selfId, triggerSourceId)
selfId.triggerEventExit = SimulatedBody.GetOnTriggerExitEvent(triggerSourceId);
if selfId.triggerEventExit ~= nil then
selfId.triggerHandlerExit = selfId.triggerEventExit:Connect(
function()
Debug:Log("Exit trigger")
end);
end
end
return T;
This alone is enough to test. Both work, OnTick and OnPhysicsEnabled, but the latter is much better! I would not recomment the use of OnTick, but some asked me to start there, due to the lack of alternative! OnPhysicsEnabled is that alternative, please use it instead of OnTick.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- When a collision begins, and trigger is "off", this activates
function T:CollisionBegin(selfId, triggerSourceId)
selfId.collisionBegin = SimulatedBody.GetOnCollisionBeginEvent(triggerSourceId);
if selfId.collisionBegin ~= nil then
selfId.collisionBeginHandler = selfId.collisionBegin:Connect(
function()
Debug:Log("Collision Begin")
end);
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- When a collision persists, and trigger is "off", this activates
-- -- This function has the worst performance of all! Dropping to 5 fps
function T:CollisionPersist(selfId, triggerSourceId)
selfId.collisionPersist = SimulatedBody.GetOnCollisionPersistEvent(triggerSourceId);
if selfId.collisionPersist ~= nil then
selfId.collisionPersistHandler = selfId.collisionPersist:Connect(
function()
Debug:Log("Collision Persist")
end);
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- When a collision ends, and trigger is "off", this activates
function T:CollisionEnd(selfId, triggerSourceId)
selfId.collisionEnd = SimulatedBody.GetOnCollisionEndEvent(triggerSourceId);
if selfId.collisionEnd ~= nil then
selfId.collisionEndHandler = selfId.collisionEnd:Connect(
function()
Debug:Log("Collision End")
end);
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Some additional features/commands/functions:
Just add these to the script, and modify the OnPhysicsEnabled() and OnDeactivate() to call these instead. Remember that you need to turn ON the trigger in the collider-component.
-- -- Enter: Modified version to GetTriggerEntityId and GetOtherEntityId
function T:TriggerEnter2(selfId, triggerSourceId)
selfId.triggerEventEnter2 = SimulatedBody.GetOnTriggerEnterEvent(triggerSourceId);
if selfId.triggerEventEnter2 ~= nil then
selfId.triggerHandlerEnter2 = selfId.triggerEventEnter2:Connect(
function(tuple, event)
triggeredEntityId = TriggerEvent.GetTriggerEntityId(event)
otherEntityId = TriggerEvent.GetOtherEntityId(event)
Debug:Log("Enter trigger. Entity with trigerOn is (GetTriggerEntityId):"..tostring(triggeredEntityId)..". The other entity is (OtherEntityId): "..tostring(otherEntityId))
end);
end
end
-- -- Exit:
function T:TriggerExit2(selfId, triggerSourceId)
selfId.triggerEventExit2 = SimulatedBody.GetOnTriggerExitEvent(triggerSourceId);
if selfId.triggerEventExit2 ~= nil then
selfId.triggerHandlerExit2 = selfId.triggerEventExit2:Connect(
function(tuple, event)
triggeredEntityId = TriggerEvent.GetTriggerEntityId(event)
otherEntityId = TriggerEvent.GetOtherEntityId(event)
Debug:Log("Exit trigger. Entity with trigerOn is (GetTriggerEntityId):"..tostring(triggeredEntityId)..". The other entity is (OtherEntityId): "..tostring(otherEntityId))
end);
end
end
Just add these to the script, and modify the OnPhysicsEnabled() and OnDeactivate() to call these instead. Remember that you need to turn OFF the trigger in the collider-component.
-- -- Begin: Modified version to GetBody1EntityId and GetBody2EntityId
function T:CollisionBegin2(selfId, triggerSourceId)
selfId.collisionBegin2 = SimulatedBody.GetOnCollisionBeginEvent(triggerSourceId);
if selfId.collisionBegin2 ~= nil then
selfId.collisionBeginHandler2 = selfId.collisionBegin2:Connect(
function(tuple, event)
local body1EntityId = CollisionEvent.GetBody1EntityId(event)
local body2EntityId = CollisionEvent.GetBody2EntityId(event)
Debug:Log("Collision Begin. Entity with trigerOff is (GetBody1EntityId):"..tostring(body1EntityId)..". The other entity is (GetBody2EntityId): "..tostring(body2EntityId))
end);
end
end
-- -- Persist: Modified version to GetBody1EntityId and GetBody2EntityId
function T:CollisionPersist2(selfId, triggerSourceId)
selfId.collisionPersist2 = SimulatedBody.GetOnCollisionPersistEvent(triggerSourceId);
if selfId.collisionPersist2 ~= nil then
selfId.collisionPersistHandler2 = selfId.collisionPersist2:Connect(
function(tuple, event)
local body1EntityId = CollisionEvent.GetBody1EntityId(event)
local body2EntityId = CollisionEvent.GetBody2EntityId(event)
Debug:Log("Collision Persist. Entity with trigerOff is (GetBody1EntityId):"..tostring(body1EntityId)..". The other entity is (GetBody2EntityId): "..tostring(body2EntityId))
end);
end
end
-- -- End: Modified version to GetBody1EntityId and GetBody2EntityId
function T:CollisionEnd2(selfId, triggerSourceId)
selfId.collisionEnd2 = SimulatedBody.GetOnCollisionEndEvent(triggerSourceId);
if selfId.collisionEnd2 ~= nil then
selfId.collisionEndHandler2 = selfId.collisionEnd2:Connect(
function(tuple, event)
local body1EntityId = CollisionEvent.GetBody1EntityId(event)
local body2EntityId = CollisionEvent.GetBody2EntityId(event)
Debug:Log("Collision End. Entity with trigerOff is (GetBody1EntityId):"..tostring(body1EntityId)..". The other entity is (GetBody2EntityId): "..tostring(body2EntityId))
end);
end
end
Additional notes:
Nice
This will Help a lot.
Describe the issue briefly
Almost all the physics ebuses are gone or not exposed to Lua and in their place are new classes and functionality that is not well documented and one of the most important pieces is how to use triggers/colliders and simulated bodies.
code for a trigger looks like this:
however it relies on
SimulatedBody
to be around and active which it probably NOT be inOnActivate
where you expect it to be ready (another doc gap?) and there doesn't appear to be an ebus for telling you when it is ready so you at least need to wait till the next tick to run the above code.Which page(s) / section(s) are affected?
Possibly a new page around here: https://www.o3de.org/docs/user-guide/scripting/lua/ebus/
Does this work have an engineering dependency? What is it?
you might need to have an engineer dive in to find the best way to know when it is OK to use the
SimulatedBody