我设法检测到3D中的碰撞,但是"类似的" 2D不起作用。
对于3D,我这样做:
SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(Main, HandleNodeCollision));
并在发生冲突时调用回调:
void HandleNodeCollision(StringHash eventType, VariantMap& eventData) {
std::cout << "asdf" << std::endl;
}
但是当我为2D尝试相同时,它永远不会被调用。
下面的完整可运行代码,使用以下样板测试:https://github.com/cirosantilli/Urho3D-cheat/blob/e2c955a45d8328fd5f8bf4df5685653452cb28a7/collision.cpp和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);
类似的可运行和正常工作的3D版本可在以下位置找到:https://github.com/cirosantilli/Urho3D-cheat/blob/e2c955a45d8328fd5f8bf4df5685653452cb28a7/collision3d.cpp
答案 0 :(得分:2)
2D事件名称为E_NODEBEGINCONTACT2D
只需将E_NODECOLLISION
替换为E_NODEUPDATECONTACT2D
即可。
发现于:https://discourse.urho3d.io/t/solved-help-with-collision-detection/1667
此文件中包含所有2D事件的名称:https://github.com/urho3d/Urho3D/blob/26ff4fce30bcc8f5a9f21e0e938d221cb2a53eaa/Source/Urho3D/Urho2D/PhysicsEvents2D.h#L35它们是:
E_PHYSICSUPDATECONTACT2D
:联系时。一次为两个机构。E_PHYSICSBEGINCONTACT2D
:开始联系E_PHYSICSENDCONTACT2D
:联系结束E_NODEUPDATECONTACT2D
:联系时。每个身体一次。E_NODEBEGINCONTACT2D
:开始联系E_NODEENDCONTACT2D
:结束联系这是我更新的工作代码,它还从事件中提取碰撞信息:https://github.com/cirosantilli/Urho3D-cheat/blob/353d0353328fc4deb788336f740c7df00d3415f1/collision.cpp#L110