• Unity
  • Rotate bones in the timeline

Is there a way to set the rotation of a bone to be immutable when I view the animation in Editor(Timeline,Spine Animation State Track) ? (via code)

You mean you don't want animations to modify the bone's rotation? You could apply your animations, then set the bone's rotation (every frame).

The code (script) of such an animation cut scene (duration 4 seconds) -

private IEnumerator ExampleAnim()
{
   TrackEntry teK;

   TrackEntry teZ = zombieAnim.state.GetCurrent(0);
   DOVirtual.Float(boneHandRightZ.Rotation, 20, 0.5f, (v) => angleRightHand = v); 
   HitHandRotateBack(teZ);
   yield return new WaitForSeconds(0.05f);
   zombie.DOMoveX(zombie.position.x + 5f, 0.65f);
   cam.DOOrthoSize(12, 0.65f);
   knight.DOMoveX(knight.position.x - 5f, 0.65f);
   zombieAnim.state.SetAnimation(0, hitZ, false);
   yield return new WaitForSeconds(0.1f);

   knightAnim.state.SetAnimation(0, attackK, false);
   knightAnim.timeScale = 1.4f;

   yield return new WaitForSeconds(0.4f);

   Transform flySword = Instantiate(objFlySword, new Vector2(-3.79f, -0.94f), Quaternion.identity, transform);
   flySword.DOMoveX(4.09f, 0.45f);

   slotSword.Attachment = null;
   adrenalinSword.StopParticles();

   yield return new WaitForSeconds(0.15f); 
   zombieAnim.UpdateLocal -= UpdateBonesRightHand;
   cam.DOOrthoSize(5, 0.3f);
   camTra.DOMoveX(4.36f, 0.3f);

   Zombie.In.SetSortOrder(3);
   zombieAnim.state.SetAnimation(0, attackZ, false);
   teZ = zombieAnim.state.GetCurrent(0);
   teZ.MixTime = 1;
   teZ.TimeScale = 0.7f;
   teZ.AnimationStart = 0.36f;
   yield return new WaitForSeconds(0.1f);
   particlesHitRed.Play();

   yield return new WaitForSeconds(0.025f);
   adrenalinSword.PlayFatalityParticles();
   yield return new WaitForSeconds(0.025f);

   knight.position = new Vector3(-0.7f, basePosKnight.y, 0); 
   knight.DOMoveX(2, 0.1f);
   knightAnim.state.SetAnimation(0, runShiledK, false); 
   teK = knightAnim.state.GetCurrent(0);
   teK.MixTime = 1;
   teK.TimeScale = 1.2f;
   Time.timeScale = 0.1f;
   flySword.DORotate(Vector3.forward * -26.6f, 0.1f);
   flySword.DOMoveY(-1.14f, 0.1f);

   yield return new WaitForSeconds(0.075f);
   particlesHitRed.Play();
   particlesHitRed2.Play();
   adrenalinSword.PlayParticles();
   angleArm = 45.4f;
   angleHandL = 15.8f;
   angleSword = -92.6f;
   angleLeftShilder = -177;
   knightAnim.UpdateLocal += UpdateBonesLeftShilder;
   DOVirtual.Float(angleLeftShilder, -94f, 0.025f, (v) => angleLeftShilder = v).SetEase(Ease.Linear);
   DOVirtual.Float(boneBody2K.Rotation, 20, 0.025f, (v) => angleBody2 = v).SetEase(Ease.Linear);
   yield return new WaitForSeconds(0.025f);
   flySword.gameObject.SetActive(false);
   Time.timeScale = 1f;
   teZ.TimeScale = 1f;
   slotSword.Attachment = saveSwordAttachment;
   cam.DOOrthoSize(12, 0.8f);
   slotShadow.Attachment = null;
   knightAnim.state.SetAnimation(0, jumpK, false);
   teK = knightAnim.state.GetCurrent(0);
   teK.AnimationStart = 0.5f; 
   teK.MixTime = 1;
   knightAnim.timeScale = 0f;

   particlesHitRed.transform.localScale = Vector3.one * 4;
   particlesHitRed.transform.position = new Vector2(5.29f, -0.64f);
   angleLeftShilder = -120; 
   yield return new WaitForSeconds(0.025f);
   DOVirtual.Float(angleLeftShilder, -80f, 0.025f, (v) => angleLeftShilder = v).SetEase(Ease.Linear);

   Time.timeScale = 0.05f;
   knight.DOJump(new Vector2(-1.73f, charactersBasicPosY), 9, 1, 1).SetEase(Ease.Linear);
   knight.DORotate(new Vector3(0, 0, 60), 0.2f, DG.Tweening.RotateMode.FastBeyond360).SetEase(Ease.Linear); 
   StartCoroutine(Jump());
   yield return new WaitForSeconds(0.025f);
   knightAnim.UpdateLocal -= UpdateBonesLeftShilder;

   Time.timeScale = 1f;
   yield return new WaitForSeconds(0.1f);

   knightAnim.timeScale = 0;
   knight.DORotate(new Vector3(0, 0, 250), 0.35f, DG.Tweening.RotateMode.FastBeyond360).SetEase(Ease.Linear);
   yield return new WaitForSeconds(0.35f);
   knight.DORotate(new Vector3(0, 0, 360), 0.45f, DG.Tweening.RotateMode.FastBeyond360).SetEase(Ease.Linear);
   boneSwordK.Rotation = 84.77f;
   yield return new WaitForSeconds(0.15f);
   knightAnim.timeScale = 0.8f;
   yield return new WaitForSeconds(0.1f);
   FastMode.In.Off();

   yield return new WaitForSeconds(0.25f);
   slotShadow.Attachment = saveShadowAttachment;
}

private IEnumerator Jump()
{
   zombieAnim.state.SetAnimation(0, dieZ, false);
   zombieAnim.timeScale = 2f;
   zombie.DOJump(new Vector2(zombie.position.x + 2.5f, zombie.position.y + 0.52f), 5, 1, 0.5f);
   zombie.DORotate(-Vector3.forward * 182, 0.3f, DG.Tweening.RotateMode.LocalAxisAdd);
   yield return new WaitForSeconds(0.05f);
   zombieAnim.timeScale = 1f;
}

private void UpdateBonesLeftShilder(ISkeletonAnimation animated)
{
   boneBody2K.Rotation = angleBody2;
   boneShilderLeftK.Rotation = angleLeftShilder;
   boneArmLeftK.Rotation = angleArm;
   boneHandLeftK.Rotation = angleHandL;
   boneSwordK.Rotation = angleSword;
}


private void HitHandRotateBack(TrackEntry teZ)
{
   angleRightHand = boneHandRightZ.Rotation; 
   zombieAnim.UpdateLocal += UpdateBonesRightHand;
}

private void UpdateBonesRightHand(ISkeletonAnimation animated)
{
   boneHandRightZ.Rotation = angleRightHand;
}

The main problem is not the amount of code, the main problem is how I change many values in this script for the more correct animation I need for the cut scene.
To change the value and see how it will look, I do a lot of things -
1) I need to exit the unity play mode.
2) Change the value in the script.
3) Run play mode.
4) Set up the prototype of the game in the desired cut scene.
5) Wait until the cutscene reaches the desired second in which there is a defective visual animation.

In this video, you can move at any second of the cut scene and change the values!
But I don't understand how to do this with your spine+animation+bone rotation(overwrite) . I want to do all this in the timeline in the editor. Is it possible to do this?

OK, that seems like quite a different question. We'll have to wait until tomorrow so Harald can help out. Unity is not my forte, but my guess is you'd need to use Spine with mecanim.

I feel like the answer to this depends on how much of the spine Skeleton you want to be able to "animate" in Timeline. With the Spine Animation State Track you can add and position your already-made spine animation clips, and scrub them, etc, but you can't create a completely new or unique spine animation in Timeline itself. They are two completely separate things.

However, if you only need to control a couple things during the cutscene (like maybe the bone that sets the angle of a weapon, or the angle a character is looking, etc) you could set up a Skeleton Utility Bone that is set to Override (I will call this the "override bone"): spine-unity Runtime Documentation: SkeletonUtilityBone
With an 'override bone' you have the option of overriding the selected bone's position/rotation/etc with the position/rotation/etc of the GameObject that has the 'override bone' component on it. This means that you could then use unity's Animation Track in Timeline, with that 'override bone' gameobject as the target to essentially animate the spine bone.

Thanks very much Jamez0r for answering! There is nothing that I would add to it, the easiest solution would be to use Skeleton Utility Bone with mode set to Override and control this Transform via Timeline.

Regarding Mecanim: There is currently no Timeline support for SkeletonMecanim component (as described here), so keeping to SkeletonAnimation or SkeletonGraphic is recommended when you need to control animations via Timeline.

I installed a free 2D rig from the asset store and it worked.
Spine in Unity can't do that?

Maybe I'm doing it wrong

Your second video is set to private, please change the access privileges accordingly.

Kurtav a écrit

Spine in Unity can't do that?

Jamez0r described above what you need to do, I also briefly repeated that. Did you create the Skeleton Utility Bone hierarchy for your SkeletonAnimation GameObject, change the mode of the target bone to Override and try to animate the Transform of the target bone in Timeline? If so, what problem did you encounter?

Harald a écrit

Your second video is set to private, please change the access privileges accordingly.

Fixed the link. The video is now open.

I've run into this problem before.

Any Spine Animation does not work in the timeline with any bone (override). In the example above (raccoon) - everything works fine(2D Rig Animated). https://assetstore.unity.com/packages/2d/characters/2d-rig-animated-raccoon-42731

Harald a écrit

what problem did you encounter?

This combination does not work in the timeline = Spine Animation State Track(animation reference asset) + Animation Track(transform bone override rotation)
Or am I doing something wrong in the implementation of this combination? any animation + any bone (overwrite transform) in the timeline

Harald a écrit

Did you create the Skeleton Utility Bone for your SkeletonAnimation GameObject, change the mode of the target bone to Override and try to animate the Transform of the target bone in Timeline?

Do you mean in the timeline, in an empty animation, to change the rotation of the bone? no animations? How do I create a cutscene in the timeline this way? It makes no sense. Will I pay money to the artist to make a huge amount of animations with minimal changes in the rotations in the bones? So that I then sequentially transfer them to the timeline? Instead of him drawing new characters, animations, content.

Thanks for updating the video permissions, it helps a lot. Your setup looks mostly correct. Since you are using the Timeline Editor preview outside of Play mode and you have the AnimationState Track below the shoulder Transform rotation Track, it could be that only the Timeline Editor Preview is wrong here, and that it looks correct in-game. Unfortunately the Timeline tracks are applied one after another from top to bottom in the Editor Timeline Preview, which could lead to the animation track to overwrite your shoulder rotation changes on the first track. Could you please check if changing the Track order fixes the preview, or whether it is displayed correctly in Play mode?

Harald a écrit

Could you please check if changing the Track order fixes the preview

bone overwrite first -

bone overwrite second -

Or are you talking about other orders?

Harald a écrit

or whether it is displayed correctly in Play mode?

I know it works in play mode. Timeline is a tool for creating cut scenes in the editor (you can view any frame of the cut scene and change the values in it - you have to do this often, especially in dynamic scenes). Why are you telling me about the Unity play mode? This will not help me create easy and convenient cut scenes.

Is there a more convenient and easier way to create dynamic combat cut scenes from animations and bone rotation overrides? Spine + Unity.
Something more convenient and simpler than my implementation method above (4 second cutscene script + each value change is 5 steps)

Kurtav a écrit

I know it works in play mode. Timeline is a tool for creating cut scenes in the editor (you can view any frame of the cut scene and change the values in it - you have to do this often, especially in dynamic scenes). Why are you telling me about the Unity play mod? This will not help me create easy and convenient cut scenes.

Harald asked you to please check if it works correctly in Play mode to verify that you are only seeing incorrect behavior in the Timeline Editor Preview. This information is useful in debugging the problem you are experiencing.

When Harald is back on Monday he can provide more details about the issue you are having. I know we have had some difficulties getting the Timeline Editor Preview to display as it should. The Unity Timeline API is very poor, probably the worst API that Unity provides. It's a miracle we are able to get it to do as much as it does. Still if it can be fixed, we'll fix it.

Note that you can set the Unity Timeline position back to the start to avoid needing to exit and re-enter Play mode.

Kurtav a écrit

I know it works in play mode.

Thanks for the info. I have uploaded a fix for both the 4.0 and 4.1-beta spine-unity Timeline UPM packages.
Spine Unity Download

The issue has been tracked under this issue ticket:
https://github.com/EsotericSoftware/spine-runtimes/issues/2031

Kurtav a écrit

Why are you telling me about the Unity play mode? This will not help me create easy and convenient cut scenes.

This is not true, you can also enter play mode and still play and scrub the Timeline as you would outside of play mode, and also edit stuff while still in Play mode. This will be more true to the final result in general, as Update calles are missing outside of Play mode (and thus behaving differently).

Harald a écrit

I have uploaded a fix for both the 4.0

Overwriting the rotation of a bone in any animation in the timeline in the editor worked! Thanks a lot! You are best!
:clap: :sun: :heart:

Glad it helped, thanks for your kind words! :nerd: