如何在 RealityKit 中为变换设置动画

Rob*_*est 2 xcode animation augmented-reality swift realitykit

在我之前的问题中,我已经找到了如何仅在对象上的一个轴上进行旋转变换,现在我希望将其设置为动画。

有没有办法在 RealityKit 中做到这一点?

ARG*_*Geo 15

1. 变换动画

\n

您可以使用实例方法在 RealityKit 中移动、旋转和缩放模型.move(...)。为了更快地编译,我使用了 SwiftUI macOS 应用程序 \xe2\x80\x93,不过,您也可以在 iOS 应用程序中使用此代码。

\n
import SwiftUI\nimport RealityKit\n\nstruct ContentView: View {\n    var body: some View {\n        ARInterface().ignoresSafeArea()\n    }\n}\n\nstruct ARInterface: NSViewRepresentable {\n\n    let arView = ARView(frame: .zero)\n    \n    func makeNSView(context: Context) -> ARView {\n        \n        let scene = try! Experience.loadBox()\n        scene.steelBox?.scale = [10, 10, 10]\n\n        let transform = Transform(pitch: 0, yaw: 0, roll: .pi)\n        scene.steelBox?.orientation = transform.rotation\n\n        arView.scene.anchors.append(scene)\n            \n        scene.steelBox?.move(to: transform,\n                     relativeTo: scene.steelBox,\n                       duration: 5.0,\n                 timingFunction: .linear)\n        \n        return arView\n    }\n    \n    func updateNSView(_ uiView: ARView, context: Context) { }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

阅读这篇文章,了解如何克服180 度旋转障碍

\n

在此输入图像描述

\n


\n

FromToByAnimation<Value>2.使用struct进行永恒轮转

\n

如果您使用该值,此结构会提醒您 SceneKit 的repeatForever(_:)方法(但更高级的版本).cumulativeFromToByAnimation结构可用于 iOS、visionOS 和 macOS 项目。

\n
struct ARViewContainer : UIViewRepresentable {\n    let arView = ARView(frame: .zero)\n    let cube = ModelEntity(mesh: .generateBox(size: 1))\n    \n    func eternalRotation() {\n        let from = Transform(rotation: .init(angle: .pi/2, axis: [0, 0, 1]))\n\n        let definition = FromToByAnimation(from: from, \n                                       duration: 1, \n                                         timing: .linear, \n                                     bindTarget: .transform, \n                                     repeatMode: .cumulative)\n\n        if let animate = try? AnimationResource.generate(with: definition) {\n            cube.playAnimation(animate)\n        }\n    }\n    \n    func makeUIView(context: Context) -> ARView {\n        let anchor = AnchorEntity()\n        anchor.position.z = -2\n        anchor.addChild(cube)\n        arView.scene.anchors.append(anchor)\n        \n        self.eternalRotation()\n        return arView\n    }\n    func updateUIView(_ view: ARView, context: Context) { }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


\n

3. 使用矩阵变换动画

\n

对于那些喜欢使用矩阵数学的人,我建议阅读这篇文章:

\n

更改 RealityKit 中 AnchorEntity 的旋转

\n


\n

4. 使用物理变换动画

\n

对于那些喜欢使用动态的人,我给出了这篇文章的链接:

\n

如何移动模型并同时生成其碰撞形状?

\n


\n

5.资产动画

\n

要播放在 3D 应用程序(如 Maya 或 Houdini)中制作的资产动画(无论是骨骼角色动画还是一组变换动画,包括围绕网格枢轴点的旋转),请使用animationPlaybackController

\n
import Cocoa\nimport RealityKit\n\nclass ViewController: NSViewController {\n    \n    @IBOutlet var arView: ARView!\n    \n    override func awakeFromNib() {\n\n        do {\n            let robot = try ModelEntity.load(named: "drummer")\n\n            let anchor = AnchorEntity(world: [0, -0.7, 0])\n\n            anchor.transform.rotation = simd_quatf(angle: .pi/4, \n                                                    axis: [0, 1, 0])\n            arView.scene.anchors.append(anchor)\n            \n            robot.scale = [1, 1, 1] * 0.1\n\n            anchor.children.append(robot)\n            \n            robot.playAnimation(robot.availableAnimations[0].repeat(), \n                                transitionDuration: 0.5, \n                                      startsPaused: false)\n        } catch {\n            fatalError("Cannot load USDZ asset.")\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

为了能够播放多个动画,请尝试此技术此技术

\n

在此输入图像描述

\n


\n

6. 在 Reality Composer 中变换动画

\n

对于那些喜欢 UI 的人来说,Reality Composer 中有一个“永久”旋转行为:

\n

Reality Composer - 如何永久旋转对象?

\n


\n

7. 使用 USDZ 的 Python 绑定转换动画

\n

USDZ 模式在 Pixar 格式的日常 Python 脚本中变得越来越流行。

\n

增强现实 911 \xe2\x80\x94 USDZ 模式

\n
import SwiftUI\nimport RealityKit\n\nstruct ContentView: View {\n    var body: some View {\n        ARInterface().ignoresSafeArea()\n    }\n}\n\nstruct ARInterface: NSViewRepresentable {\n\n    let arView = ARView(frame: .zero)\n    \n    func makeNSView(context: Context) -> ARView {\n        \n        let scene = try! Experience.loadBox()\n        scene.steelBox?.scale = [10, 10, 10]\n\n        let transform = Transform(pitch: 0, yaw: 0, roll: .pi)\n        scene.steelBox?.orientation = transform.rotation\n\n        arView.scene.anchors.append(scene)\n            \n        scene.steelBox?.move(to: transform,\n                     relativeTo: scene.steelBox,\n                       duration: 5.0,\n                 timingFunction: .linear)\n        \n        return arView\n    }\n    \n    func updateNSView(_ uiView: ARView, context: Context) { }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


\n

8. 使用三角法进行永恒轨道运行

\n

三角函数sin()cos()计时器和计数器对象将允许您围绕任何轴旋转模型。

\n

将实体悬停在 ARCamera 前面

\n


\n

9. 轨道动画

\n

使用OrbitAnimationstruct 可以使实体围绕其原点旋转。这是visionOS 应用程序的代码片段。

\n
import SwiftUI\nimport RealityKit\n\nstruct ContentView: View {\n    var body: some View {\n        RealityView { content in\n            async let car = ModelEntity(named: "car.usdz")\n            \n            let entity = Entity()\n            entity.position.y = 0.1\n            \n            if let car = try? await car {\n                car.scale /= 5\n                entity.addChild(car)\n                \n                let orbit = OrbitAnimation(duration: 5.0,\n                                               axis: [1,0,0],\n                                     startTransform: entity.transform,\n                                         bindTarget: .transform,\n                                         repeatMode: .repeat)\n                \n                if let animation = try? AnimationResource.generate(with: orbit) {\n                    entity.playAnimation(animation)\n                }\n                content.add(entity)\n            }\n        }\n    }\n}\n#Preview {\n    ContentView()\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

  • 你好@Andy,你能回答这个问题吗:/sf/ask/4962352881/:你是一个很大的帮助为社区。 (2认同)

Rob*_*est 6

旋转动画:

复制框的当前变换

var rotationTransform = boxAnchor.steelBox?.transform
Run Code Online (Sandbox Code Playgroud)

将框设置为在 z 轴上旋转 90 度

rotationTransform?.rotation = simd_quatf(angle: .pi/2, axis: [0,0,1])
Run Code Online (Sandbox Code Playgroud)

在 10 秒内将框移动到新的变换

boxAnchor.steelBox?.move(to: rotationTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)
Run Code Online (Sandbox Code Playgroud)

动画翻译:

var translationTransform = boxAnchor.steelBox?.transform

translationTransform?.translation = SIMD3<Float>(x: 5, y: 0, z: 0)

boxAnchor.steelBox?.move(to: translationTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)
Run Code Online (Sandbox Code Playgroud)

用动画缩放:

var scaleTransform = boxAnchor.steelBox?.transform

scaleTransform?.scale = SIMD3<Float>(x: 1, y: 1, z: 1)

boxAnchor.steelBox?.move(to: scaleTransform!, relativeTo: boxAnchor.steelBox?.parent, duration: 10, timingFunction: .easeInOut)
Run Code Online (Sandbox Code Playgroud)