• RuntimesUnity
  • Intermittent <none> State Flickering During Fast Skin Changes in Unity

Hi everyone,
I'm facing a flickering issue in my Unity project where I'm using Spine SkeletonGraphic to display bot avatars during a matchmaking scrolling animation. The avatars are updated every 0.25s, and each update sets a new skin, refreshes the slots, and starts the "Idle" animation.

The issue is that, during these fast updates, I occasionally see the <none> state for a fraction of a second, which results in a visual "trim" or flicker. I suspect it has to do with SetSlotsToSetupPose() or SetAnimation() not syncing perfectly. Despite adding MixDuration for smooth transitions, the issue persists.

What I Have Tried:

  • Added MixDuration to SetAnimation calls — still flickers.
  • Set MixDuration = 0
  • Ensured SetSlotsToSetupPose() is only called if the skin has actually changed.
    -
  • Played around with Coroutine intervals — no improvement.

Expected Behavior:
Smooth scrolling of different bot avatars without any flickering or <none> state visibility during updates.

private void DisplayBotData(BotData data) {
if (BotAvatarImage != null) BotAvatarImage.sprite = data.Avatar;
if (BotDisplayName != null) BotDisplayName.text = data.DisplayName ?? "Bot";
if (BotLevel != null) BotLevel.text = data.Level.ToString();
if (BotPower != null) BotPower.text = data.Power.ToString();

if (BotSpineGraphic != null && !string.IsNullOrEmpty(data.SkinName)) {
    var skeletonData = BotSpineGraphic.Skeleton.Data;
    if (skeletonData != null) {
        var skinToSet = skeletonData.FindSkin(data.SkinName);
        if (skinToSet != null) {
            BotSpineGraphic.gameObject.SetActive(true);

            // Only set the skin if it is different
            if (BotSpineGraphic.Skeleton.Skin?.Name != data.SkinName) {
                BotSpineGraphic.Skeleton.SetSkin(skinToSet);
                BotSpineGraphic.Skeleton.SetSlotsToSetupPose();
            }

            // Attempted crossfade to avoid flicker
            var trackEntry = BotSpineGraphic.AnimationState.SetAnimation(0, "Idle", true);
            trackEntry.MixDuration = 0.1f;
        } else {
            var fallbackSkin = skeletonData.Skins.Count > 0 ? skeletonData.Skins.Items[3] : null;
            if (fallbackSkin != null) {
                BotSpineGraphic.gameObject.SetActive(true);
                BotSpineGraphic.Skeleton.SetSkin(fallbackSkin);
                BotSpineGraphic.Skeleton.SetSlotsToSetupPose();
                var trackEntry = BotSpineGraphic.AnimationState.SetAnimation(0, "Idle", true);
                trackEntry.MixDuration = 0.1f;
                Debug.LogWarning($"Bot skin '{data.SkinName}' not found. Applying first available skin: {fallbackSkin.Name}");
            } else {
                BotSpineGraphic.gameObject.SetActive(false);
                Debug.LogWarning($"Bot skin '{data.SkinName}' not found and no default skin available.");
            }
        }
    } else if (BotSpineGraphic != null) {
        BotSpineGraphic.gameObject.SetActive(false);
    }
} else if (BotSpineGraphic != null) {
    BotSpineGraphic.gameObject.SetActive(false);
}

}

Question:
How can I ensure smooth, flicker-free updates of Spine skins during fast scroll animations? Is there a way to guarantee that <none> state is never visible even for a single frame?

  • Harald ответили на это сообщение.
    Related Discussions
    ...

    The flickering issue you're experiencing during fast skin changes in Unity with Spine SkeletonGraphic might be due to the timing of the SetSlotsToSetupPose() and SetAnimation() calls. To address this, ensure that the SetSlotsToSetupPose() is only called when necessary, as you've already done. Additionally, consider using SkeletonAnimation.Update(0) immediately after setting the skin and before setting the animation to ensure that the skeleton's state is updated within the same frame. This can help prevent the <none> state from being visible. Also, check if the Advanced - PMA Vertex Color setting is affecting the rendering and try disabling it to see if it resolves the flickering.

    Another approach is to ensure that the MixDuration is set appropriately and that the animations are being applied correctly. If the flickering persists, you might want to explore using a SortingGroup component or enabling Advanced - Fix Draw Order on your SkeletonAnimation component to address potential draw order issues, especially if you're using multiple atlas textures or the Universal Render Pipeline (URP).

    meanwhile I occasionally see the <none> state

    What do you mean by "the <none> state"? Do you mean that there is no skin assigned for a frame and displayed as <none> in the Inspector? Then your game logic does something wrong.

    In general try to remove all your game logic code that does other things, then you can see whether it's your Spine API calls which cause the problem or your game logic which is wrong.

    meanwhile Added MixDuration to SetAnimation calls — still flickers.

    If I understood you correctly, you are changing attachments or skins, so how would changing MixDuration change anything here? Attachments are switched in binary fashion, according to the set attachment threshold mixAttachmentThreshold. They don't fade in and out over time.

    meanwhile Played around with Coroutine intervals — no improvement.

    Do you call your code from coroutines? Then you might need to call SkeletonAnimation.Update(0) immediately afterwards as Spinebot mentioned.

    yes, it worked when i put SkeletonAnimation.Update(0). thanks

    Glad to hear, thanks for letting us know.