NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Character/Anim/CharacterAnim.cs

356 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using PhxhSDK;
using UnityEngine;
using Constants = Framework.Constants;
using Object = UnityEngine.Object;
namespace Gameplay.Character
{
public class CharacterAnim
{
public readonly Character owner;
public string targetUpAnim;
public string targetDownAnim;
public string targetFullAnim;
public bool noFade = false;
public string currentUpAnim { get; private set; }
public string currentDownAnim { get; private set; }
public string currentFullAnim { get; private set; }
public readonly Animator rawAnim;
private bool _lastIsFullControl = false;
public bool isFullControl = false;
private Dictionary<int, LTAnimLayerInfo> _layerDict;
private float _splitScaleNormalShoot = 1;
public float splitScaleNormalShoot
{
get
{
return _splitScaleNormalShoot;
}
set
{
if (Math.Abs(_splitScaleNormalShoot - value) < 0.01f) return;
_splitScaleNormalShoot = value;
rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
if (owner.weapon != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
}
}
}
private float _splitScaleLowShoot = 1;
public float splitScaleLowShoot
{
get
{
return _splitScaleLowShoot;
}
set
{
if (Math.Abs(_splitScaleLowShoot - value) < 0.01f) return;
_splitScaleLowShoot = value;
rawAnim.SetFloat(EAnimParamConst.AttackScaleLow, _splitScaleLowShoot);
if (owner.weapon != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.AttackScaleLow, _splitScaleLowShoot);
}
}
}
private float _splitScaleNormalReload = 1;
public float splitScaleNormalReload
{
get
{
return _splitScaleNormalReload;
}
set
{
if (Math.Abs(_splitScaleNormalReload - value) < 0.01f) return;
_splitScaleNormalReload = value;
rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
if (owner.weapon != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
}
}
}
private float _splitScaleLowReload = 1;
public float splitScaleLowReload
{
get
{
return _splitScaleLowReload;
}
set
{
if (Math.Abs(_splitScaleLowReload - value) < 0.01f) return;
_splitScaleLowReload = value;
rawAnim.SetFloat(EAnimParamConst.ReloadScaleLow, _splitScaleLowReload);
if (owner.weapon != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.ReloadScaleLow, _splitScaleLowReload);
}
}
}
private float _splitScaleNormalMove = 1;
public float splitScaleNormalMove
{
get
{
return _splitScaleNormalMove;
}
set
{
if (Math.Abs(_splitScaleNormalMove - value) < 0.01f) return;
_splitScaleNormalMove = value;
rawAnim.SetFloat(EAnimParamConst.MoveScaleNormal, _splitScaleNormalMove);
}
}
private float _splitScaleLowMove = 1;
public float splitScaleLowMove
{
get
{
return _splitScaleLowMove;
}
set
{
if (Math.Abs(_splitScaleLowMove - value) < 0.01f) return;
_splitScaleLowMove = value;
rawAnim.SetFloat(EAnimParamConst.MoveScaleLow, _splitScaleLowMove);
}
}
public float NORMAL_MOVESPEED = 3f;
public float LOW_MOVESPEED = 0.6f;
public CharacterAnim(Character owner)
{
this.owner = owner;
rawAnim = owner.RawAnimator;
// var animatorInst = Object.Instantiate(rawAnim.runtimeAnimatorController);
// var overrideController = animatorInst as AnimatorOverrideController;
// if (overrideController != null)
// {
// // 把基础animator也clone一份
// var baseController = overrideController.runtimeAnimatorController;
// var cloneController = Object.Instantiate(baseController);
// overrideController.runtimeAnimatorController = cloneController;
// }
// rawAnim.runtimeAnimatorController = animatorInst;
_lastIsFullControl = false;
isFullControl = false;
rawAnim.SetLayerWeight(EAnimStateIndex.Full, 0);
rawAnim.SetLayerWeight(EAnimStateIndex.Up, 1);
rawAnim.SetLayerWeight(EAnimStateIndex.Down, 1);
}
public void ResetFloats()
{
rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
rawAnim.SetFloat(EAnimParamConst.AttackScaleLow, _splitScaleLowShoot);
rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
rawAnim.SetFloat(EAnimParamConst.ReloadScaleLow, _splitScaleLowReload);
rawAnim.SetFloat(EAnimParamConst.MoveScaleNormal, _splitScaleNormalMove);
rawAnim.SetFloat(EAnimParamConst.MoveScaleLow, _splitScaleLowMove);
if (owner.weapon.weaponAnim != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.AttackScaleLow, _splitScaleLowShoot);
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.ReloadScaleLow, _splitScaleLowReload);
}
}
public async UniTask Init()
{
await _InitAnimInfo();
ResetAnim();
}
private async UniTask _InitAnimInfo()
{
_layerDict = new Dictionary<int, LTAnimLayerInfo>();
var fileName = owner.runtimeData.configData.nameId;
var animInfoPath = string.Format(Constants.ANIMATOR_CONFIG_FORMAT_PATH, fileName);
var loadAsset = await AssetManager.Instance.LoadAssetAsync<TextAsset>(animInfoPath);
if (loadAsset == null)
{
DebugUtil.LogError("[AnimatorInfoExporter] Load animator info failed: {0}", animInfoPath);
return;
}
var json = loadAsset.text;
var result = JsonUtility.FromJson<SaveAnimatorData>(json);
// 立即释放资源
AssetManager.Instance.Unload(animInfoPath);
var layers = result.layers;
// 遍历每个 Layer获取其中的所有动画状态信息
for (var i = 0; i < layers.Count; ++i)
{
var layer = layers[i];
GetAllStates(layer, i);
}
}
/// <summary>
/// 该方法需要在动画速度发生改变时进行调用
/// </summary>
public void ResetAnim()
{
ResetReloadAnim();
ResetShootAnim();
}
public void ResetReloadAnim()
{
// reload时间
var reloadTime = owner.fightData.reloadTime;
var reloadAnimLength = GetStateLength(EAnimUpState.S_RELOAD, EAnimStateIndex.Up);
splitScaleNormalReload = reloadAnimLength / reloadTime;
// rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, splitScaleNormalReload);
var cReloadAnimLength = GetStateLength(EAnimUpState.S_C_RELOAD, EAnimStateIndex.Up);
splitScaleLowReload = cReloadAnimLength / reloadTime;
// rawAnim.SetFloat(EAnimParamConst.ReloadScaleLow, splitScaleLowReload);
}
public void ResetShootAnim()
{
// 开枪时间
var shootTime = owner.fightData.shootCd;
var shootAnimLength = GetStateLength(EAnimUpState.S_ATTACK, EAnimStateIndex.Up);
splitScaleNormalShoot = shootAnimLength / shootTime;
// rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, splitScaleNormalShoot);
var cShootAnimLength = GetStateLength(EAnimUpState.S_C_ATTACK, EAnimStateIndex.Up);
splitScaleLowShoot = cShootAnimLength / shootTime;
// rawAnim.SetFloat(EAnimParamConst.AttackScaleLow, splitScaleLowShoot);
}
private void GetAllStates(SaveLayerData stateMachine,
int layerIndex)
{
// 获取 stateMachine 中的所有动画状态信息
var states = stateMachine.states;
var newLayer = new LTAnimLayerInfo(layerIndex);
_layerDict.Add(layerIndex, newLayer);
// 遍历每个动画状态信息并处理
foreach (var state in states)
{
var newStateInfo = new LTAnimStateInfo();
newStateInfo.stateName = state.stateName;
newStateInfo.clipName = state.clipName;
newStateInfo.clipLength = state.clipLength;
newLayer.stateMap.Add(state.stateName, newStateInfo);
}
}
public void ViewUpdate(float dt)
{
if (isFullControl != _lastIsFullControl)
{
// 控制状态发生改变
if (isFullControl)
{
rawAnim.SetLayerWeight(EAnimStateIndex.Full, 1);
rawAnim.SetLayerWeight(EAnimStateIndex.Up, 0);
rawAnim.SetLayerWeight(EAnimStateIndex.Down, 0);
}
else
{
rawAnim.SetLayerWeight(EAnimStateIndex.Full, 0);
rawAnim.SetLayerWeight(EAnimStateIndex.Up, 1);
rawAnim.SetLayerWeight(EAnimStateIndex.Down, 1);
}
_lastIsFullControl = isFullControl;
currentDownAnim = null;
currentUpAnim = null;
currentFullAnim = null;
}
if (currentFullAnim != targetFullAnim)
{
if (currentFullAnim == null || noFade)
{
rawAnim.Play(targetFullAnim, EAnimStateIndex.Full, 0);
}
else
{
rawAnim.CrossFade(targetFullAnim, 0.1f, EAnimStateIndex.Full, 0);
}
currentFullAnim = targetFullAnim;
}
if (currentUpAnim != targetUpAnim)
{
if (currentUpAnim == null || noFade)
{
rawAnim.Play(targetUpAnim, EAnimStateIndex.Up, 0);
}
else
{
rawAnim.CrossFade(targetUpAnim, 0.1f, EAnimStateIndex.Up, 0);
}
currentUpAnim = targetUpAnim;
}
if (currentDownAnim != targetDownAnim)
{
// TODO: 下半身融合看着比较奇怪,暂时不用
if (currentDownAnim == null || noFade)
{
rawAnim.Play(targetDownAnim, EAnimStateIndex.Down, 0);
}
else
{
rawAnim.CrossFade(targetDownAnim, 0.05f, EAnimStateIndex.Down, 0);
}
currentDownAnim = targetDownAnim;
}
}
public float GetStateLength(string stateName,
int layerIndex)
{
var layer = _layerDict[layerIndex];
var stateInfo = layer.stateMap[stateName];
return stateInfo.clipLength;
}
//public void SetStateSpeed(string stateName, int layerIndex, float speed)
//{
// var layer = _layerDict[layerIndex];
// var stateInfo = layer.stateMap[stateName];
// stateInfo.rawState.speed = speed;
//}
}
}