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

317 lines
10 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;
namespace Gameplay.Character
{
public class CharacterAnim
{
public readonly Character owner;
public string targetDownAnim
{
get;
set;
}
public string targetFullAnim
{
get;
set;
}
public bool noFade = false;
public string currentDownAnim { get; private set; }
public string currentFullAnim { get; private set; }
public readonly Animator rawAnim;
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 _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 _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);
}
}
private float _splitScaleRaiseWeapon = 1;
public float splitScaleRaiseWeapon
{
get
{
return _splitScaleRaiseWeapon;
}
set
{
if (Math.Abs(_splitScaleRaiseWeapon - value) < 0.01f) return;
_splitScaleRaiseWeapon = value;
rawAnim.SetFloat(EAnimParamConst.RaiseWeaponScale, _splitScaleRaiseWeapon);
}
}
public float NORMAL_MOVESPEED = 3f;
public float NO_FIGHT_MOVESPEED = 3F;
public float LOW_MOVESPEED = 0.6f;
public CharacterAnim(Character owner)
{
this.owner = owner;
rawAnim = owner.RawAnimator;
}
public void ResetFloats()
{
rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
rawAnim.SetFloat(EAnimParamConst.MoveScaleNormal, _splitScaleNormalMove);
rawAnim.SetFloat(EAnimParamConst.MoveScaleLow, _splitScaleLowMove);
rawAnim.SetFloat(EAnimParamConst.RaiseWeaponScale, _splitScaleRaiseWeapon);
if (owner.weapon.weaponAnim != null && owner.weapon.weaponAnim.rawAnim != null)
{
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.AttackScaleNormal, _splitScaleNormalShoot);
owner.weapon.weaponAnim.rawAnim.SetFloat(EAnimParamConst.ReloadScaleNormal, _splitScaleNormalReload);
}
}
public async UniTask Init()
{
await _InitAnimInfo();
ResetAnim();
}
private async UniTask _InitAnimInfo()
{
_layerDict = new Dictionary<int, LTAnimLayerInfo>();
var nameId = owner.runtimeData.configData.nameId;
var weaponId = owner.runtimeData.configData.weaponId;
var fileName = nameId + "_" + weaponId;
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();
// ResetRaiseWeaponAnim();
ResetAttackEndAnim();
}
public void ResetAttackEndAnim()
{
var attackEndAnimLength = GetStateLength(EAnimFullState.S_ATTACK_END, EAnimStateIndex.Full);
var attackEndAnimTime = owner.fightData.attackEndTime;
var splitScaleAttackEnd = attackEndAnimLength / attackEndAnimTime;
rawAnim.SetFloat(EAnimParamConst.AttackEndScale, splitScaleAttackEnd);
}
public void ResetRaiseWeaponAnim()
{
var raiseTime = owner.runtimeData.fightData.raiseWeaponTime;
if (raiseTime <= 0)
{
DebugUtil.LogError("配置的 raiseWeaponTime 为 0, 请检查配置");
return;
}
var raiseAnimLength = GetStateLength(EAnimFullState.S_RAISE, EAnimStateIndex.Full);
splitScaleRaiseWeapon = raiseAnimLength / raiseTime;
}
public void ResetReloadAnim()
{
// reload时间
var reloadTime = owner.fightData.reloadTime;
if (reloadTime <= 0)
{
DebugUtil.LogError("配置的 reloadTime 为 0, 请检查配置");
return;
}
var reloadAnimLength = GetStateLength(EAnimFullState.S_RELOAD, EAnimStateIndex.Full);
splitScaleNormalReload = reloadAnimLength / reloadTime;
}
public void ResetShootAnim()
{
// 开枪时间
var shootTime = owner.fightData.shootCd;
if (shootTime <= 0)
{
DebugUtil.LogError("配置的 shootCd 为 0, 请检查配置");
return;
}
var shootAnimLength = GetStateLength(EAnimFullState.S_ATTACK, EAnimStateIndex.Full);
splitScaleNormalShoot = shootAnimLength / shootTime;
}
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 (currentFullAnim != targetFullAnim)
{
if (currentFullAnim == null || noFade)
{
rawAnim.Play(targetFullAnim, EAnimStateIndex.Full, 0);
}
else
{
rawAnim.Play(targetFullAnim, EAnimStateIndex.Full, 0);
// rawAnim.CrossFade(targetFullAnim, 0.1f, EAnimStateIndex.Full, 0);
}
currentFullAnim = targetFullAnim;
}
if (currentDownAnim != targetDownAnim)
{
// TODO: 下半身融合看着比较奇怪,暂时不用
if (currentDownAnim == null || noFade)
{
rawAnim.Play(targetDownAnim, EAnimStateIndex.Down, 0);
}
else
{
rawAnim.Play(targetDownAnim, EAnimStateIndex.Down, 0);
// rawAnim.CrossFade(targetDownAnim, 0.05f, EAnimStateIndex.Down, 0);
}
currentDownAnim = targetDownAnim;
}
}
public float GetStateLength(string stateName,
int layerIndex)
{
if (_layerDict.TryGetValue(layerIndex, out var layer))
{
if (layer.stateMap.TryGetValue(stateName, out var stateInfo))
{
return stateInfo.clipLength;
}
}
DebugUtil.LogError("GetStateLength failed: {0} {1}", stateName, layerIndex);
return 0;
}
//public void SetStateSpeed(string stateName, int layerIndex, float speed)
//{
// var layer = _layerDict[layerIndex];
// var stateInfo = layer.stateMap[stateName];
// stateInfo.rawState.speed = speed;
//}
}
}