• RuntimesUnity
  • Event Not Firing on Starting Animation

I have an event on my Starting Animation that does not fire when our Spine prefab is instantiated via code, but does fire later, from a different animation. Curiously, the Starting Animation event fires when the prefab is dragged into the scene during Play Mode, so I believe the hookup is correct.

One thought is that our Spine prefab is an Addressable being instantiated with InstantiateAsync. Maybe there's a weird interaction there, like Spine's playing the animation before our code can subscribe to the event or something. That would explain why the event doesn't work at first, but does later, and also works with a non-async instantiation like drag and drop.

Anyway, any insight or advice would be great, thanks!

  • Harald ha risposto a questo messaggio
    Related Discussions
    ...

    It seems like the issue you're experiencing might be related to the timing of when the event subscription occurs relative to when the animation starts playing. When using InstantiateAsync, it's possible that the animation begins before your code has a chance to subscribe to the event, which would explain why the event doesn't fire initially but does later on. To address this, you can ensure that the event subscription happens before the animation starts. You might want to check if the SkeletonAnimation component is fully initialized and the event is subscribed before setting the animation. You can also try delaying the start of the animation until after the event subscription is confirmed.

    Additionally, you can set breakpoints or use logging to verify the order of operations and ensure that the event subscription is happening as expected. This approach can help you identify if the animation is indeed starting before the event handler is attached.

    calvin-tl One thought is that our Spine prefab is an Addressable being instantiated with InstantiateAsync. Maybe there's a weird interaction there, like Spine's playing the animation before our code can subscribe to the event or something.

    How are you subscribing to the event? In general your timing of registering to the event is likely off. Without seeing any of your code it's hard to help, but as Spinebot mentioned above, you might want to set the animation and register to the event from the same source to ensure the order is correct. Also see the documentation here:
    https://esotericsoftware.com/spine-unity-main-components#Script-Execution-Order

    calvin-tl Curiously, the Starting Animation event fires when the prefab is dragged into the scene during Play Mode, so I believe the hookup is correct.

    Drag and drop instantiation uses a different codepath and timing since it's editor code, let alone when compared to async calls. Your hookup code is using the right calls, but likely registeres at the wrong time (too late).

    7 giorni dopo

    Ah dang, somehow failed to mention that we are subscribing to the event in the Start method of an attached script:
    skeletonGraphic.AnimationState.Event += OnEvent;

    And this is how we instantiate the prefab the Skeleton Graphic is a part of:
    Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(parent, instantiateInWorldSpace), GameObjectReady);
    followed by:
    var result = op.WaitForCompletion();
    which I believe means we're waiting for it to be fully loaded and instantiated before continuing (not as familiar with this part).

    We aren't actually setting the animation in code, either. We're just:

    1. setting the Starting Animation on the Skeleton Graphic component within our prefab
    2. subscribing to events in Start
    3. instantiating the prefab using Addressables (as illustrated)
    4. waiting for the event to come through

    Thanks for your help!

    @calvin-tl Thanks for the additional info. SkeletonGraphic.Start() calls Initialize() which when a starting animation is set, calls AnimationState.SetAnimation(), raising the Start callback. However, accessing SkeletonGraphic.AnimationState before SkeletonGraphic.Start() implicitly calls Initialize(false) as well, to ensure that everything has been initialized accordingly. So I'm afraid there is no easy solution to receive a start callback from the startingAnimation field, which is mainly intended as an easy beginner interface.

    So a solution would be to once call the callback-target method yourself from your script's Start method which would otherwise be called via the callback delegate, if you need to use the startingAnimation field. Another solution would be to not set SkeletonGraphic.startingAnimation but instead leave it at none and set the animation via SkeletonGraphic.AnimationState.SetAnimation() yourself.

    Ah, some additional confusion.

    We aren't using the Start callback on AnimationState. We're just using Unity's Start method on a separate SpinePlayer script like this:

    public class SpinePlayer
    {
    private void Start()
    {
    skeletonGraphic.AnimationState.Event += OnEvent;
    }
    }

    Subscribing to this event from within Start does work for the selected Starting Animation, just not when we first instantiate our prefabs as described above.

    The solution was just to subscribe within Awake. For whatever reason Start was too late. Maybe because of the InstantiateAsync + op.WaitForCompletion().

    Anyway, thanks for your time! 🙂

    Glad to hear you've figured it out, thanks for getting back to us.