不明白RealityKit的entity.move在visionOS沉浸式空间中

问题描述 投票:0回答:1

设置:
我正在开发一个使用沉浸式空间的visionOS应用程序。
用户看到一个板上放置了实体。 我的应用程序将板放置在默认相机和相对于板具有特定位置和方向的实体前面。放置和旋转应该是动画的。

问题:
如果我通过直接将

Transform
分配给实体的
transform
属性来放置实体,即没有动画,则结果是正确的。
但是我必须使用实体的
move(to:
函数来为其设置动画。而且
move(to:
以意想不到的方式发挥作用。
因此,我根据Apple的visionOS沉浸式应用程序模板(如下)编写了一个小测试应用程序。在那里,治疗以下 5 例病例:

  1. 直接设置

    transform
    (无动画)。这给出了正确的结果,并且按预期工作(没有动画)

  2. 使用

    transform
    相对于世界设置
    move
    (无动画)。这给出了正确的结果,尽管它没有按预期工作。我期望“相对于世界”意味着平移和旋转是相对于世界的。这对于平移来说似乎是错误的,对于旋转来说是正确的。

  3. 使用

    transform
    相对于
    move
    设置
    parentEntity
    (无动画)。尽管
    translation
    rotation
    是相对于
    parentEntity
    定义的,但这会给出错误的结果。

  4. 使用

    transform
    相对于动画世界设置
    move
    。这也会给出错误的结果,并且没有动画。

  5. 使用

    transform
    相对于
    move
    设置
    parentEntity
    ,并带有动画。这也会给出错误的结果,并且没有动画。

以下是案例 1...5 的屏幕截图:

enter image description here
案例 1 和 2

enter image description here
案例3

enter image description here
案例 4 和 5

问题:
所以,显然,我不明白

move(to:
的作用。我很乐意得到任何建议,什么是错的以及如何做正确的。

这是代码:

import SwiftUI
import RealityKit
import RealityKitContent

struct ImmersiveView: View {
    @Environment(AppModel.self) var appModel
    
    let boardHeight: Float = 0.1
    let boxHeight: Float = 0.3

    var body: some View {
        RealityView { content in
            let boardEntity = makeBoard()
            content.add(boardEntity)
            let boxEntity = makeBox(parentEntity: boardEntity)
            boardEntity.addChild(boxEntity)
        }
    }
    
    func makeBoard() -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 1.0, height: boardHeight, depth: 1.0)
        var material = UnlitMaterial(); material.color.tint = .red
        let boardEntity = ModelEntity(mesh: mesh, materials: [material])
        boardEntity.transform.translation = [0, 0, -3]
        return boardEntity
    }
    
    func makeBox(parentEntity: Entity) -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 0.3, height: boxHeight, depth: 0.3)
        var material = UnlitMaterial(); material.color.tint = .green
        let boxEntity = ModelEntity(mesh: mesh, materials: [material])
        
        // Set position and orientation of the box
        
        // To put the box onto the board, move it up by half height of the board and half height of the box
        let y_up = boardHeight/2.0 + boxHeight/2.0
        let translation = SIMD3<Float>(0, y_up, 0)
        // Turn the box by 45 degrees around the y axis
        let rotationY = simd_quatf(angle: Float(45.0 * .pi/180.0), axis: SIMD3(x: 0, y: 1, z: 0))
        let transform = Transform(rotation: rotationY, translation: translation)
        
        // Do the actual move
        
        // 1) Set transform directly (without animation)
        boxEntity.transform = transform // Translation and rotation correct
        
        // 2) Set transform using move relative to world (without animation)
//      boxEntity.move(to: transform, relativeTo: nil) // Translation and rotation correct
        
        // 3) Set transform using move relative to parentEntity (without animation)
//      boxEntity.move(to: transform, relativeTo: parentEntity) // Translation incorrect, rotation correct
        
        // 4) Set transform using move relative to world with animation
//      boxEntity.move(to: transform,
//                     relativeTo: nil,
//                     duration: 1.0,
//                     timingFunction: .linear) // Translation incorrect, rotation incorrect, no animation
        
        // 5) Set transform using move relative to parentEntity with animation
//      boxEntity.move(to: transform,
//                     relativeTo: parentEntity,
//                     duration: 1.0,
//                     timingFunction: .linear) // 5) Translation incorrect, rotation incorrect, no animation

        return boxEntity
    }

}
swift realitykit visionos immersive-space
1个回答
0
投票

这似乎是一个 RealityKit 错误。
我在Apple的开发者论坛上发布了这个问题,Vision Pro工程师回答并找到了解决方法(缩写):

这可能是一个错误,但我们的团队需要进一步调查。 请考虑使用反馈助手提交错误。

我这样做了(FB15152333)。

解决方法如下:

import SwiftUI
import RealityKit
import RealityKitContent

struct ImmersiveView: View {
    @Environment(AppModel.self) var appModel
    
    let boardHeight: Float = 0.1
    let boxHeight: Float = 0.3
    
    var body: some View {
        RealityView { content in
            let boardEntity = makeBoard()
            content.add(boardEntity)
            let mesh = MeshResource.generateBox(width: 0.3, height: boxHeight, depth: 0.3)
            var material = UnlitMaterial(); material.color.tint = .green
            let boxEntity = ModelEntity(mesh: mesh, materials: [material])
            boardEntity.addChild(boxEntity)
            
            Task {
                moveBox(boxEntity, parentEntity: boardEntity)
            }
        }
    }
    
    func makeBoard() -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 1.0, height: boardHeight, depth: 1.0)
        var material = UnlitMaterial(); material.color.tint = .red
        let boardEntity = ModelEntity(mesh: mesh, materials: [material])
        boardEntity.transform.translation = [0, 0, -3]
        return boardEntity
    }
    
    func moveBox(_ boxEntity:Entity, parentEntity: Entity)  {
        // Set position and orientation of the box
        
        // To put the box onto the board, move it up by half height of the board and half height of the box
        let y_up = boardHeight/2.0 + boxHeight/2.0
        let translation = SIMD3<Float>(0, y_up, 0)
        // Turn the box by 45 degrees around the y axis
        let rotationY = simd_quatf(angle: Float(45.0 * .pi/180.0), axis: SIMD3(x: 0, y: 1, z: 0))
        let transform = Transform(rotation: rotationY, translation: translation)
        
        // Do the actual move
        
        // 5) Set transform using move relative to parentEntity with animation
        boxEntity.move(to: transform,
                       relativeTo: parentEntity,
                       duration: 1.0,
                       timingFunction: .linear) // 5) Translation incorrect, rotation incorrect, no animation
    }
    
}
© www.soinside.com 2019 - 2024. All rights reserved.