GLTFUtility
GLTFUtility copied to clipboard
Animations don't work at runtime
Hello, I tried to import .glb character with animation, but it doesnt seem to work. It plays fine when I load it at runtime in the editor. But when I build it, the character is not animated. I tried it on Android, iOS and MacOS and neither of these worked. Only in the editor. Do you have a clue, what could I do wrong?
Thanks in advance for your response.
Here's the code I use:
// Create new mesh.
AnimationClip[] animationClips;
GameObject result = Importer.LoadFromFile(itemFileInfo.FullName, new ImportSettings(), out animationClips);
// Setup animation, if there is any.
if (animationClips.Length > 0)
{
Animator animatorComponent = result.gameObject.AddComponent<Animator>();
AnimatorOverrideController gltfAnimatorOverride = new AnimatorOverrideController(gltfAnimator);
for (int i = 0; i < animationClips.Length; ++i)
{
gltfAnimatorOverride["test"] = animationClips[i];
}
animatorComponent.runtimeAnimatorController = gltfAnimatorOverride;
}
I'm also attaching the .glb file: mixamo.glb.zip
I've tried to use legacy "Animation" instead of "Animator" and that works. So I can use that as a temporary workaround.
@Legacycz Is this the correct way to create an animation component play an animation clip with Unity at runtime? I've never done it before so I'm unsure. I'm also, looking for the correct way to import animations. Here is my current method that works in the editor only, it just plays the first clip in the list of clips using the Playables API.
private void OnGLTFImportComplete(GameObject result, AnimationClip[] clips) {
if (clips != null) {
if (clips.Length > 0) {
PlayableGraph playable = new PlayableGraph();
var animator = result.AddComponent<Animator>();
AnimationPlayableUtilities.PlayClip(animator, clips[0], out playable);
}
}
}
@Legacycz Is this the correct way to create an animation component play an animation clip with Unity at runtime? I've never done it before so I'm unsure. I'm also, looking for the correct way to import animations. Here is my current method that works, it just plays the first clip in the list of clips using the Playables API.
private void OnGLTFImportComplete(GameObject result, AnimationClip[] clips) { if (clips != null) { if (clips.Length > 0) { PlayableGraph playable = new PlayableGraph(); var animator = result.AddComponent<Animator>(); AnimationPlayableUtilities.PlayClip(animator, clips[0], out playable); } } }
I din't try to use Playables with GLTF loader, so I can't confirm if it's correct or not :). Although if it works at least with the first clip, I would say it's at least on the right way. You can try to find and replace animation clips by name, if it's possible. Or if there is a way to put the animation clip at runtime to the playable graph, then try that?
I'm thinking as a default a PlayableGraph will just play each animation clip and then loop back to the beginning. I'm not sure how I can handle anything more complex at the moment without writing something custom each time.
https://gist.github.com/polytropoi/91c1625826783a3ad283bccf6ffccf30 here's a gist with gltf loading at runtime using GLTFUtility and animating using Animancer, seems to work fine. I'm not familiar with Playables API, but I need to wire up all that mechanim stuff at runtime, and Animancer looks promising: https://kybernetik.com.au/animancer/
The Playables API doesn't support legacy animation clips and GLTFUtility was failing to import non legacy clips at runtime, Unity was throwing this error: "Can't use AnimationClip::SetCurve at Runtime on non Legacy AnimationClips".
So now I'm using the the legacy Animation system, tested and working on iOS.
private void OnGLTFImportComplete(GameObject result, AnimationClip[] clips) {
if (clips != null)
{
if (clips.Length > 0)
{
Animation animation = result.AddComponent<Animation>();
animation.AddClip(clips[0], clips[0].name);
animation.clip = animation.GetClip(clips[0].name);
animation.Play();
animation.wrapMode = WrapMode.Loop;
}
}
}
Had the same issue on Android. I was getting error. "can't use animatioclip set curve at runtime on non legacy animation clips"
Solved it by setting useLegacyClips to true on importSettings.
AnimationClip[] animClips;
var i = new ImportSettings();
i.useLegacyClips = true;
GameObject result = Importer.LoadFromFile(fileSavePath, i, out animClips);
GameObject _wrapper = Instantiate(WrapperPrefab, pos, rot);
if (animClips.Length > 0)
{
Animation anim = result.AddComponent<Animation>();
animClips[0].legacy = true;
anim.AddClip(animClips[0], animClips[0].name);
anim.clip = anim.GetClip(animClips[0].name);
anim.wrapMode = WrapMode.Loop;
anim.Play();
}
Its still not solved for me and I tried nearly every solution here. I was using legacy animation and tried also the animator, I was setting the animation in importer of " GLTFAnimations.cs " as result.clip.legacy = true; , I tried also the animancer asset in Unity but...unfortunately: The Animation is still not playing on an Android device. Any other idea here how to achieve this?
Its still not solved for me and I tried nearly every solution here. I was using legacy animation and tried also the animator, I was setting the animation in importer of " GLTFAnimations.cs " as result.clip.legacy = true; , I tried also the animancer asset in Unity but...unfortunately: The Animation is still not playing on an Android device. Any other idea here how to achieve this?
Did you find a solution? I also try to use animation and it doesn't work.