Unity Autodesk.Fbx,如何在运行时从fbx文件中提取动画?

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

众所周知,fbx 文件可以包含动画。如何在运行时统一获取fbx文件的动画?

我使用这个脚本来打印fbx每个节点的位置、旋转和缩放。如何获取 fbx 在动画中任意时间点的位置、旋转和缩放?

using Autodesk.Fbx;
using UnityEngine;
 
public class DisplayingAnimation : MonoBehaviour
{
    public string fbxPath;
 
    private FbxScene scene;
 
    private void Awake()
    {
        ImportFBX();
    }
 
    private void ImportFBX()
    {
        FbxManager manager = FbxManager.Create();
        FbxIOSettings ioSettings = FbxIOSettings.Create(manager, Globals.IOSROOT);
        manager.SetIOSettings(ioSettings);
 
        FbxImporter importer = FbxImporter.Create(manager, "Importer");
 
        if (importer.Initialize(fbxPath, -1, manager.GetIOSettings()))
        {
            scene = FbxScene.Create(manager, "Scene");
            importer.Import(scene);
 
            FbxNode rootNode = scene.GetRootNode();
            if (rootNode != null)
            {
                ProcessNode(rootNode);
            }
        }
 
        importer.Destroy();
        ioSettings.Destroy();
        manager.Destroy();
    }
 
    private void ProcessNode(FbxNode node)
    {
        int childCount = node.GetChildCount();
        for (int i = 0; i < childCount; i++)
        {
            FbxNode childNode = node.GetChild(i);
            PrintCoordinates(childNode);
            ProcessNode(childNode);
        }
    }
 
    private void PrintCoordinates(FbxNode node)
    {
        Vector3 translation = new Vector3((float)globalTransform.GetT().X, (float)globalTransform.GetT().Y, (float)globalTransform.GetT().Z);
        Quaternion rotation = new Quaternion((float)globalTransform.GetQ().X, (float)globalTransform.GetQ().Y, (float)globalTransform.GetQ().Z, (float)globalTransform.GetQ().W);
        Vector3 scale = new Vector3((float)globalTransform.GetS().X, (float)globalTransform.GetS().Y, (float)globalTransform.GetS().Z);
 
        Debug.Log($"Coordinates of {node.GetName()}: Translation = {translation}, Rotation = {rotation}, Scale = {scale}: parent {node.GetParent().GetName()}");
    }
}
unity-game-engine autodesk fbx
1个回答
0
投票

您需要使用 Unity 中的动画组件:

using Autodesk.Fbx;
    using UnityEngine;
    
    public class DisplayingAnimation : MonoBehaviour
    {
        public string fbxPath;
    
        private FbxScene scene;
    
        private void Awake()
        {
            ImportFBX();
        }
    
        private void ImportFBX()
        {
            FbxManager manager = FbxManager.Create();
            FbxIOSettings ioSettings = FbxIOSettings.Create(manager, Globals.IOSROOT);
            manager.SetIOSettings(ioSettings);
    
            FbxImporter importer = FbxImporter.Create(manager, "Importer");
    
            if (importer.Initialize(fbxPath, -1, manager.GetIOSettings()))
            {
                scene = FbxScene.Create(manager, "Scene");
                importer.Import(scene);
    
                FbxNode rootNode = scene.GetRootNode();
                if (rootNode != null)
                {
                    // Assume you have an animation stack at index 0 (change this if you have multiple animations)
                    FbxAnimStack animStack = scene.GetSrcObject<FbxAnimStack>(0);
                    if (animStack != null)
                    {
                        // Get the start and end time of the animation
                        FbxTimeSpan animTimeSpan = animStack.GetLocalTimeSpan();
                        FbxTime startTime = animTimeSpan.GetStart();
                        FbxTime endTime = animTimeSpan.GetStop();
    
                        // Set the time step for sampling the animation
                        FbxTime timeStep = FbxTime.FromSecondDouble(1.0 / 30.0); // 30 FPS, adjust as needed
    
                        // Loop through the animation time range and sample the transformations
                        for (FbxTime currentTime = startTime; currentTime <= endTime; currentTime += timeStep)
                        {
                            scene.GetEvaluator().SetContext(scene);
    
                            // Sample the transformations at the current time
                            ProcessNode(rootNode, currentTime);
                        }
                    }
                }
            }
    
            importer.Destroy();
            ioSettings.Destroy();
            manager.Destroy();
        }
    
        private void ProcessNode(FbxNode node, FbxTime time)
        {
            FbxAMatrix globalTransform = node.EvaluateGlobalTransform(time);
            // ... Continue with the rest of your code
            // You can access the globalTransform to get the position, rotation, and scale at the current time.
            // Remember to convert the FbxAMatrix to Unity's Vector3 and Quaternion for position and rotation.
        }
    
        // Rest of your code remains the same
    }
© www.soinside.com 2019 - 2024. All rights reserved.