首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在2D世界中检测碰撞事件并在Urho3D中运行回调?

如何在2D世界中检测碰撞事件并在Urho3D中运行回调?
EN

Stack Overflow用户
提问于 2017-11-27 06:34:08
回答 1查看 417关注 0票数 1

我已经成功地检测到了3D中的碰撞,但是“类似”的2D没有工作。

对于3D,我需要:

代码语言:javascript
复制
SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(Main, HandleNodeCollision));

每当发生冲突时,回调就会被调用:

代码语言:javascript
复制
void HandleNodeCollision(StringHash eventType, VariantMap& eventData) {
    std::cout << "asdf" << std::endl;
}

但是当我对2D做同样的尝试时,它就不会被调用。

下面的全部可运行代码,用以下样板进行测试:https://github.com/cirosantilli/Urho3D-cheat/blob/e2c955a45d8328fd5f8bf4df5685653452cb28a7/collision.cpp和Urho3D @ 5e8a275:

代码语言:javascript
复制
#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中找到。

EN

回答 1

Stack Overflow用户

发布于 2017-11-27 06:39:55

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47505166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档