22using Gameframe . GUI . Tween ;
33using UnityEngine ;
44using UnityEngine . Events ;
5+ using UnityEngine . Serialization ;
56
67namespace Gameframe . GUI
78{
89 public abstract class PlayableTextMeshEffect : MonoBehaviour , IPlayableTextMeshEffect
910 {
1011 [ SerializeField ]
1112 private TextMeshEffectTMPro effectManager ;
12-
13+
1314 [ SerializeField ]
1415 protected bool playOnEnable ;
1516
16- [ SerializeField ]
17+ [ SerializeField ]
1718 protected Easing easeType = Easing . Linear ;
1819
19- [ SerializeField ]
20- protected float charactersPerSecond = 15 ;
21- public float CharacterPerSecond
20+ public Easing EaseType
21+ {
22+ get => easeType ;
23+ set => easeType = value ;
24+ }
25+
26+ [ SerializeField ]
27+ protected AnimationCurve customCurve = AnimationCurve . Linear ( 0 , 0 , 1 , 1 ) ;
28+
29+ public AnimationCurve Curve
30+ {
31+ get => customCurve ;
32+ set => customCurve = value ;
33+ }
34+
35+ [ SerializeField ] [ FormerlySerializedAs ( "charactersPerSecond" ) ]
36+ protected float speed = 15 ;
37+ public float Speed
38+ {
39+ get => speed ;
40+ set => speed = value ;
41+ }
42+
43+ [ SerializeField ] [ FormerlySerializedAs ( "startDelayMultiplier" ) ]
44+ protected float delayPerCharacter = 1f ;
45+
46+ public float DelayPerCharacter
47+ {
48+ get => delayPerCharacter ;
49+ set => delayPerCharacter = value ;
50+ }
51+
52+ [ SerializeField ]
53+ protected float characterAnimationDuration = 1f ;
54+
55+ public float CharacterAnimationDuration
2256 {
23- get => charactersPerSecond ;
24- set => charactersPerSecond = value ;
57+ get => characterAnimationDuration ;
58+ set => characterAnimationDuration = value ;
2559 }
26-
60+
2761 [ SerializeField ]
2862 protected UnityEvent onComplete = new UnityEvent ( ) ;
2963 public UnityEvent OnComplete => onComplete ;
30-
31- protected float progress ;
32-
33- private Coroutine coroutine ;
3464
35- public bool IsPlaying => coroutine != null ;
36-
65+ private float _progress ;
66+
67+ private Coroutine _coroutine ;
68+
69+ public bool IsPlaying => _coroutine != null ;
70+
71+ protected float GetEasedTime ( ref EffectData data , float offset = 0 )
72+ {
73+ var characterStartTime = data . Index * delayPerCharacter ;
74+ var rawTime = ( _progress + offset - characterStartTime ) / characterAnimationDuration ;
75+ var easeTime = Ease ( Mathf . Clamp01 ( rawTime ) ) ;
76+ return easeTime ;
77+ }
78+
79+ /// <summary>
80+ /// Value goes from 1 to 0 instead of 0 to 1
81+ /// </summary>
82+ /// <param name="data"></param>
83+ /// <param name="offset"></param>
84+ /// <returns></returns>
85+ protected float GetInverseEaseTime ( ref EffectData data , float offset = 0 )
86+ {
87+ var characterStartTime = data . Index * delayPerCharacter ;
88+ var rawTime = ( _progress + offset - characterStartTime ) / characterAnimationDuration ;
89+ var easeTime = Ease ( 1 - Mathf . Clamp01 ( rawTime ) ) ;
90+ return easeTime ;
91+ }
92+
3793 protected void OnEnable ( )
3894 {
3995 if ( playOnEnable )
@@ -49,57 +105,67 @@ protected void OnDisable()
49105
50106 public void Play ( )
51107 {
52- if ( coroutine != null )
108+ if ( _coroutine != null )
53109 {
54110 Finish ( ) ;
55111 }
56- coroutine = StartCoroutine ( Run ( ) ) ;
112+ _coroutine = StartCoroutine ( Run ( ) ) ;
57113 }
58114
59115 public void Finish ( )
60116 {
61- if ( coroutine != null )
117+ if ( _coroutine != null )
62118 {
63119 RemoveFromManager ( effectManager ) ;
64- StopCoroutine ( coroutine ) ;
120+ StopCoroutine ( _coroutine ) ;
65121 onComplete . Invoke ( ) ;
66122 }
67- coroutine = null ;
123+ _coroutine = null ;
68124 }
69125
70126 protected abstract void AddToManager ( TextMeshEffectTMPro effectManager ) ;
71127 protected abstract void RemoveFromManager ( TextMeshEffectTMPro effectManager ) ;
72128
129+ protected float Ease ( float t )
130+ {
131+ return easeType == Easing . CustomCurve ? customCurve . Evaluate ( t ) : EaseFunctions . Ease ( easeType , t ) ;
132+ }
133+
73134 private IEnumerator Run ( )
74135 {
75136 AddToManager ( effectManager ) ;
76137 yield return RunAnimation ( ) ;
77138 Finish ( ) ;
78139 }
79-
140+
80141 private IEnumerator RunAnimation ( )
81142 {
82- int characterCount = effectManager . Text . textInfo . characterCount ;
83- progress = 0 ;
84- while ( progress < characterCount )
143+ var characterCount = effectManager . Text . textInfo . characterCount ;
144+ _progress = 0 ;
145+ var duration = ( delayPerCharacter * characterCount ) + characterAnimationDuration ;
146+ while ( _progress < duration )
85147 {
86- progress += Time . smoothDeltaTime * charactersPerSecond ;
148+ _progress += Time . deltaTime * speed ;
87149 yield return null ;
88150 }
89151 }
90-
91- private void OnValidate ( )
152+
153+ protected virtual void OnValidate ( )
92154 {
93155 if ( effectManager == null )
94156 {
95157 effectManager = GetComponent < TextMeshEffectTMPro > ( ) ;
96158 }
97159
98- if ( charactersPerSecond < 0 )
160+ if ( speed < 0 )
99161 {
100- charactersPerSecond = 1 ;
162+ speed = 1 ;
163+ }
164+
165+ if ( characterAnimationDuration < 0.01f )
166+ {
167+ characterAnimationDuration = 0.01f ;
101168 }
102169 }
103170 }
104171}
105-
0 commit comments