126 lines
3.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|