/// <summary>
        /// If there is TMPro and a link to potentially animate then ask the AnimLookup for it
        /// </summary>
        protected void UpdateAnimation()
        {
            //could we anim
            if (TMProComponent != null && enabled)
            {
                bool requiresVertexDataUpdate = false;

                //for all found links
                for (int i = 0; i < TMProComponent.textInfo.linkCount; i++)
                {
                    var curLink = TMProComponent.textInfo.linkInfo[i];

                    //if a static lookup exists, ask it to run its animation with us as the context
                    if (TMProLinkAnimLookup.LinkHashToEffect.TryGetValue(curLink.hashCode, out TMProLinkAnimLookup.TMProAnimFunc animFunc))
                    {
                        //only update caches if we actually need it
                        HandleDirty();

                        animFunc(this, curLink.linkTextfirstCharacterIndex, curLink.linkTextLength);

                        requiresVertexDataUpdate = true;
                    }
                }

                // Push changes if we actually found a matching effect
                if (requiresVertexDataUpdate)
                {
                    TMProComponent.UpdateVertexData();
                }
            }
        }
 protected void HandleDirty()
 {
     //update internal cache if underlying data has changed
     if (dirty)
     {
         if (needsToForceMeshUpdate)
         {
             forcedUpdater = this;
             TMProComponent.ForceMeshUpdate();
             forcedUpdater = null;
         }
         CachedMeshInfo = TMProComponent.textInfo.CopyMeshInfoVertexData();
         dirty          = false;
     }
 }