You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LibGDX中Bullet 3D物理碰撞检测失效问题求助

LibGDX Bullet物理碰撞检测失效问题

我使用LibGDX开发一款带有3D物理效果的游戏,生成项目时已启用Bullet扩展。开发过程中遵循教程,但在设置重力后,碰撞检测功能失效。

相关代码

主逻辑代码

btDefaultCollisionConfiguration collisionConfig = new btDefaultCollisionConfiguration();
world = new btDiscreteDynamicsWorld(new btCollisionDispatcher(collisionConfig), new btSimpleBroadphase(), new btSequentialImpulseConstraintSolver(), collisionConfig);
world.setGravity(new Vector3(0, -10f, 0));
object = new btRigidBody(0, new btDefaultMotionState(), Bullet.obtainStaticNodeShape(model.nodes));
object.setWorldTransform(model.transform);
object.setCollisionFlags(object.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT);
world.addRigidBody(object);
object.setContactCallbackFlag(1 << 8);
object.setContactCallbackFilter(0);
object.setActivationState(Collision.DISABLE_DEACTIVATION);

world.addRigidBody(Player.collisionObject);
Player.collisionObject.setContactCallbackFlag(1 << 9);
Player.collisionObject.setContactCallbackFilter(1 << 8);

Player类代码

model = new ModelInstance(new ModelBuilder().createSphere(1, 1, 1, 10, 10, new Material(ColorAttribute.createDiffuse(Color.GREEN)), VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal));
btSphereShape shape = new btSphereShape(0.5f);
shape.calculateLocalInertia(1f, new Vector3(0, 0, 0));
collisionObject = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(1f, null, shape, new Vector3(0, 0, 0)));
model.transform = new Matrix4().translate(pos);
collisionObject.proceedToTransform(model.transform);
collisionObject.setCollisionFlags(Player.collisionObject.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
collisionObject.setUserValue(1);

问题修复方案

1. 补充Player刚体的MotionState

Player的btRigidBody构造时传入了null作为btDefaultMotionState,导致物理世界无法同步刚体的位置变换,碰撞检测无法正常触发。修改Player类代码:

// 创建MotionState并传入构造方法
btDefaultMotionState motionState = new btDefaultMotionState(model.transform);
collisionObject = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(1f, motionState, shape, new Vector3(0, 0, 0)));

2. 修正碰撞过滤规则

静态物体的setContactCallbackFilter(0)会忽略所有碰撞标记,导致与Player的碰撞无法触发回调。调整过滤规则,确保双方标记互斥匹配:

// 静态物体的filter设置为Player的callbackFlag
object.setContactCallbackFilter(1 << 9);
// Player的filter设置为静态物体的callbackFlag
Player.collisionObject.setContactCallbackFilter(1 << 8);

3. 优化静态物体的刚体配置

质量为0的静态物体无需设置CF_KINEMATIC_OBJECT(该标记用于主动运动的静态物体),删除多余代码:

// 移除这一行
// object.setCollisionFlags(object.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT);

4. 确保物理世界步进更新

在游戏的render方法中添加物理世界的步进逻辑,这是碰撞检测生效的必要条件:

@Override
public void render() {
    // ... 其他渲染逻辑
    world.stepSimulation(Gdx.graphics.getDeltaTime(), 5);
}

内容的提问来源于stack exchange,提问作者Dominicentek Gaming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:09:26