I am translating my SceneKit app to RealityKit. In SceneKit I can run multiple actions concurrently or in sequence (e.g. running both translateTo and scaleTo together). I am wondering how I can do so in RealityKit. I have the following:
let translateAction = FromToByAction<Transform>(
from: Transform(translation: [0.0, 2.0, 0.0]),
to: Transform(translation: [0.0, -2.0, 0.0]),
mode: .parent,
timing: .linear,
isAdditive: true)
let translateAnimation = try! AnimationResource
.makeActionAnimation(
for: translateAction,
duration: 5.0,
bindTarget: .transform)
box.playAnimation(translateAnimation)
let scaleAction = FromToByAction(
from: Transform(scale: SIMD3(0.5, 0.5, 0.5)),
to: Transform(scale: SIMD3(2.5, 2.5, 2.5)),
mode: .local,
timing: .linear,
isAdditive: true)
let scaleAnimation = try! AnimationResource
.makeActionAnimation(
for: scaleAction,
duration: 10,
bindTarget: .transform)
box.playAnimation(scaleAnimation)
However, it only runs the scaleAnimation, not the translationAnimation. Probably because they both bind to .transform target, so the 2nd one overwrites the 1st one. I am wondering how to solve this problem.
The good news is that you can use the .group(with:) type method to simultaneously play multiple primitive's transform animations. The bad news is that in RealityKit's actual version doesn't currently work a simultaneous playback of multiple skeletal animations.
import SwiftUI
import RealityKit
struct ContentView : View {
let box = ModelEntity(mesh: .generateBox(size: 0.25))
var body: some View {
RealityView { rvc in
let translateAction = FromToByAction<Transform>(
from: .init(translation: [0.0, 1.0, 0.0]),
to: .init(translation: [0.0,-1.0, 0.0]),
mode: .local,
timing: .easeInOut,
isAdditive: true
)
let translate = try! AnimationResource.makeActionAnimation(
for: translateAction,
duration: 2.0,
bindTarget: .transform
)
let scaleAction = FromToByAction(
from: .init(scale: .one / 10),
to: .init(scale: .one * 4),
mode: .local,
timing: .easeInOut,
isAdditive: true
)
let scale = try! AnimationResource.makeActionAnimation(
for: scaleAction,
duration: 2.0,
bindTarget: .transform
)
let simultaneously = try! AnimationResource.group(
with: [translate, scale]
)
box.playAnimation(simultaneously)
rvc.add(box)
}
.ignoresSafeArea()
.background(.black)
}
}