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

RealityKit中球体穿过平面未触发碰撞,如何解决?

问题修复方案

核心问题分析

  • 平面缺少物理体配置:仅设置碰撞形状不足以让物理引擎识别平面为碰撞实体,必须添加HasPhysicsBody协议并配置静态物理体。
  • 碰撞订阅被提前销毁:subscriptions是makeUIView内的局部变量,方法执行完毕后会被释放,导致碰撞事件监听失效。
  • 强制类型转换存在风险:直接声明实体需遵循的协议,比强制类型转换更安全清晰。

修复后的完整代码

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer: UIViewRepresentable {
    
    // 将订阅存储提升为结构体属性,避免提前释放
    private var subscriptions = Set<AnyCancellable>()
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        let anchor = AnchorEntity()
    
        // 创建带物理体的平面
        let planeModel = ModelEntity(
            mesh: .generatePlane(width: 2.0, depth: 2.0),
            materials: [SimpleMaterial(color: .gray, isMetallic: false)]
        ) as Entity & HasCollision & HasPhysicsBody
        
        planeModel.position = [0, -10, -1.5]
        planeModel.generateCollisionShapes(recursive: true)
        planeModel.physicsBody = .init()
        planeModel.physicsBody?.mode = .static  // 设置为静态物理体,固定不动
        
        // 创建球体
        let ballModel = ModelEntity(
            mesh: .generateSphere(radius: 0.4),
            materials: [SimpleMaterial(color: .red, isMetallic: true)]
        ) as Entity & HasCollision & HasPhysicsBody
        
        ballModel.generateCollisionShapes(recursive: true)
        ballModel.position = [0, 0, -1.5]
        ballModel.physicsBody = .init()
        ballModel.physicsBody?.mode = .dynamic
        
        // 持久化碰撞事件订阅
        arView.scene.subscribe(to: CollisionEvents.Began.self, on: ballModel) { _ in
            print("OCCURED!")
        }.store(in: &subscriptions)
        
        anchor.addChild(ballModel)
        anchor.addChild(planeModel)
        arView.scene.addAnchor(anchor)
        
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {}
}

关键修复说明

  • 给平面添加HasPhysicsBody协议并设置static模式,让物理引擎将其识别为可碰撞的地面。
  • 将subscriptions改为结构体属性(使用Set<AnyCancellable>规范存储),确保订阅在ARView生命周期内持续生效。
  • 优化实体类型声明方式,替代强制类型转换,提升代码安全性和可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:01:54