Blender导入模型的Cylinder添加Collision Component后碰撞无效
问题
导入包含平面(Plane)和圆柱体(Cylinders)的Blender模型后,尝试为圆柱体添加碰撞组件,但碰撞功能未生效。已确认模型及子实体结构打印正常,实体结构如下:
▿ '/' : Entity, children: 1 ⟐ Transform ⟐ SynchronizationComponent ▿ 'cilinders' : Entity, children: 6 ⟐ Transform ⟐ SynchronizationComponent ▿ 'Light' : Entity ⟐ Transform ⟐ SynchronizationComponent ▿ 'Camera' : Entity ⟐ Transform ⟐ SynchronizationComponent ▿ 'Plane' : Entity, children: 1 ⟐ Transform ⟐ SynchronizationComponent ▿ 'Plane_geometry' : ModelEntity ⟐ Transform ⟐ ModelComponent ⟐ SynchronizationComponent ▿ 'Cylinder' : Entity, children: 1 ⟐ Transform ⟐ SynchronizationComponent ▿ 'Cylinder_geometry' : ModelEntity ⟐ Transform ⟐ ModelComponent ⟐ SynchronizationComponent ▿ 'Cylinder_001' : Entity, children: 1 ⟐ Transform ⟐ SynchronizationComponent ▿ 'Cylinder_001_geometry' : ModelEntity ⟐ Transform ⟐ ModelComponent ⟐ SynchronizationComponent ▿ 'Cylinder_002' : Entity, children: 1 ⟐ Transform ⟐ SynchronizationComponent ▿ 'Cylinder_002_geometry' : ModelEntity ⟐ Transform ⟐ ModelComponent ⟐ SynchronizationComponent
已编写以下代码为单个圆柱体添加碰撞并订阅碰撞事件,但无效果:
let cylinder1 = importModel.children[0].children[3].children[0] as! ModelEntity cylinder1.generateCollisionShapes(recursive: false)
DispatchQueue.main.async { arView.scene.subscribe(to: CollisionEvents.Began.self, on: cylinder1) { _ in print("Collision ball detected!") }.store(in: &self.subscriptions) }
修复方案
以下是你遗漏的关键环节及修复方法:
碰撞双方都需具备碰撞组件:碰撞事件触发的前提是两个交互实体都拥有
CollisionComponent。如果是和虚拟物体(比如测试用的小球)碰撞,要给该物体也生成碰撞形状;如果是和AR场景中的真实平面交互,需确认ARPlaneAnchor对应的实体已开启碰撞。检查碰撞掩码匹配性:默认生成的碰撞掩码可能和目标实体不匹配,导致事件无法触发。手动设置掩码确保双方兼容:
cylinder1.collision?.filter.group = .all cylinder1.collision?.filter.mask = .all替换硬索引的实体获取方式:
importModel.children[0].children[3].children[0]这种硬编码索引极易因模型结构变动出错,建议通过名称递归查找实体:func findModelEntity(named targetName: String, in entity: Entity) -> ModelEntity? { if let modelEntity = entity as? ModelEntity, modelEntity.name == targetName { return modelEntity } for child in entity.children { if let found = findModelEntity(named: targetName, in: child) { return found } } return nil } // 使用示例 if let cylinder1 = findModelEntity(named: "Cylinder_geometry", in: importModel) { cylinder1.generateCollisionShapes(recursive: false) // 后续设置掩码、订阅事件 }确认事件订阅时机:必须在实体被添加到ARView场景后再订阅碰撞事件,否则无法接收回调。建议在模型导入完成并加入场景后执行订阅逻辑。
调整碰撞形状生成参数:如果圆柱体模型包含子网格,
recursive: false可能无法生成完整的碰撞形状,尝试改为recursive: true:cylinder1.generateCollisionShapes(recursive: true)
内容的提问来源于stack exchange,提问作者saro
相关产品推荐
相关产品推荐

