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
}
}