question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

GLTF/GLB with multiple Animations Doesn't work

See original GitHub issue

Using GLTFComponent Script to Load GLB from Assets… I tried several files which contain some animations… *File which contained only 1 animation loaded fine. an example file is robot.glb.zip

*Files which contained more animations didn’t loaded. : e.g Bee.glb.zip

I got these Errors:

Errors

Error 1. (IndexOutOfRangeException: Index was outside the bounds of the array.) in Code Below

private static void SetTangentMode(AnimationCurve curve, int keyframeIndex, InterpolationType interpolation)
		{
			var key = curve.keys[keyframeIndex]; // On this line
			switch (interpolation)
			{
				case InterpolationType.CATMULLROMSPLINE:
					key.inTangent = 0;
					key.outTangent = 0;
					break;
				case InterpolationType.LINEAR:
					key.inTangent = GetCurveKeyframeLeftLinearSlope(curve, keyframeIndex);
					key.outTangent = GetCurveKeyframeLeftLinearSlope(curve, keyframeIndex + 1);
					break;
				case InterpolationType.STEP:
					key.inTangent = float.PositiveInfinity;
					key.outTangent = float.PositiveInfinity;
					break;
				default:
					throw new NotImplementedException();
			}
			curve.MoveKey(keyframeIndex, key);			
		}

Error 2: (Unity does not allow you to put two keyframes in with the same time, so this should never occur) In Code Below:

private static float GetCurveKeyframeLeftLinearSlope(AnimationCurve curve, int keyframeIndex)
		{
			if (keyframeIndex <= 0 || keyframeIndex >= curve.keys.Length)
			{
				return 0;
			}
			var valueDelta = curve.keys[keyframeIndex].value - curve.keys[keyframeIndex - 1].value;
			var timeDelta = curve.keys[keyframeIndex].time - curve.keys[keyframeIndex - 1].time;
			Debug.Assert(timeDelta > 0, "Unity does not allow you to put two keyframes in with the same time, so this should never occur.");

			return valueDelta / timeDelta;
		}

Issue Details: So basically the problem is when i try to load the file with more than 1 animations, UnityGLTF cant load it. and it crashes on line “var key = curve.keys[keyframeIndex];” in method named “SetTangentMode()” in script “GLTFSceneImporter.cs.”

I tried to debug, and the error is due to the array “curve.key[]” because the length of this array is being reduced in size after some iterations in loop. i couldn’t figure out why… e.g initially it’s length was 34, but after 8th iteration… the size becomes 33… and after a while 32… i have no clue why… and when the loop tries to access the 33th index… its fails.

you can reproduce the error by using the attached files below.

Bee.glb.zip blue_whale_-_textured.zip wolf.glb.zip

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:3
  • Comments:7

github_iconTop GitHub Comments

2reactions
enaraartetxecommented, Jun 16, 2020

Hi! I came across the same problem a few weeks ago and as I don’t see any other solution this is my approach: As @khizerawan commented “the error is due to the array “curve.key[]” because the length of this array is being reduced in size after some iterations in loop”. That’s because according to Unity documentation “If a keyframe already exists at key.time, then the time of the old keyframe’s position key[index].time will be used instead” https://docs.unity3d.com/ScriptReference/AnimationCurve.MoveKey.html so whenever two keyframes share the same time, it discards one of them and the array shrinks one size. To solve it, I’ve just added a quick check to verify key.inTangent and key.outTangent values are not NaN or Infinite (divided by zero in GetCurveKeyframeLeftLinearSlope) before the curve.MoveKey().

private static void SetTangentMode(AnimationCurve curve, Keyframe[] keyframes, int keyframeIndex, InterpolationType interpolation)
        {
            ...

            if (!float.IsNaN(key.inTangent) && !float.IsNaN(key.outTangent) && !float.IsInfinity(key.inTangent) && !float.IsInfinity(key.outTangent))
                 curve.MoveKey(keyframeIndex, key);
        }

I don’t know if there is a better solution out there but I’ve tested with a couple of models and they work now 😃

2reactions
nodermattcommented, Nov 25, 2019

@HenkHull I would also be interested to hear how you integrated a third-party loader within UnityGLTF.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple object animations not exporting to GLB
I am trying to export multiple objects, each of which is animated separately. Currently both the objects export but only one animation. I...
Read more >
How to play all animations within .glb using typescript
Drag your model into the dropzone and if it contains multiple animations, then it should give you the option to “play all”. If...
Read more >
Animation in GLB export not playing : r/Cinema4D
I have a project I'm trying to export as a GLB and that works all well and good ... Gltf doesn't support animated...
Read more >
Animation of Gltf model exported from blender not working
Hello there, i am trying to animate a gltf model exported from blender using gltf-Blender-Exporter. The animation works in blender and some ...
Read more >
GLTF animation is not working in Three js
I'm struggling to get an animation to play together with my GLTF 3D model. Most similar issues that I've seen on Stack Overflow...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found