using System;
using System.Collections;
using System.Collections.Generic;
using AnimatorPlus;
using SLSFramework.General;
using UnityEngine;
namespace Continentis.MainGame.Character
{
///
/// Tier 2 动画驱动器:帧动画方案,基于 AnimatorPlus2D + AnimationClip。
/// 通过 CharacterData.animations 映射表驱动 Sprite Sheet 帧动画。
/// 适合有完整帧动画序列的像素风角色(如 PixelFantasy 系列)。
///
public class FrameAnimator : MonoBehaviour, ICharacterAnimator
{
private AnimatorPlus2D _animatorPlus;
private SerializableDictionary _animations;
private Coroutine _completionCoroutine;
// ── ICharacterAnimator ──────────────────────────────────────────────
///
/// 初始化:从 CombatCharacterViewBase 获取 AnimatorPlus2D 引用和动画映射表。
///
public void InitializeAnimator(CombatCharacterViewBase view)
{
_animatorPlus = view.animatorPlus2D;
// 从 CharacterData 拷贝动画映射
_animations = new SerializableDictionary();
foreach (KeyValuePair pair in view.character.data.animations)
{
_animations.Add(pair.Key, pair.Value);
}
// 设置 Idle 并初始化 Playable Graph
if (_animations.TryGetValue("Idle", out AnimationClip idle))
{
_animatorPlus.defaultIdleClip = idle;
_animatorPlus.Initialize();
}
else
{
Debug.LogError($"[FrameAnimator] 角色 '{view.character.data.displayName}' 缺少 Idle 动画,无法初始化。");
}
}
///
/// 播放指定动作的 AnimationClip,播完自动回 Idle 并触发回调。
///
public void PlayAction(string actionName, float speed = 1f, Action onComplete = null)
{
StopCompletionCoroutine();
if (!_animations.TryGetValue(actionName, out AnimationClip clip))
{
Debug.LogWarning($"[FrameAnimator] 找不到动画 '{actionName}',跳过播放。");
onComplete?.Invoke();
return;
}
_animatorPlus.Play(clip, speed);
// 动画播完后触发回调(AnimatorPlus2D 自动回 Idle,此处仅等待时长)
if (onComplete != null)
{
float duration = clip.length / Mathf.Max(speed, 0.01f);
_completionCoroutine = StartCoroutine(WaitForCompletion(duration, onComplete));
}
}
///
/// 立即停止当前动作,切回 Idle。
///
public void ReturnToIdle()
{
StopCompletionCoroutine();
_animatorPlus.Stop();
}
///
/// 暂停或恢复 PlayableGraph。
///
public void SetPause(bool isPaused)
{
_animatorPlus.SetPause(isPaused);
}
// ── 内部逻辑 ────────────────────────────────────────────────────────
private IEnumerator WaitForCompletion(float duration, Action onComplete)
{
yield return new WaitForSeconds(duration);
onComplete?.Invoke();
_completionCoroutine = null;
}
private void StopCompletionCoroutine()
{
if (_completionCoroutine != null)
{
StopCoroutine(_completionCoroutine);
_completionCoroutine = null;
}
}
}
}