using Entitas; using UnityEngine; using Game; public class MoveSystemFixed : IExecuteSystem, IInitializeSystem { private IGroup _entities; public void Initialize() { _entities = Util.GetGroup(GameMatcher.Move); } public void Execute() { foreach (var entity in _entities) { if (Util.IsPause(entity)) { continue; } var move = entity.move; GravityUpdate(entity.move); if (!Util.EntityIsStagger(entity)) //硬直状态无法主动移动和跳跃 { if (move.StepType == EMovestepType.None) { JumpUpdate(move); //更新跳跃 } var timelineRunning = entity.hasTimeline && entity.timeline.IsRunning; if (!timelineRunning || move.IsSlide) MoveUpdate(move); //更新移动 } if (move.StepType != EMovestepType.None && entity.hasSkill) { SkillMoveUpdate(entity); //更新技能位移 } if (!(move.StepType == EMovestepType.SetSpeed || move.MoveDir.magnitude == 0)) SpeedLimit(move); //速度限制 FallUpdate(move); //下落 } } private void MoveUpdate(MoveComponent move) { if (move.IsWalk && !move.IsAgainstWall) { move.Rigidbody.AddForce(move.MoveDir * move.MoveParam.MoveForce); } } private void SkillMoveUpdate(GameEntity entity) { var move = entity.move; var skillCastDir = entity.skill.CastDir; var adjustAngel = move.IsRight ? 0f : 180f; if (skillCastDir.x != 0 || skillCastDir.z != 0) { adjustAngel = Vector3.Angle(Vector3.right, new Vector3(skillCastDir.x, 0, skillCastDir.z)); adjustAngel *= skillCastDir.z > 0 ? -1 : 1; } var moveValue = Quaternion.AngleAxis(adjustAngel, Vector3.up) * move.StepValue; switch ((int)move.StepType) { case (int)EMovestepType.AddForce: move.Rigidbody.AddForce(moveValue * (1 + move.TempMoveForceScale)); break; case (int)EMovestepType.SetSpeed: move.Rigidbody.velocity = moveValue; break; } } private void SpeedLimit(MoveComponent move) { var speedXZ = new Vector3(move.Velocity.x, 0, move.Velocity.z); var speedXMax = move.MoveParam.MoveSpeedMax * (1 + move.MoveSpeedScale); if (!move.IsGround) { speedXMax *= move.MoveParam.AirSpeedMaxRate; } if (speedXZ.magnitude > speedXMax) { var speedXMaxVec = speedXZ.normalized * speedXMax; move.Velocity = new Vector3(speedXMaxVec.x, move.Velocity.y, speedXMaxVec.z); } } private void GravityUpdate(MoveComponent move) { var mass = move.Rigidbody.mass; var force = Vector3.down * move.MoveParam.Gravity * 10f * mass; move.Rigidbody.AddForce(force); } private void FallUpdate(MoveComponent move) { if (!move.IsGround && move.Velocity.y < 0) { var mass = move.Rigidbody.mass; var force = Vector3.down * move.MoveParam.FallForce * mass; move.Rigidbody.AddForce(force); } if (move.Position.y < 0) { move.Position = new Vector3(move.Position.x, 0, move.Position.z); } } private void JumpUpdate(MoveComponent move) { var addForce = false; var dt = Time.fixedDeltaTime; var forceScale = 1f; move.IsSkillAble = true; switch ((int)move.JumpState) { case (int)EJumpState.OnGround: move.Rigidbody.drag = move.MoveParam.GroundDrag; if (move.IsJumpCommand) { move.JumpTimeNow += dt; addForce = true; move.JumpState = EJumpState.LeavingGround; } if (!move.IsGround) { move.JumpState = EJumpState.InAir; } break; case (int)EJumpState.LeavingGround: addForce = true; move.Rigidbody.drag = move.MoveParam.AirDrag; move.IsSkillAble = false; if (!move.IsGround) { move.JumpState = EJumpState.InAir; } break; case (int)EJumpState.InAir: move.Rigidbody.drag = move.MoveParam.AirDrag; if (!move.IsJumpPressed) { move.IsJumpCommand = false; } if (move.IsJumpCommand) { var jumpTimeNow = move.JumpTimeNow + dt; var isMinJump = jumpTimeNow <= move.MoveParam.JumpTimeMin; var isMaxJump = jumpTimeNow >= move.MoveParam.JumpTimeMax && move.IsJumpPressed; if (isMinJump) { move.IsSkillAble = false; } if (isMinJump || isMaxJump) { move.JumpTimeNow = jumpTimeNow; addForce = true; } if (isMaxJump) { var addForceTimeLeft = move.MoveParam.JumpTimeMax - jumpTimeNow; forceScale = addForceTimeLeft / dt; forceScale = Mathf.Min(forceScale, 1); } } if (move.IsGround) { move.JumpTimeNow = 0; move.IsJumpCommand = false; move.Velocity = new Vector2(move.Velocity.x, 0); move.Position = move.GroundPosition; move.JumpState = EJumpState.OnGround; } break; } var velocity = move.Velocity; if (addForce) { move.Velocity = new Vector3(velocity.x, move.MoveParam.JumpForce * forceScale, velocity.z); } } }