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 } }