Files
Main/Assets/Code/Logic/_Required/Entity/Character/Player/PlayerMoveAnimModule.cs
2025-01-25 04:38:09 +08:00

199 lines
9.6 KiB
C#

using Thousandto.Code.Center;
using Thousandto.Core.Asset;
using UnityEngine;
using Thousandto.Cfg.Data;
namespace Thousandto.Code.Logic
{
//移动动作管理模块,用于管理玩家移动动作的切换
public class PlayerMoveAnimModule
{
#region//常量
private const float MountBaseAnimSpeed = 8.0f;
private const float BaseAnimSpeed = 5.0f;
private const float FastBaseAnimSpeed = 10f;
#endregion
#region//私有变量
private float _lastMoveSpeed = 0f; //上一帧的移动速度,用以检测移动速度改变
private bool _lastFightState = false; //上一帧的战斗状态,用以检测战斗状态改变
private Player _player = null;
private string _lastAnim = string.Empty;
#endregion
#region//公有函数
public void SetHostPlayer(Player player)
{
if (_player != player)
{
_lastMoveSpeed = 0f;
_lastFightState = false;
_player = player;
_lastAnim = string.Empty;
}
}
public void Update(Vector2 moveDir, bool isCrossFade = true)
{
float baseAnimSpeed = BaseAnimSpeed;
var curAnimName = AnimClipNameDefine.NormalRun;
var useCfgRun = false;
if(!_player.IsOnMount && !string.IsNullOrEmpty(_player.Scene.Cfg.RunAnim))
{
curAnimName = _player.Scene.Cfg.RunAnim;
useCfgRun = true;
}
var modelDir = moveDir;
var target = _player.GetCurSelectedTarget();
if (!_player.IsChangeModel && _player.AnimFightState && _player.IsXState(EntityStateID.DirMove) && target != null && _player.GetSqrDistance2d(target.Position2d) < 400f)
{
var tarDir = target.Position2d - _player.Position2d;
tarDir = tarDir.normalized;
var angle = VectorAngle(moveDir, tarDir);
//4方向
if ((angle >= 0 && angle <= 45f) || (angle <= 0 && angle >= -45f))
{
curAnimName = AnimClipNameDefine.FightRunFront;
modelDir = moveDir;
}
else if (angle >= 135f || angle <= -135)
{
curAnimName = AnimClipNameDefine.FightRunBack;
modelDir = -moveDir;
}
else if (angle >= 0f)
{
curAnimName = AnimClipNameDefine.FightRunLeft;
modelDir = tarDir;
}
else if (angle < 0f)
{
curAnimName = AnimClipNameDefine.FightRunRight;
modelDir = tarDir;
}
}
else if (_player.AnimFightState)
{
curAnimName = AnimClipNameDefine.FightRunFront;
}
else if (_player.IsXState(EntityStateID.DirMove) && _player.IsLocalPlayer())
{
var joyDir = GameCenter.InputSystem.JoystickHandler.CurWorldJoystickDir2d.normalized;
modelDir = joyDir;
}
if (!useCfgRun && !_player.AnimFightState && !_player.IsOnMount && !_player.IsChangeModel && _player.MoveSpeed >= 8f)
{
baseAnimSpeed = FastBaseAnimSpeed;
curAnimName = AnimClipNameDefine.FastRun;
}
_player.SetDirection2d(modelDir);
var animPlayer = _player.Skin.GetAnimationPlayer();
if (animPlayer == null)
return;
if (_lastMoveSpeed != _player.MoveSpeed || _lastFightState != _player.AnimFightState || _lastAnim != curAnimName || !animPlayer.IsLowerPlaying || !animPlayer.IsUPPlaying)
{
bool playSucc = false;
if (_player.IsOnMount)
{
var speedScale = _player.MoveSpeed / MountBaseAnimSpeed * _player.AnimSpeedScale * _player.MountAnimSpeed;
//Debug.LogFormat("yy speed scale:{0} movesped:{1} mountBaseSpeed:{2} animSpeedScale:{3} mountAnimSpeed:{4}", speedScale,_player.MoveSpeed,MountBaseAnimSpeed,_player.AnimSpeedScale,_player.MountAnimSpeed);
playSucc = _player.PlayAnim(AnimClipNameDefine.NormalRun, AnimationPartType.AllBody, WrapMode.Loop, isCrossFade, AnimationPlayer.DefaultCrossFadeTime, speedScale);
_lastMoveSpeed = _player.MoveSpeed;
_lastFightState = _player.AnimFightState;
}
else if (_player.IsChangeModel)
{
if (!_player.skillManager.IsSkillUseing())
{
var speedScale = _player.MoveSpeed / MountBaseAnimSpeed * _player.AnimSpeedScale;
playSucc = _player.PlayAnim(AnimClipNameDefine.NormalRun, AnimationPartType.AllBody, WrapMode.Loop, isCrossFade, AnimationPlayer.DefaultCrossFadeTime, speedScale);
}
_lastMoveSpeed = _player.MoveSpeed;
_lastFightState = _player.AnimFightState;
}
else
{
var speedScale = _player.MoveSpeed / baseAnimSpeed * _player.AnimSpeedScale;
float normalTime = 0f;
if (animPlayer.IsLowerPlaying && FPlayerAnimRelation.GetLogicType(animPlayer.LowerPart.CurState.ParentAnimName) == FAnimLogicType.Move)
{
normalTime = animPlayer.LowerPart.CurState.CurNormalizeTime;
}
if (!_player.AnimFightState)
{
//脱战了,直接播放跑步动作
if(_lastFightState != _player.AnimFightState)
{
//不进行动作融合防止收武器动作问题
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.AllBody, WrapMode.Loop, false, 0.2f, speedScale, normalTime);
}
else
{
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.AllBody, WrapMode.Loop, isCrossFade, 0.2f, speedScale, normalTime);
}
}
else if (animPlayer.IsUPPlaying && FPlayerAnimRelation.GetLogicType(animPlayer.UPPart.CurState.ParentAnimName) == FAnimLogicType.Skill
&& animPlayer.IsLowerPlaying && FPlayerAnimRelation.GetLogicType(animPlayer.LowerPart.CurState.ParentAnimName) == FAnimLogicType.Skill)
{
//如果上下半身都在播放技能,尝试切换到移动技能动作
string moveSkill = FPlayerAnimRelation.SkillIdleToMove(animPlayer.UPPart.CurState.ParentAnimName);
if (_player.CheckAnimValid(moveSkill, AnimationPartType.UpBody))
{
_player.PlayAnim(moveSkill, AnimationPartType.UpBody,
animPlayer.UPPart.CurState.WrapMode, isCrossFade, 0.2f,
animPlayer.UPPart.CurState.Speed,
animPlayer.UPPart.CurState.CurNormalizeTime);
//如果可以切换到移动技能动作,下半身播放移动动作
if (!animPlayer.IsLowerPlaying || animPlayer.LowerPart.CurState.ParentAnimName != curAnimName)
{
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.LowerBody, WrapMode.Loop, isCrossFade, 0.2f, speedScale, normalTime);
}
}
else if (!_player.skillManager.IsSkillUseing())
{
//如果正在播放技能收招动作,直接切换
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.AllBody, WrapMode.Loop, isCrossFade, 0.2f, speedScale, normalTime);
}
}
else if (animPlayer.IsUPPlaying && FPlayerAnimRelation.GetLogicType(animPlayer.UPPart.CurState.ParentAnimName) == FAnimLogicType.Skill)
{
//上半身在播放技能,下半身播放跑步动作
if (!animPlayer.IsLowerPlaying || animPlayer.LowerPart.CurState.ParentAnimName != curAnimName)
{
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.LowerBody, WrapMode.Loop, isCrossFade, 0.2f, speedScale, normalTime);
}
}
else
{
if (!_player.skillManager.IsSkillUseing())
{
playSucc = _player.PlayAnim(curAnimName, AnimationPartType.AllBody, WrapMode.Loop, isCrossFade, 0.2f, speedScale, normalTime);
}
}
_lastMoveSpeed = _player.MoveSpeed;
_lastFightState = _player.AnimFightState;
}
if (playSucc)
{
_lastAnim = curAnimName;
}
}
}
#endregion
#region//私有函数
private float VectorAngle(Vector2 from, Vector2 to)
{
float angle;
Vector3 cross = Vector3.Cross(from, to);
angle = Vector2.Angle(from, to);
return cross.z > 0 ? -angle : angle;
}
#endregion
}
}