在RealityView中独立旋转多个ModelEntity的实现方案
实现RealityView中多ModelEntity独立旋转的方案
一、为每个实体单独添加旋转手势的方法
要让多个ModelEntity各自独立响应旋转手势,核心是识别拖拽操作对应的实体,针对性更新其旋转状态,而非给整个RealityView绑定全局手势。具体实现步骤如下:
- 定义状态变量存储每个实体的旋转角度:
@State private var cube1Rotation: Angle = .zero @State private var cube2Rotation: Angle = .zero
- 在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] ) } }
- 使用
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
相关产品推荐
相关产品推荐

