Hello ! 🙂
I have a performance issue when trying to fade out a SkeletonGraphic via code.
To do that, I am using the SkeletonGraphic.color property, inherited from UnityEngine.UI.Graphic.color, and modify its alpha.
My first question is : is it the correct way to do it ? (or should I use a CanvasGroup on top, or another method...)
When profiling, I was surprised by the long time processing Canvas.SendWillRenderCanvases, in particular, CanvasUpdate.PreRender.
After debugging, I eventually understood that :
- Setting the color property marks the vertices of the Graphic component as dirty :
public virtual Color color { get { return m_Color; } set { if (SetPropertyUtility.SetColor(ref m_Color, value)) SetVerticesDirty(); } } // from UnityEngine.UI.Graphic.cs
The dirty SkeletonGraphic will be rebuilt during the Canvas Update (cf. "SpineCanvasRebuild" screenshot)
When rebuilding, the SkeletonGraphic will (re)Update its mesh.
// From SkeletonGraphic.cs
public override void Rebuild (CanvasUpdate update) {
base.Rebuild(update);
if (canvasRenderer.cull) return;
if (update == CanvasUpdate.PreRender) UpdateMesh(keepRendererCount: true);
if (allowMultipleCanvasRenderers) canvasRenderer.Clear();
}
For my use case, this is redundant : the mesh is already updated in SkeletonGraphic.LateUpdate(), I don't want to reupdate it in the same frame as it was already quite expensive ^^"
So I tried setting the color not via the color property, but directly in the skeleton using skeleton.A or skeleton.SetColor().
Unfortunately, SkeletonGraphic eventually uses this Graphic.color property I'm dreading :
public void UpdateMesh (bool keepRendererCount = false) {
if (!this.IsValid) return;
// !!!
skeleton.SetColor(this.color); // !!! The culprit !!!
// !!!
var currentInstructions = this.currentInstructions;
if (!this.allowMultipleCanvasRenderers) {
UpdateMeshSingleCanvasRenderer();
} else {
UpdateMeshMultipleCanvasRenderers(currentInstructions, keepRendererCount);
}
if (OnMeshAndMaterialsUpdated != null)
OnMeshAndMaterialsUpdated(this);
}
Do you have any recommendation ? How can I achieve my effect, possibly without modifying the Spine Unity runtime ?
Thanks in advance 🙂
One way I see to prevent this would be to temporarily limit the updateMode to "OnlyAnimationStatus", while I do my alpha fading.
But I'd be happy to hear other solutions 🙂