using System; using System.Collections; using AibisDream.Framework; using AibisDream.SaveSystem; using AibisDream.Utility; using DG.Tweening; using UnityEngine; using Object = UnityEngine.Object; namespace AibisDream { /// /// 角色基类 /// 有Sprite实现和Animator实现 /// public abstract class AbsActor : MonoBehaviour { protected string _actorName; protected string _slotName; protected ActorType _actorType; protected float _alpha; protected SpriteRenderer spriteRenderer; public string ActorName => _actorName; public string SlotName => _slotName; public ActorType ActorType => _actorType; public void Init(string actorName, ActorSlot slot, ActorType actorType) { _actorName = actorName; _slotName = slot.slotName; _actorType = actorType; _alpha = 0; InitInternal(); SetSlot(slot); } public void InitFromEntry(ActorEntrySnapshotDto entry, ActorSlot slot) { _actorName = entry.actorName; _slotName = entry.slotName; _alpha = entry.alpha; if (!Enum.TryParse(entry.actorType, out _actorType)) { _actorType = ActorType.Anima; } InitInternal(); SetSlot(slot); } protected virtual void InitInternal() { gameObject.name = ActorName; spriteRenderer = GetComponent(); spriteRenderer.SetAlpha(0); } public abstract ActorEntrySnapshotDto CaptureEntry(); public abstract IEnumerator ApplyEntryAsync(ActorEntrySnapshotDto entry); protected void FillBaseEntry(ActorEntrySnapshotDto entry) { entry.actorName = _actorName; entry.slotName = _slotName; entry.actorType = _actorType.ToString(); entry.alpha = _alpha; } protected void ApplyAlphaFromEntry(ActorEntrySnapshotDto entry) { if (entry.alpha <= 0.01f) { Hide(); } else { SetAlpha(Mathf.RoundToInt(entry.alpha)); } } public void Show() { _alpha = 1; spriteRenderer.SetAlpha(1); } public void Hide() { _alpha = 0; spriteRenderer.SetAlpha(0); } public void SetSlot(ActorSlot slot) { transform.position = slot.Position; spriteRenderer.sortingOrder = slot.sortingOrder; spriteRenderer.sortingLayerID = slot.sortingLayer; _slotName = slot.slotName; } public IEnumerator FadeInAsync(float duration) { _alpha = 1; yield return spriteRenderer.DOFade(1, duration).WaitForCompletion(); } public IEnumerator FadeOutAsync(float duration) { _alpha = 0; yield return spriteRenderer.DOFade(0, duration).WaitForCompletion(); } public void SetAlpha(int alpha) { _alpha = alpha; spriteRenderer.SetAlpha(alpha); } public abstract void ChangeState(string stateName); public virtual IEnumerator ChangeStateAsync(string stateName) { ChangeState(stateName); yield break; } public virtual void SetTalkingState(bool isTalking) {} public virtual void SetFaceState(string faceName) {} } public class ActorFactory { private readonly Transform _actorRoot; private readonly GameObject _actorAnimaPrefab; private readonly GameObject _spriteActorPrefab; private readonly GameObject _actorAnimaExPrefab; public ActorFactory(Transform actorRoot) { _actorRoot = actorRoot; _actorAnimaPrefab = ResourceKit.LoadAssetSync(ConstRef.ActorPrefabName); _spriteActorPrefab = ResourceKit.LoadAssetSync(ConstRef.SpriteActorPrefabName); _actorAnimaExPrefab = ResourceKit.LoadAssetSync(ConstRef.ActorAnimaExPrefabName); } public AbsActor CreateActor(string actorName, ActorSlot slot, ActorType actorType) { var actor = InstantiateByType(actorType); if (actor) { actor.Init(actorName, slot, actorType); } return actor; } public AbsActor CreateFromEntry(ActorEntrySnapshotDto entry, ActorSlot slot) { if (!Enum.TryParse(entry.actorType, out var actorType)) { actorType = ActorType.Anima; } var actor = InstantiateByType(actorType); if (actor) { actor.InitFromEntry(entry, slot); } return actor; } private AbsActor InstantiateByType(ActorType actorType) { return actorType switch { ActorType.Sprite => Object.Instantiate(_spriteActorPrefab, _actorRoot).GetComponent(), ActorType.Anima => Object.Instantiate(_actorAnimaPrefab, _actorRoot).GetComponent(), ActorType.AnimaEx => Object.Instantiate(_actorAnimaExPrefab, _actorRoot).GetComponent(), _ => null }; } } public enum ActorType { Sprite, Anima, AnimaEx } }