Fish

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
  • Posts: 14

Harald

Fish wrote: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.
User avatar
Harald

Harri
  • Posts: 4328

Fish

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).
Fish
  • Posts: 14

Harald

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();
User avatar
Harald

Harri
  • Posts: 4328

Fish

Hi Harald,
It works! Thanks so much!
Fish
  • Posts: 14

Harald

Great to hear, thanks for getting back to us!
User avatar
Harald

Harri
  • Posts: 4328


Return to Unity