Files

126 lines
3.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using AibisDream.Framework;
using AibisDream.SaveSystem;
using UnityEngine;
namespace AibisDream
{
public class ActorAnimaEx : AbsActor
{
private const string IsTalkingParam = "Is Talking";
private Animator _animator;
private string _currentStateName;
private string _currentFaceName;
private Dictionary<string, BlendTreeInfo> _blendTreeDict;
protected override void InitInternal()
{
_animator = GetComponent<Animator>();
base.InitInternal();
_actorType = ActorType.AnimaEx;
var controller = ResourceKit.LoadAssetSync<RuntimeAnimatorController>($"Animation/{ActorName}");
_animator.runtimeAnimatorController = controller;
ParseBlendTreeInfos();
}
private void ParseBlendTreeInfos()
{
_blendTreeDict = new Dictionary<string, BlendTreeInfo>();
var configText = ResourceKit.LoadAssetSync<TextAsset>($"AnimationConfig/{ActorName}");
if (configText == null) return;
var blendTreeConfig = AnimatorKit.ParseBlendTreeConfigFromJson(configText.text);
if (blendTreeConfig?.blendTrees == null) return;
foreach (var info in blendTreeConfig.blendTrees)
{
_blendTreeDict[info.name] = info;
}
_currentStateName = blendTreeConfig.defaultStateName;
}
public override void ChangeState(string stateName)
{
StartCoroutine(ChangeStateAsync(stateName));
}
public override IEnumerator ChangeStateAsync(string stateName)
{
_currentStateName = stateName;
_animator.SetTrigger(stateName);
while (!_animator.GetCurrentAnimatorStateInfo(0).IsName(stateName))
{
yield return null;
}
_animator.ResetTrigger(stateName);
}
public override void SetTalkingState(bool isTalking)
{
_animator.SetFloat(IsTalkingParam, isTalking ? 1 : 0);
}
public override void SetFaceState(string faceName)
{
_currentFaceName = faceName;
if (!_blendTreeDict.TryGetValue(_currentStateName, out var blendTreeInfo))
{
Debug.LogWarning($"当前状态{_currentStateName}的混合树信息不存在");
return;
}
if (blendTreeInfo.type == "1D")
{
var clipInfo = blendTreeInfo.GetClipInfo(faceName);
if (clipInfo != null)
{
_animator.SetFloat(blendTreeInfo.blendParameter, clipInfo.threshold);
}
}
else
{
var clipInfo = blendTreeInfo.GetClipInfo(faceName);
if (clipInfo != null)
{
_animator.SetFloat(blendTreeInfo.blendParameter, clipInfo.position.x);
}
}
}
public override ActorEntrySnapshotDto CaptureEntry()
{
var entry = new ActorEntrySnapshotDto();
FillBaseEntry(entry);
entry.stateName = _currentStateName;
entry.faceName = _currentFaceName;
entry.isTalking = _animator.GetFloat(IsTalkingParam) > 0.5f;
return entry;
}
public override IEnumerator ApplyEntryAsync(ActorEntrySnapshotDto entry)
{
ApplyAlphaFromEntry(entry);
if (!string.IsNullOrEmpty(entry.stateName))
{
yield return ChangeStateAsync(entry.stateName);
}
if (!string.IsNullOrEmpty(entry.faceName))
{
SetFaceState(entry.faceName);
}
SetTalkingState(entry.isTalking);
}
}
}