11using Live2D . Cubism . Framework . MotionFade ;
22using System ;
33using UnityEngine ;
4+ using UnityEngine . Playables ;
5+ using UnityEngine . Animations ;
46using System . Collections ;
57
68namespace Live2D . Cubism . Framework . Motion
@@ -24,6 +26,8 @@ public class CubismMotionController : MonoBehaviour
2426 public Action < int , AnimationClip > OnAnimationStart ; // 动画开始时触发
2527 public Action < int , AnimationClip > OnAnimationEnd ; // 动画结束时触发
2628
29+ private Animation [ ] layerAnimations ;
30+
2731 #endregion
2832
2933 #region Public Methods
@@ -137,13 +141,27 @@ private void OnEnable()
137141 Debug . LogError ( "CubismFadeMotionList is not set in CubismFadeController." ) ;
138142 return ;
139143 }
140-
141- SyncAnimators ( ) ;
142- InitializeOverrideController ( ) ;
144+ // SyncAnimators();
145+ // InitializeOverrideController();
143146 InitializeStateArrays ( ) ;
147+ InitializeAnimationComponents ( ) ;
144148 isActive = true ;
145149 }
146150
151+ private void InitializeAnimationComponents ( )
152+ {
153+ layerAnimations = new Animation [ layerCount ] ;
154+ for ( int i = 0 ; i < layerCount ; i ++ )
155+ {
156+ Animation anim = gameObject . GetComponent < Animation > ( ) ;
157+ if ( anim == null )
158+ {
159+ anim = gameObject . AddComponent < Animation > ( ) ;
160+ }
161+ layerAnimations [ i ] = anim ;
162+ }
163+ }
164+
147165 private void InitializeComponents ( )
148166 {
149167 fadeMotionList = GetComponent < CubismFadeController > ( ) . CubismFadeMotionList ;
@@ -213,5 +231,93 @@ private void SyncAnimatorParameters()
213231 }
214232
215233 #endregion
234+
235+ #region Animation Component Methods
236+
237+ /// <summary>
238+ /// 使用 Animation 组件播放旧版动画剪辑,支持优先级和速度。
239+ /// </summary>
240+ public void PlayLegacyAnimation ( AnimationClip legacyClip , int layerIndex = 0 , int priority = CubismMotionPriority . PriorityNormal ,
241+ bool isLoop = true , float speed = 1.0f , Action onComplete = null )
242+ {
243+ if ( ! CanPlayLegacyAnimation ( legacyClip , layerIndex , priority ) )
244+ {
245+ Debug . LogWarning ( $ "Cannot play legacy animation: { legacyClip ? . name } on Layer { layerIndex } ") ;
246+ return ;
247+ }
248+
249+ SetupLegacyAnimation ( legacyClip , layerIndex , priority , isLoop , speed ) ;
250+ StartCoroutine ( MonitorLegacyAnimation ( layerIndex , legacyClip , onComplete ) ) ;
251+ }
252+
253+ /// <summary>
254+ /// 停止指定层的旧版动画。
255+ /// </summary>
256+ public void StopLegacyAnimation ( int layerIndex )
257+ {
258+ if ( ! IsValidLayer ( layerIndex ) || ! isLayerPlaying [ layerIndex ] ) return ;
259+
260+ layerAnimations [ layerIndex ] . Stop ( ) ;
261+ ResetLayerState ( layerIndex ) ;
262+ Debug . Log ( $ "Stopped legacy animation on Layer { layerIndex } ") ;
263+ }
264+
265+ private bool CanPlayLegacyAnimation ( AnimationClip clip , int layerIndex , int priority )
266+ {
267+ return enabled && isActive && clip != null && clip . legacy && IsValidLayer ( layerIndex )
268+ && ( priority == CubismMotionPriority . PriorityForce || motionPriorities [ layerIndex ] <= priority ) ;
269+ }
270+
271+ private void SetupLegacyAnimation ( AnimationClip legacyClip , int layerIndex , int priority , bool isLoop , float speed )
272+ {
273+ // 设置 Animation 组件状态
274+ Animation animation = layerAnimations [ layerIndex ] ;
275+ animation . playAutomatically = false ;
276+ animation . Stop ( ) ; // 停止当前动画
277+
278+ // 添加或替换 Clip
279+ string clipName = $ "Layer{ layerIndex } _Legacy_{ legacyClip . name } ";
280+ animation . AddClip ( legacyClip , clipName ) ;
281+
282+ // 配置播放参数
283+ AnimationState state = animation [ clipName ] ;
284+ state . speed = speed ;
285+ state . wrapMode = isLoop ? WrapMode . Loop : WrapMode . Once ;
286+
287+ // 更新层状态
288+ motionPriorities [ layerIndex ] = priority ;
289+ shouldLoop [ layerIndex ] = isLoop ;
290+ isLayerPlaying [ layerIndex ] = true ;
291+
292+ // 开始播放
293+ animation . Play ( clipName ) ;
294+
295+ OnAnimationStart ? . Invoke ( layerIndex , legacyClip ) ;
296+ Debug . Log ( $ "Playing legacy animation { legacyClip . name } on Layer { layerIndex } | Priority: { priority } | Loop: { isLoop } | Speed: { speed } ") ;
297+ }
298+
299+ private IEnumerator MonitorLegacyAnimation ( int layerIndex , AnimationClip legacyClip , Action onComplete )
300+ {
301+ Animation animation = layerAnimations [ layerIndex ] ;
302+ AnimationState state = animation [ $ "Layer{ layerIndex } _Legacy_{ legacyClip . name } "] ;
303+
304+ yield return new WaitForSeconds ( legacyClip . length / state . speed ) ;
305+
306+ if ( ! shouldLoop [ layerIndex ] || ! isLayerPlaying [ layerIndex ] )
307+ {
308+ OnAnimationEnd ? . Invoke ( layerIndex , legacyClip ) ;
309+ ResetLayerState ( layerIndex ) ;
310+ onComplete ? . Invoke ( ) ;
311+ Debug . Log ( $ "Legacy animation { legacyClip . name } ended on Layer { layerIndex } ") ;
312+ }
313+ else
314+ {
315+ Debug . Log ( $ "Legacy animation { legacyClip . name } looping on Layer { layerIndex } ") ;
316+ }
317+ }
318+
319+ #endregion
320+
321+
216322 }
217323}
0 commit comments