在同一装备 USDZ 模型上加载 USDZ 动画

问题描述 投票:0回答:1

我正在尝试使用相同的装备在模型上加载一些 Mixamo 3d 动画。 所有动画同时导出。如果我在创建“modelEntity”时播放动画,则动画可以工作,但是当我尝试更新动画时,会收到此错误:

无法找到任何绑定路径的 BindPoint:“”、“”、“Bboy_Uprock.mixamorig_Hips”、“Bboy_Uprock.mixamorig_Hips.SkeletalPose.SkeletalPoses[0]”

没有想法了。

import SwiftUI
import RealityKit
import ARKit
import Combine
import Foundation

struct ContentView: View {
    @State private var animationTrigger = false
    @StateObject private var arViewModel = ARViewModel()

    var body: some View {
        VStack {
            ARViewContainer(animationTrigger: $animationTrigger, viewModel: arViewModel)
                .edgesIgnoringSafeArea(.all)

            Button("Change Animation") {
                animationTrigger.toggle()
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
        }
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var animationTrigger: Bool
    @ObservedObject var viewModel: ARViewModel 
    @State var mainModelEntity: ModelEntity?
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        setupARView(arView)
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
           if animationTrigger, let mainModelEntity = viewModel.mainModelEntity {
               print("Applying new animation!")
               applyRandomAnimation(to: mainModelEntity, in: uiView)
           }
       }
    
    
    private func setupARView(_ arView: ARView) {
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = [.horizontal, .vertical]
        arView.session.run(config)
        
        let mainModelName = "BboyUprock.usdz"
       
        if let modelEntity = try? ModelEntity.loadModel(named: mainModelName) {
            modelEntity.scale = SIMD3<Float>(0.01, 0.01, 0.01)

            DispatchQueue.main.async {
                self.viewModel.mainModelEntity = modelEntity
            }
            
            if let animation = modelEntity.availableAnimations.first {
                modelEntity.playAnimation(animation.repeat())
                print("Playing first animation")
            } else {
                print("No animations found in the model")
            }
            
            let anchor = AnchorEntity(plane: .horizontal)
            anchor.addChild(modelEntity)
            arView.scene.addAnchor(anchor)
        } else {
            fatalError("Failed to load main model")
        }
    }
    
    
    private func applyRandomAnimation(to entity: ModelEntity, in arView: ARView) {
        
        let animationModelNames = ["BboyUprock.usdz", "HipHopDancing1", "HipHopDancing2", "HipHopDancing3"]
        
        var animations = [AnimationResource]()
        
        for animModelName in animationModelNames {
            if let animationEntity = try? Entity.load(named: animModelName) {
                if let animation = animationEntity.availableAnimations.first {
                    animations.append(animation)
                } else {
                    print("No animations found in \(animModelName)")
                }
            } else {
                print("Failed to load entity from \(animModelName)")
            }
        }
        
        if let randomAnimation = animations.randomElement() {
            print("Attempting to play animation with bind paths:")
                      
            entity.playAnimation(randomAnimation.repeat(duration: .infinity), transitionDuration: 1.25, startsPaused: false)
            
            print("Playing animation from \(animations.count) loaded animations")
        } else {
            print("No animations available to play")
        }
    }
}

class ARViewModel: ObservableObject {
    @Published var mainModelEntity: ModelEntity?
}

xcode animation swiftui arkit usdz
1个回答
0
投票

这可能有助于解决您在更新动画时遇到的绑定错误。

您需要修改ARViewContainer结构体中的setupARView函数。具体来说,您需要加载所有动画以及主模型实体

private func setupARView(_ arView: ARView) {
    let config = ARWorldTrackingConfiguration()
    config.planeDetection = [.horizontal, .vertical]
    arView.session.run(config)

let mainModelName = "BboyUprock.usdz"

if let modelEntity = try? ModelEntity.loadModel(named: mainModelName) {
    modelEntity.scale = SIMD3<Float>(0.01, 0.01, 0.01)

    DispatchQueue.main.async {
        self.viewModel.mainModelEntity = modelEntity
    }
    
    // Load all animations along with the main modelEntity
    var animations = [AnimationResource]()
    for animModelName in animationModelNames {
        if let animation = try? Entity.load(named: animModelName) as? AnimationResource {
            animations.append(animation)
        }
    }
    
    // Apply the first animation if available
    if let animation = animations.first {
        modelEntity.playAnimation(animation.repeat())
        print("Playing first animation")
    } else {
        print("No animations found in the model")
    }
    
    let anchor = AnchorEntity(plane: .horizontal)
    anchor.addChild(modelEntity)
    arView.scene.addAnchor(anchor)
} else {
    fatalError("Failed to load main model")
}

}

© www.soinside.com 2019 - 2024. All rights reserved.