4

I spent 2 days trying to understand how to play properly an animation in my RealityKit project.

I followed many tips from others stackoverflow topics but without success. I know that with RealityKit v2 we can only play the first animation from the usdz file, ok. I'm trying to play the first animation of the "toy_robot_vintage.usdz" delivered by Apple directly in the Reality Composer.

Here is my complete code :

func loadModel(named: String, result: ARRaycastResult) {
        
        var usdzToLoad: String = ""
        
        switch named {
        case "ROBOT":
            usdzToLoad = "toy_robot_vintage.usdz"
        default:
            break;
        }
        
        DispatchQueue.main.async {
            let modelToLoad = try! ModelEntity.loadModel(named: usdzToLoad)
            
            switch named {
            case "ROBOT":
                modelToLoad.name = "ROBOT"
            default:
                break;
            }
            
            let anchor = AnchorEntity(plane: .horizontal, classification: .any, minimumBounds: [0.1, 0.1])
                anchor.position.y = 0.01
                anchor.addChild(modelToLoad)
            
            // Create a "Physics" model of the toy in order to add physics mode
            guard let modelEntity = anchor.children.first as? (Entity & HasPhysics)
            else { return }

            self.arView.installGestures([.rotation], for: modelEntity)
            
            modelEntity.generateCollisionShapes(recursive: true)
            modelEntity.physicsBody = PhysicsBodyComponent(shapes: [.generateBox(size: .one)],
                                                           mass: 1.0,
                                                           material: .default,
                                                           mode: .kinematic)

            self.currentEntity = modelEntity
            self.anchorsEntities.append(anchor)
            
            self.arView.scene.addAnchor(anchor)
            
//            self.currentEntity!.availableAnimations.forEach { self.currentEntity!.playAnimation($0.repeat()) }
            
            let robotAnimationResource = self.currentEntity?.availableAnimations.first
            
            self.currentEntity!.playAnimation(robotAnimationResource!.repeat(duration: .infinity),
                                             transitionDuration: 1.25,
                                                   startsPaused: false)
        }

robotAnimationResource is always nil returning of course a fatal error when I try to play the animation.

Any idea ? Thanks in advance for your help and support.

Silvering
  • 756
  • 1
  • 6
  • 33

1 Answers1

6

Change ModelEntity.loadModel to ModelEntity.load and it should now have the animations.
It's very weird and I don't know why, but that has worked for me in the past.

Also HasPhysics inherits Entity, so to save yourself looking for the anchor's children etc, you should be able to replace that guard let modelEntity... line with this:

guard let modelEntity = modelToLoad as? HasPhysics else { return }

EDIT:

I just ran this in playground and the animation runs fine:

import PlaygroundSupport
import UIKit
import RealityKit

let arview = ARView(frame: .zero, cameraMode: .nonAR, automaticallyConfigureSession: true)
arview.environment.lighting.intensityExponent = 3
let newAnchor = AnchorEntity(world: .zero)
let newEnt = try! Entity.load(named: "toy_robot_vintage")
newAnchor.addChild(newEnt)
arview.scene.addAnchor(newAnchor)
for anim in newEnt.availableAnimations {
    newEnt.playAnimation(anim.repeat(duration: .infinity), transitionDuration: 1.25, startsPaused: false)
}

PlaygroundSupport.PlaygroundPage.current.liveView = arview

enter image description here

The issue is that a model imported this way does not conform to HasPhysics (useful if you mentioned that's where it was now failing for you).

Apply the ModelComponent to another entity class or ModelEntity instead.

maxxfrazer
  • 1,173
  • 6
  • 15
  • Hi @maxxfrazer thanks for your reply. I edited my code : https://gist.github.com/MickaelCruzDB/19a63e72915f5848df734fe90acc69fa With the load function instead of loadModel I can not see the loaded usdz. I mean the model doesn't appear in the ar scene... – Silvering Jan 06 '21 at 13:18
  • Looking at my code I see I actually use `Entity.load("filename")`, so Entity instead of ModelEntity, and filename without the extension. See if that works for you – maxxfrazer Jan 06 '21 at 13:52
  • Unfortunately same issue : https://gist.github.com/MickaelCruzDB/010ebd85390799a5b43c048e0e6be0fa :-( – Silvering Jan 06 '21 at 14:16
  • @AndyFedoroff I know you are the RealityKit expert ;-) maybe you have a solution ? Thanks! – Silvering Jan 07 '21 at 05:40