Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
616 views
in Technique[技术] by (71.8m points)

swift - Play USDZ animation in RealityKit

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...