I have managed to detect collisions in 3D, but the "analogous" 2D did not work.
For the 3D, I do:
SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(Main, HandleNodeCollision));
and the callback gets called whenever there is a collision:
void HandleNodeCollision(StringHash eventType, VariantMap& eventData) {
std::cout << "asdf" << std::endl;
}
but when I try the same for 2D, it never gets called.
Full runnable code below, tested with the following boilerplate: https://github.com/cirosantilli/Urho3D-cheat/blob/e2c955a45d8328fd5f8bf4df5685653452cb28a7/collision.cpp and Urho3D @ 5e8a275:
#include <iostream>
#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Core/Object.h>
#include <Urho3D/Engine/Application.h>
#include <Urho3D/Engine/Engine.h>
#include <Urho3D/Engine/EngineDefs.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/DebugRenderer.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Input/InputEvents.h>
#include <Urho3D/Physics/PhysicsEvents.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/Scene/SceneEvents.h>
#include <Urho3D/Urho2D/CollisionBox2D.h>
#include <Urho3D/Urho2D/CollisionCircle2D.h>
#include <Urho3D/Urho2D/PhysicsWorld2D.h>
#include <Urho3D/Urho2D/RigidBody2D.h>
#include <Urho3D/Scene/Component.h>
using namespace Urho3D;
class Main : public Application {
URHO3D_OBJECT(Main, Application);
public:
Main(Context* context) : Application(context) {}
virtual void Setup() override {
engineParameters_[EP_FULL_SCREEN] = false;
engineParameters_[EP_WINDOW_TITLE] = __FILE__;
engineParameters_[EP_WINDOW_HEIGHT] = 512;
engineParameters_[EP_WINDOW_WIDTH] = 512;
}
void Start() {
auto windowWidth = 10.0f;
auto windowHeight = windowWidth;
auto groundWidth = windowWidth;
auto groundHeight = 1.0f;
auto ballRadius = 0.5f;
auto ballRestitution = 0.8f;
auto ballDensity = 1.0f;
// TODO: not working. Is there any way to avoid creating a custom
// Component as in the ragdoll example?
SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(Main, HandleNodeCollision));
SubscribeToEvent(E_POSTRENDERUPDATE, URHO3D_HANDLER(Main, HandlePostRenderUpdate));
SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(Main, HandleKeyDown));
// Scene
this->scene_ = new Scene(this->context_);
this->scene_->CreateComponent<Octree>();
this->scene_->CreateComponent<DebugRenderer>();
this->scene_->CreateComponent<PhysicsWorld2D>();
auto physicsWorld = scene_->GetComponent<PhysicsWorld2D>();
physicsWorld->SetGravity(Vector2(0.0f, -10.0f));
// Graphics
auto cameraNode_ = this->scene_->CreateChild("Camera");
// Center of the camera.
cameraNode_->SetPosition(Vector3(0.0f, windowHeight / 2.0, -1.0f));
auto camera = cameraNode_->CreateComponent<Camera>();
camera->SetOrthographic(true);
camera->SetOrthoSize(windowWidth);
auto renderer = GetSubsystem<Renderer>();
SharedPtr<Viewport> viewport(new Viewport(context_, this->scene_, cameraNode_->GetComponent<Camera>()));
renderer->SetViewport(0, viewport);
// Ground
{
auto node = this->scene_->CreateChild("Ground");
node->SetPosition(Vector3(0.0f, groundHeight / 2.0f, 0.0f));
node->CreateComponent<RigidBody2D>();
auto collisionBox2d = node->CreateComponent<CollisionBox2D>();
collisionBox2d->SetSize(Vector2(groundWidth, groundHeight));
}
// Falling balls
{
auto nodeLeft = this->scene_->CreateChild("BallLeft");
{
auto& node = nodeLeft;
node->SetPosition(Vector3(-windowWidth / 4.0f, windowHeight / 2.0f, 0.0f));
auto body = node->CreateComponent<RigidBody2D>();
body->SetBodyType(BT_DYNAMIC);
auto collisionCircle2d = node->CreateComponent<CollisionCircle2D>();
collisionCircle2d->SetRadius(ballRadius);
collisionCircle2d->SetDensity(ballDensity);
collisionCircle2d->SetRestitution(ballRestitution);
}
auto nodeRight = nodeLeft->Clone();
nodeRight->SetPosition(Vector3(windowWidth / 4.0f, windowHeight * (3.0f / 4.0f), 0.0f));
}
}
void Stop() {}
private:
SharedPtr<Scene> scene_;
void HandleNodeCollision(StringHash eventType, VariantMap& eventData) {
std::cout << "asdf" << std::endl;
}
void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData) {
auto physicsWorld = this->scene_->GetComponent<PhysicsWorld2D>();
physicsWorld->DrawDebugGeometry();
}
void HandleKeyDown(StringHash /*eventType*/, VariantMap& eventData) {
using namespace KeyDown;
int key = eventData[P_KEY].GetInt();
if (key == KEY_ESCAPE) {
engine_->Exit();
}
}
};
URHO3D_DEFINE_APPLICATION_MAIN(Main);
The analogous runnable and working as expected 3D version can be found at: https://github.com/cirosantilli/Urho3D-cheat/blob/e2c955a45d8328fd5f8bf4df5685653452cb28a7/collision3d.cpp