Added support for collision and trigger events in code properly

This commit is contained in:
Kah Wei 2022-11-01 00:11:09 +08:00
parent b7aca5b118
commit e4cb8ede5a
3 changed files with 97 additions and 49 deletions

View File

@ -21,6 +21,7 @@
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE namespace SHADE
{ {
@ -353,7 +354,17 @@ namespace SHADE
{ {
system->SyncTransforms(); system->SyncTransforms();
// TODO(Kah Wei): Take Collision & Trigger messages here // Collision & Trigger messages
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
if (scriptSys)
{
scriptSys->ExecuteFixedUpdates();
scriptSys->ExecuteCollisionFunctions();
}
else
{
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
}
system->ClearInvalidCollisions(); system->ClearInvalidCollisions();
} }

View File

@ -485,33 +485,39 @@ namespace SHADE
const auto& collisions = SHPhysicsSystemInterface::GetCollisionInfo(); const auto& collisions = SHPhysicsSystemInterface::GetCollisionInfo();
for (const auto& collisionInfo : collisions) for (const auto& collisionInfo : collisions)
{ {
const EntityID OWNER = collisionInfo.GetEntityA(); auto entities =
{
// Don't bother if this object has no scripts or is inactive std::make_pair(collisionInfo.GetEntityA(), collisionInfo.GetEntityB()),
if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) std::make_pair(collisionInfo.GetEntityB(), collisionInfo.GetEntityA())
continue; };
for (auto entity : entities)
// Construct the collision state object
CollisionInfo info;
info.GameObject = GameObject(OWNER);
// Call all of the script's functions
auto entityScripts = scripts[OWNER];
if (entityScripts->Count > 0)
{ {
for each (Script^ script in entityScripts) // Don't bother if this object has no scripts or is inactive
if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first))
continue;
// Construct the collision state object
CollisionInfo info;
info.GameObject = GameObject(entity.second);
// Call all of the script's functions
auto entityScripts = scripts[entity.first];
if (entityScripts->Count > 0)
{ {
switch (collisionInfo.GetCollisionState()) for each (Script ^ script in entityScripts)
{ {
case SHCollisionEvent::State::ENTER: switch (collisionInfo.GetCollisionState())
script->OnCollisionEnter(info); {
break; case SHCollisionEvent::State::ENTER:
case SHCollisionEvent::State::STAY: script->OnCollisionEnter(info);
script->OnCollisionStay(info); break;
break; case SHCollisionEvent::State::STAY:
case SHCollisionEvent::State::EXIT: script->OnCollisionStay(info);
script->OnCollisionExit(info); break;
break; case SHCollisionEvent::State::EXIT:
script->OnCollisionExit(info);
break;
}
} }
} }
} }
@ -520,33 +526,39 @@ namespace SHADE
const auto& triggers = SHPhysicsSystemInterface::GetTriggerInfo(); const auto& triggers = SHPhysicsSystemInterface::GetTriggerInfo();
for (const auto& triggerInfo : triggers) for (const auto& triggerInfo : triggers)
{ {
const EntityID OWNER = triggerInfo.GetEntityA(); auto entities =
{
// Don't bother if this object has no scripts or is inactive std::make_pair(triggerInfo.GetEntityA(), triggerInfo.GetEntityB()),
if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) std::make_pair(triggerInfo.GetEntityB(), triggerInfo.GetEntityA())
continue; };
for (auto entity : entities)
// Construct the collision state object
CollisionInfo info;
info.GameObject = GameObject(OWNER);
// Call all of the script's functions
auto entityScripts = scripts[OWNER];
if (entityScripts->Count > 0)
{ {
for each (Script ^ script in entityScripts) // Don't bother if this object has no scripts or is inactive
if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first))
continue;
// Construct the collision state object
CollisionInfo info;
info.GameObject = GameObject(entity.second);
// Call all of the script's functions
auto entityScripts = scripts[entity.first];
if (entityScripts->Count > 0)
{ {
switch (triggerInfo.GetCollisionState()) for each (Script ^ script in entityScripts)
{ {
case SHCollisionEvent::State::ENTER: switch (triggerInfo.GetCollisionState())
script->OnTriggerEnter(info); {
break; case SHCollisionEvent::State::ENTER:
case SHCollisionEvent::State::STAY: script->OnTriggerEnter(info);
script->OnTriggerStay(info); break;
break; case SHCollisionEvent::State::STAY:
case SHCollisionEvent::State::EXIT: script->OnTriggerStay(info);
script->OnTriggerExit(info); break;
break; case SHCollisionEvent::State::EXIT:
script->OnTriggerExit(info);
break;
}
} }
} }
} }

View File

@ -40,4 +40,29 @@ public class PhysicsTest : Script
} }
Debug.Log($"{Transform.LocalPosition.y}"); Debug.Log($"{Transform.LocalPosition.y}");
} }
protected override void onCollisionEnter(CollisionInfo info)
{
Debug.Log($"Collision Enter: {info.GameObject.Name}");
}
protected override void onCollisionStay(CollisionInfo info)
{
Debug.Log($"Collision Stay: {info.GameObject.Name}");
}
protected override void onCollisionExit(CollisionInfo info)
{
Debug.Log($"Collision Exit: {info.GameObject.Name}");
}
protected override void onTriggerEnter(CollisionInfo info)
{
Debug.Log($"Trigger Enter: {info.GameObject.Name}");
}
protected override void onTriggerStay(CollisionInfo info)
{
Debug.Log($"Trigger Stay: {info.GameObject.Name}");
}
protected override void onTriggerExit(CollisionInfo info)
{
Debug.Log($"Trigger Exit: {info.GameObject.Name}");
}
} }