using System; using System.Collections; using System.Collections.Generic; using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; using Yarn.Unity; namespace AibisDream { public class ActorManager : Singleton { #region 索引 private Transform _actorRoot; private Dictionary _slotDict; private Dictionary _actorDict; private ActorFactory _actorFactory; #endregion private ActorSystemData _actorSystemData; public override void OnSingletonInit() { InitRefs(); DestroyEditorTemp(); InitDefaultActor(); } public override void OnSingletonDestroy() { _actorSystemData.OnLoad -= OnDataLoad; StorageSystem.Instance.UnregisterData(); } public void DestroyEditorTemp() { foreach (Transform child in _actorRoot) { #if UNITY_EDITOR if (!Application.isPlaying) { DestroyImmediate(child.gameObject); continue; } #endif Destroy(child.gameObject); } _actorDict.Clear(); } private void InitDefaultActor() { foreach (var slot in _slotDict.Values.Where(slot => slot.hasDefaultActor)) { InitActor(slot.defaultActorName, slot.slotName, slot.defaultActorType); } } private void InitRefs() { _actorRoot = transform.Find("ActorRoot"); _slotDict = new Dictionary(); foreach (var child in transform.Find("Slots").GetComponentsInChildren()) { _slotDict[child.slotName] = child; } _actorDict = new Dictionary(); _actorFactory = new ActorFactory(_actorRoot); // 注册数据 _actorSystemData = new ActorSystemData(); _actorSystemData.OnLoad += OnDataLoad; StorageSystem.Instance.RegisterData(_actorSystemData); } private void OnDataLoad(ActorSystemData data) { Debug.Log("Actor Load"); foreach (var actorData in data.actorDataList) { InitActor(actorData); } } #if UNITY_EDITOR public void InitAllDefault() { InitRefs(); DestroyEditorTemp(); foreach (var slot in _slotDict.Values) { if (!string.IsNullOrEmpty(slot.defaultActorName)) { var actor = InitActor(slot.defaultActorName, slot.slotName, slot.defaultActorType); actor.Show(); } else { Debug.Log($"slot {slot.slotName} 没有默认角色"); } } } #endif public AbsActor InitActor(string actorName, string slotName, ActorType actorType) { var slot = _slotDict[slotName]; // 生成新组件 var actor = _actorFactory.CreateActor(actorName, slot, actorType); // 保存 _actorDict.Add(actorName, actor); _actorSystemData.actorDataList.Add(actor.actorData); return actor; } private void InitActor(ActorData actorData) { if (_slotDict.TryGetValue(actorData.slotName, out var slot)) { // 生成新组件 var actor = _actorFactory.CreateActor(actorData, slot); // 保存 _actorDict.Add(actorData.actorName, actor); } else { Debug.LogWarning($"slot {actorData.slotName} 不存在"); } } public bool TryFindActor(string actorOrSlot, out AbsActor actor) { if (_actorDict.TryGetValue(actorOrSlot, out actor)) { return true; } actor = _actorDict.Values.FirstOrDefault(item => item.SlotName == actorOrSlot); return actor != null; } public void ChangeSlot(string actorOrSlot, string targetSlot) { if (!_slotDict.TryGetValue(targetSlot, out var targetSlotObj)) return; if (!TryFindActor(actorOrSlot, out var actor)) return; actor.SetSlot(targetSlotObj); } } public static class ActorYarnCommand { private const string ClinicSlotName = "clinic"; [YarnCommand("init_actor")] public static void InitActor(string actorName, string slotName = ClinicSlotName, string actorType = "Anima") { if (Enum.TryParse(actorType, out var actorTypeEnum)) { ActorManager.Instance.InitActor(actorName, slotName, actorTypeEnum); } else { Debug.Log($"Actor类型{actorType}有问题"); } } [YarnCommand("change_actor_state")] public static void PlayAnima(string animaName, string slotOrActorName = ClinicSlotName) { if (ActorManager.Instance.TryFindActor(slotOrActorName, out var actor)) { actor.ChangeState(animaName); } } [YarnCommand("change_actor_state_async")] public static IEnumerator PlayAnimaAsync(string animaName, string slotOrActorName = ClinicSlotName) { if (ActorManager.Instance.TryFindActor(slotOrActorName, out var actor)) { yield return actor.ChangeStateAsync(animaName); } } [YarnCommand("fade_in_actor")] public static IEnumerator ActorFadeIn(string actorName = ClinicSlotName, float duration = 1) { if (ActorManager.Instance.TryFindActor(actorName, out var actor)) { yield return actor.FadeInAsync(duration); } } [YarnCommand("fade_out_actor")] public static IEnumerator ActorFadeOut(string actorName = ClinicSlotName, float duration = 1) { if (ActorManager.Instance.TryFindActor(actorName, out var actor)) { yield return actor.FadeOutAsync(duration); } } [YarnCommand("change_actor_slot")] public static void ChangeSlot(string actorOrSlot, string targetSlot) { ActorManager.Instance.ChangeSlot(actorOrSlot, targetSlot); } [YarnCommand("show_actor")] public static void ShowActor(string actorName = ClinicSlotName) { if (ActorManager.Instance.TryFindActor(actorName, out var actor)) { actor.Show(); } } [YarnCommand("hide_actor")] public static void HideActor(string actorName = ClinicSlotName) { if (ActorManager.Instance.TryFindActor(actorName, out var actor)) { actor.Hide(); } } } [Serializable] public class ActorSystemData : IData { public List actorDataList = new(); public event Action OnLoad; public IEnumerator Load() { OnLoad?.Invoke(this); yield break; } public void Save() { foreach (var actorData in actorDataList) { actorData.onSave.Invoke(); } } } }