1

I use simple transform and move method to animate my entity. Something like this:

let transform = Transform(scale: .one, 
                       rotation: simd_quatf(angle: .pi, axis: [0,0,1]), 
                      translate: .zero)

myEntity.move(to: transform, relativeTo: myEntity, duration: 1)

All is well, but when I try to rotate any more than 180 degree, the rotation stays still ?

How do I animate something that wants to turn 360 degree?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 2
    as reported [here](https://developer.apple.com/forums/thread/676461) the animation will always take the shortest path to get to the correct transform. so if you set two pi it will cancel out to zero. as a solution you could chain two 180° transforms, the first will get you half way and the second full around – Fault Jul 19 '23 at 17:17

1 Answers1

2

Concatenating transform animations in RealityKit

RealityKit 2023 transform animation is still imperfect today. However, you can sequentially merge several move(to:) methods to go beyond 180 degree rotation barrier. Internally several rotation animations are merged into one smooth animation. I firmly believe that the reason for the 180 degree barrier is some kind of RealityKit's quaternion limitation. This solution works in iOS and visionOS.

visionOS app version for Xcode 15 Simulator.

import SwiftUI
import RealityKit

struct ContentView: View {
        
    var body: some View {
        RealityView { content in
            let model = ModelEntity(mesh: .generateBox(size: 0.1))
            content.add(model)
        } update: { content in
            if let model = content.entities.first {
                
                // 540 degree CCW rotation in 4 seconds (about Z axis)
                model.move(to: .init(roll: .pi), relativeTo: model,
                     duration: 4.0, timingFunction: .linear)
                model.move(to: .init(roll: .pi), relativeTo: model,
                     duration: 4.0, timingFunction: .linear)
                model.move(to: .init(roll: .pi), relativeTo: model,
                     duration: 4.0, timingFunction: .linear)
            }
        }
    }
}
#Preview {
    ContentView()
}

enter image description here

This post is also helpful.


SwiftUI animation for Model3D view

Also, you can prototype a scene in Reality Composer Pro app (do not forget to apply InputTarget and Collision components to 3D model) and then you'll be able to rotate a view with tap gesture using .rotation3DEffect(...) modifier, where you can set a pivot (a.k.a. anchor) point.

import SwiftUI
import RealityKit
import RealityKitContent

struct ContentView: View {
    @State private var rotation: Angle = .zero
    
    var body: some View {
        Model3D(named: "Scene", bundle: realityKitContentBundle)
            .onTapGesture {
                withAnimation(.smooth(duration: 0.5)) {
                    rotation.degrees -= 540
                }
            }
            .rotation3DEffect(rotation, axis: .z, anchor: .center)
    }
}
#Preview {
    ContentView()
}

enter image description here

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 1
    This is incredibly helpful, Andy. Thank you. I am curious though, you open up a scene which likely has both the components added. How does one open a model and add those components in code? IE: `Model3D(named: "skull", bundle: realityKitContentBundle)...` – Zach Jul 28 '23 at 23:29
  • @Zach, please post it as a question. – Andy Jazz Jul 29 '23 at 05:11
  • 1
    Done! https://stackoverflow.com/questions/76796001/how-to-rotate-a-modelentity-in-visionos – Zach Jul 30 '23 at 01:08
  • 1
    Thank you @AndyJazz this is super helpful I was just wondering how to do chain animations on RealityKit and of course you wrote the answer. Apple should pay you royalties. – justCubesAndText Aug 09 '23 at 00:13