Demigiant / dotween

A Unity C# animation engine. HOTween v2
http://dotween.demigiant.com
Other
2.33k stars 348 forks source link

DOTweenTMPAnimator - SetChar not working #567

Open LazyEti opened 2 years ago

LazyEti commented 2 years ago

I've been trying to create a simple reveal effect for hours and came to the conclusion that .SetChar doesn't work. The values should be updated since .GetChar returns the correct Set values, But It just wont update the visuals and the tweens ignore these changes. Is there something I need to do to refresh the text with the new set values before applying tweens to it?

Here's a sample of my code: ` DOTweenTMPAnimator textAnimator = new DOTweenTMPAnimator (_text); currentTypeSequence = DOTween.Sequence ();

    for (var i = 0; i < charCount; ++i)
    {
        //skip spaces
        if (!textAnimator.textInfo.characterInfo[i].isVisible) continue; 

        //create timing offset for each char:
        timeOffset += charTime;

        //set character scale to zero:
        textAnimator.SetCharScale (i, Vector3.zero);

        //Tween scale char to 1
        currentTypeSequence.Insert (timeOffset, textAnimator.DOScaleChar (i, 1, .2f).SetEase (Ease.OutBack, 5));

        //play sound every 2 char
        if (i % 2 == 0) currentTypeSequence.InsertCallback (timeOffset, () => dlab.AudioSystem.Instance.OneShot (q: characterProfile.SoundCue));

        //add pause if ,
        timeOffset += _text.text[i] == ',' ? .2f : 0;
    }

    SpeakAnim (timeOffset);
    currentTypeSequence.OnComplete (TypingEnded);
    `
         I got it to work with this dirty hack, but I don't think it's great performance wise:

//tween all chars to 0 instantly then scale them back to 1 currentTypeSequence.Insert (0, textAnimator.DOScaleChar (i, 0, 0)); currentTypeSequence.Insert (timeOffset, textAnimator.DOScaleChar (i, 1, .2f).SetEase (Ease.OutBack, 5));

Demigiant commented 2 years ago

Ahoy,

I can't test it right now, but the problem might be related to the fact that TMP (like most Unity objects) doesn't really like its characters' scale to be set to 0. Could you make a test in the meantime, and let me know if this method works?

  1. Remove the textAnimator.SetCharScale (i, Vector3.zero); line
  2. Replace the Insert line with this: currentTypeSequence.Insert (timeOffset, textAnimator.DOScaleChar (i, 1, .2f).From(0).SetEase (Ease.OutBack, 5));
LazyEti commented 2 years ago

Ahoy,

I can't test it right now, but the problem might be related to the fact that TMP (like most Unity objects) doesn't really like its characters' scale to be set to 0. Could you make a test in the meantime, and let me know if this method works?

  1. Remove the textAnimator.SetCharScale (i, Vector3.zero); line
  2. Replace the Insert line with this: currentTypeSequence.Insert (timeOffset, textAnimator.DOScaleChar (i, 1, .2f).From(0).SetEase (Ease.OutBack, 5));

I tried this out already but using .From() doesn't seems to work either. The text starts completely visible from a scale of 1 and receive only the ease animation overshoot

Demigiant commented 2 years ago

I just made a test and it works here, even with setting them at 0 instead of 0.0001. But I had a problem with TMP's TextChanged event not being called, which didn't trigger the textAnimator Refresh (used to refresh TMP's mesh).

Could you try calling textAnimator.Refresh(); before starting your FOR loop? That should work, in which case I need to understand why in recent TMP versions that's a problem.

LazyEti commented 2 years ago

Heya Thanks for the help, I tried to call textAnimator.Refresh(); before starting the FOR loop but it didn't do anything for me. I'm using Unity 2020.3.16f1 and TMP 3.0.6

fmoyano commented 2 years ago

I'm not sure if this is related but I noticed something when upgrading from 1.0.244 to the latest one (1.0.310).

I had this effect where I first would warp the text according to a curve, and then, apply a per-character punch scale to the warped text. It worked perfectly on 1.0.244, but in the newer version, the punch scale animation resets the vertex data and undoes the warping.

I used to have this line in the previous version for the punch scale: var animator = new DOTweenTMPAnimator(GetComponent(), false);

The second argument to false would prevent the vertex data to be refreshed.

But in the newer version, the second argument is not allowed anymore and my guess is that once I create the animator, the vertex data is refreshed.

Does it make sense? Is there a way to avoid the refresh of vertex data when creating the animator?