众所周知,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 中的动画组件:
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
}