• Unity
  • How to set first frame before animation starting in Unity?

  • Изменено
Related Discussions
...

Hi, I have a SkeletonGraphic GameObject used in Unity. It's inactive after the scene is loaded. When I set it active and call state.SetAnimation manually, the GameObject will firstly display static pose, and then play the animation after few fame (may be one fame).
I want the SkeletonGraphic GameObject display the animation right after I call state.SetAnimation without showing the static pose.

Could someone help me how to do it?

Fish написал

When I set it active and call state.SetAnimation manually, the GameObject will firstly display static pose, and then play the animation after few fame (may be one fame).

Please note that you can use the Pause and Next Frame buttons in Unity to know exactly what happens every frame.

From the code above I would guess that your problem is a single frame and is based on execution order. The coroutine will be called after Skeleton.Update(), which is just one frame too late with the SetAnimation call.

So possible solutions would be:

  • a) call
    skeletonAnimation.Update(0);
        // and optionally also skeletonAnimation.LateUpdate(); if it's not updating in the same frame
    after your SetAnimation() calls.
  • b.) move the code from the coroutine to somewhere else, e.g. to Update() or even OnEnable() and ensure the script is called before SkeletonAnimation and SkeletonRenderer.

Maybe I don't describe my problem clearly. I have reorder by code to make things clearly:

  1. I Instantiate a SkeletonGraphic Prefab, whose Starting Animation property is set to one Animation name.
  2. The Unity will firstly display the setup pose of the SpineAnimation, then begin the animation in the next frame.

It's very confusing for me. Because I make an "Appear" Animation and want to play this animation as soon as the GameObject is Instantiated. But It sometimes will show the Setup Pose after Instantiation and then show the Animation's first pose in the next frame.

This is my Code:

GameObject clickEffectPre = Resources.Load<GameObject>("Prefabs/ClickEffect");
GameObject clickEffectGo = Instantiate(clickEffectPre, transform);
clickEffectGo.GetComponent<SkeletonGraphic>().LateUpdate();

My English is not very good. If there's anything I don't describe clearly, I will explain as soon so possible.
Thanks!


I have recorded a video and put it on our server:
http://file.gongfubb.com/wksz/ydsz/books/test/click_effect.mp4

When I click the image, a SkeletonGraphic GameObject is Instantiated. But the Setup pose (a circle) is shown in the first frame, and the Animation begin to play from the next frame (two circle scale up gradually).

No need to apologize for your English, thank you for the video and the description!

Regarding using instantiation at cursor-click:
In general it is not considered good practice in Unity (or also in general) to instantiate and destroy objects frequently, when they can be reused. For such frequent use cases as the cursor click animation shown above, it would be much more advisable to have a pool of objects that are reused, otherwise you create a lot of unnecessary overhead, such as skeleton loading time and garbage collection.

Regarding the actual question:
Have you tried adding the line

skeletonAnimation.Update(0);

after your Instantiate code as I have described in the previous post?

e.g. like this:

GameObject clickEffectPre = Resources.Load<GameObject>("Prefabs/ClickEffect");
GameObject clickEffectGo = Instantiate(clickEffectPre, transform);
var skeletonGraphic = clickEffectGo.GetComponent<SkeletonGraphic>();
skeletonGraphic.Update(0); // add this line here before your existing LateUpdate() call
skeletonGraphic.LateUpdate();

Hi Harald,
It works! Thanks so much!

Great to hear, thanks for getting back to us!