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

RealityKit中自动碰撞盒偏移、按钮触发模型位移及平面移动实现问题求助

RealityKit中自动碰撞盒偏移、按钮触发模型位移及平面移动实现问题求助

嘿各位,我最近在RealityKit里折腾一个绑定好的3D模型,遇到几个卡壳的问题,想请大家帮忙看看:

  • 模型能成功加载,但自动生成的碰撞盒居然跑到模型下方去了,完全没贴合模型本身
  • 我想做个按钮,点击就让模型往上挪一点,但目前写的代码好像没起作用
  • 另外想问下,能不能让这个模型在AR检测到的平面上自由移动呀?

下面是我目前的代码,麻烦大家帮我找找问题在哪:

import SwiftUI
import RealityKit
import Combine

struct ContentView : View {
    
    @State private var yOffset: Float = 0.0
    @State var btnPressed = false
    
    var body: some View {
        VStack{
            ARViewContainer(yOffset: $yOffset)
            
            Button {
                btnPressed.toggle()
                yOffset += 0.1
                arView.arView.debugOptions = btnPressed ? [] :
                [.showPhysics,.showFeaturePoints,.showAnchorOrigins]
            } label: {
                Text("Show Debug")
            }
        }
    }
}

struct ARViewContainer: UIViewRepresentable {
    
    @Binding var yOffset: Float
    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {
        arView.addGestureRecognizer(UITapGestureRecognizer(
            target: context.coordinator,
            action: #selector(context.coordinator.handleTap)))
        context.coordinator.arview = arView
        
        //        let boxMesh = MeshResource.generateBox(size: 0.05)
        //        let boxMaterial = SimpleMaterial(color: UIColor.red, isMetallic: true)
        //        let boxEntity = ModelEntity(mesh: boxMesh, materials: [boxMaterial])
        //        boxEntity.generateCollisionShapes(recursive: true)
        //        let planeAnchor = AnchorEntity(plane: .horizontal)
        //        planeAnchor.addChild(boxEntity)
        //        arView.scene.addAnchor(planeAnchor)
        
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        if let modelEntity = uiView.scene.anchors.compactMap({ $0 as? ModelEntity }).first {
            modelEntity.position.y += yOffset
        }
    }
    
    func makeCoordinator() -> ARCoordinator {
        return ARCoordinator()
    }
}

#Preview {
    ContentView()
}

class ARCoordinator: NSObject {
    
    var arview: ARView?
    var cancellable: AnyCancellable?
    
    @objc func handleTap(_ recognizer: UITapGestureRecognizer){
        if let arview {
            let tapLocation = recognizer.location(in: arview)
            arview.debugOptions = [.showPhysics]
            
            //            if let tappedEntity = arview.entity(at: tapLocation) as? ModelEntity {
            //                tappedEntity.model?.materials = [SimpleMaterial(color: UIColor.purple, isMetallic: true)]
            //            }
            
            let results = arview.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal)
            if let hitResult = results.first{
                //                let anchorEntity = AnchorEntity(raycastResult: hitResult)
                //                let boxMesh = MeshResource.generateBox(size: 0.2)
                //                let boxMaterial = SimpleMaterial(color: UIColor.red, isMetallic: true)
                //                let boxEntity = ModelEntity(mesh: boxMesh, materials: [boxMaterial])
        //    anchorEntity.addChild(boxEntity)
                //                boxEntity.generateCollisionShapes(recursive: true)
                //                arview.installGestures(.all, for: boxEntity)
                
                let anchorEntity = AnchorEntity(raycastResult: hitResult)
                cancellable =  ModelEntity.loadModelAsync(named: "Evangelion_-_Eva_01_Rigged")
                    .sink { [self] result  in
                        switch result {
                        case .finished:
                            print("Finished")
                            cancellable?.cancel()
                            break
                        case .failure(let error):
                            print(error)
                            break
                        }
                    } receiveValue: { modelEnity in
                        modelEnity.generateCollisionShapes(recursive: true)
                        anchorEntity.addChild(modelEnity)
                        arview.installGestures(.all, for: modelEnity)
                        arview.scene.addAnchor(anchorEntity)
                    }
            }
        }
    }
}

特别困惑的几个点:

  1. 碰撞盒偏移是不是因为模型本身的轴心设置问题?还是generateCollisionShapes(recursive: true)这个方法的参数不对?
  2. 按钮触发位移的部分,我在updateUIView里尝试获取场景里的ModelEntity然后改position,但看下来好像没找到正确的实体?
  3. 如果要实现模型在平面上移动,是不是应该结合手势或者重新做raycast定位?

希望大家能给点思路或者修改建议,谢谢啦!

备注:内容来源于stack exchange,提问作者user11640506

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 13:04:40