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

在RealityView中独立旋转多个ModelEntity的实现方案

实现RealityView中多ModelEntity独立旋转的方案

一、为每个实体单独添加旋转手势的方法

要让多个ModelEntity各自独立响应旋转手势,核心是识别拖拽操作对应的实体,针对性更新其旋转状态,而非给整个RealityView绑定全局手势。具体实现步骤如下:

  1. 定义状态变量存储每个实体的旋转角度:
@State private var cube1Rotation: Angle = .zero
@State private var cube2Rotation: Angle = .zero
  1. 在RealityView中程序化生成实体,为每个实体添加InputTargetComponent(确保能接收输入事件),并设置唯一标识(比如name属性):
RealityView { content in
    // 生成第一个实体(红色立方体)
    let cube1 = ModelEntity(
        mesh: .generateBox(size: 0.5),
        materials: [SimpleMaterial(color: .red, isMetallic: false)]
    )
    cube1.name = "cube1"
    cube1.generateCollisionShapes(recursive: true)
    cube1.components.set(InputTargetComponent())
    cube1.position = [-0.75, 0, 0]
    content.add(cube1)

    // 生成第二个实体(蓝色立方体)
    let cube2 = ModelEntity(
        mesh: .generateBox(size: 0.5),
        materials: [SimpleMaterial(color: .blue, isMetallic: false)]
    )
    cube2.name = "cube2"
    cube2.generateCollisionShapes(recursive: true)
    cube2.components.set(InputTargetComponent())
    cube2.position = [0.75, 0, 0]
    content.add(cube2)
} update: { content in
    // 根据状态变量更新实体旋转
    if let cube1 = content.entities.first(where: { $0.name == "cube1" }) {
        cube1.transform.rotation = simd_quatf(
            angle: Float(cube1Rotation.radians),
            axis: [0, 1, 0] // 绕Y轴旋转
        )
    }
    if let cube2 = content.entities.first(where: { $0.name == "cube2" }) {
        cube2.transform.rotation = simd_quatf(
            angle: Float(cube2Rotation.radians),
            axis: [0, 1, 0]
        )
    }
}
  1. 使用targetedToAnyEntity()的DragGesture,识别当前拖拽的实体并更新对应旋转状态:
.gesture(
    DragGesture()
        .targetedToAnyEntity()
        .onChanged { value in
            // 根据拖拽偏移量计算旋转增量
            let rotationDelta = value.translation.width * 0.01
            switch value.entity.name {
            case "cube1":
                cube1Rotation += .radians(rotationDelta)
            case "cube2":
                cube2Rotation += .radians(rotationDelta)
            default:
                break
            }
        }
)

这种方式下,每个实体的旋转状态独立维护,拖拽时只会修改被选中实体的角度。

二、能否用Model3D实现?

可以。Model3D是SwiftUI原生视图,每个Model3D实例可单独绑定手势,天然支持独立交互:

@State private var model1Rotation: Double = 0
@State private var model2Rotation: Double = 0

var body: some View {
    HStack(spacing: 150) {
        // 第一个Model3D视图
        Model3D(named: "Cube", bundle: RealityKitContent.realityKitContentBundle) { model in
            model
                .resizable()
                .scaledToFit()
                .rotation3DEffect(
                    .degrees(model1Rotation),
                    axis: (x: 0, y: 1, z: 0)
                )
        } placeholder: {
            ProgressView()
        }
        .gesture(
            DragGesture()
                .onChanged { value in
                    model1Rotation += value.translation.width * 0.1
                }
        )

        // 第二个Model3D视图
        Model3D(named: "Cube", bundle: RealityKitContent.realityKitContentBundle) { model in
            model
                .resizable()
                .scaledToFit()
                .rotation3DEffect(
                    .degrees(model2Rotation),
                    axis: (x: 0, y: 1, z: 0)
                )
        } placeholder: {
            ProgressView()
        }
        .gesture(
            DragGesture()
                .onChanged { value in
                    model2Rotation += value.translation.width * 0.1
                }
        )
    }
}

需要注意的是,Model3D的旋转是SwiftUI的视图变换,而非RealityKit实体的transform修改。如果场景需要RealityKit的物理引擎、实体组件等特性,建议用RealityView方案;如果只是简单的UI级3D模型交互,Model3D更轻量便捷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:01:26