using Entitas; using UnityEngine; using Game; public class MoveSystem : IExecuteSystem, IInitializeSystem { private IGroup _entities; public void Initialize() { _entities = Util.GetGroup(GameMatcher.Move); EventManager.Instance.AddEvent(EEvent.EntityMoveInput, OnEntityMove); } public void Execute() { //TODO 现在物理系统用unity原生的 foreach (var entity in _entities) { CheckHit(entity); //打射线 检查角色四周是否有阻挡 是否在地面 TurnUpdate(entity.move); //更新转向 ReboundWallUpdate(entity); //更新撞墙反弹 ReboundUpdate(entity); //更新落地反弹 } } private static void OnEntityMove(PEntityMoveInput param) { var entity = Util.GetEntity(param.EntityID); var move = entity.move; switch ((int)param.CommandType) { case (int)EMoveCommandType.Stop: move.IsWalk = false; break; case (int)EMoveCommandType.FunctionKey: HandleFunctionCommand(move, param.Command); break; case (int)EMoveCommandType.Move: HandleMoveCommand(move, param.Command); break; } } private static void HandleFunctionCommand(MoveComponent move, EMoveCommand command) { switch (command) { case EMoveCommand.Jump: move.IsJumpPressed = true; break; case EMoveCommand.JumpRelease: move.IsJumpPressed = false; break; } } private static void HandleMoveCommand(MoveComponent move, EMoveCommand command) { move.IsWalk = true; if (GameConst.MoveCommand2Dir.TryGetValue(command, out var moveDir)) { move.MoveDir = moveDir; if (moveDir == GameConst.Stop) { move.IsWalk = false; } } switch ((int)command) { case (int)EMoveCommand.Stop: case (int)EMoveCommand.Up: case (int)EMoveCommand.Down: break; default: if (move.IsFreeTurn) move.IsRight = move.MoveDir.x > 0; break; } } private static void TurnUpdate(MoveComponent move) { if (!move.MoveParam.NeedScale) return; move.TransformViewMain.localScale = new Vector3((move.IsRight ? 1f : -1f), 1, 1); } private static void ReboundUpdate(GameEntity entity) { var move = entity.move; if (!move.IsFlowing) return; if (!move.IsGround) return; var velocity = move.Velocity; if (velocity.y > 0) return; if (!entity.hasBuff) return; if (Util.HasSetSpeedBuff(entity.ID())) return; //强制位移途中不检测 if (Util.HasHitDownBuff(entity.ID())) { //触地反弹 Util.RemoveHitDownBuff(entity.ID()); move.Velocity = new Vector3(move.Velocity.x / 2, 6, move.Velocity.z / 2); move.Position = move.GroundPosition; if (entity.hasAnimation) { entity.animation.ReboundMsg = true; } //触地反弹特效 Util.CastGroundStaticEffect(GameConst.EffectHitGround1, entity.ID()); //卡帧 Util.EntityPause(entity, 0.05f); //抖动 Util.EntityShake(entity, 2); //缩放 Util.EntityScale(entity, Vector3.right * 6); } else { //落地 move.IsFlowing = false; //触地特效 Util.CastGroundStaticEffect(GameConst.EffectHitGround2, entity.ID()); Util.AddStaggerBuff(entity.ID(), 2f); //缩放 Util.EntityScale(entity, Vector3.right * 3); } } private static void ReboundWallUpdate(GameEntity entity) { var move = entity.move; if (!move.IsFlowing) return; if (!move.IsCrashToWall) return; if (!entity.hasBuff) return; if (Util.HasSetSpeedBuff(entity.ID())) { //撞墙反弹-大 Util.RemoveHitDownBuff(entity.ID()); Util.RemoveSetSpeedBuff(entity.ID()); //反弹方向xz沿CrashWallNormal,值为当前速度钳制[2,10] var speed = new Vector3(move.Velocity.x, 0, move.Velocity.z).magnitude; speed = Mathf.Clamp(speed, 2, 10); var velocity = move.CrashWallNormal * speed; move.Velocity = new Vector3(velocity.x, 6, velocity.z); if (entity.hasAnimation) { entity.animation.AirHitMsg = true; } //撞墙反弹特效 Util.CastWallStaticEffect(GameConst.EffectHitWall1, entity.ID(), move.CrashWallPosition, move.CrashWallNormal); //卡帧 Util.EntityPause(entity, 0.05f); //抖动 Util.EntityShake(entity, 2); //缩放 Util.EntityScale(entity, Vector3.up * 6); } else { //撞墙反弹-小 var speed = new Vector3(move.Velocity.x, 0, move.Velocity.z).magnitude; speed = Mathf.Clamp(speed, 2, 3); var velocity = move.CrashWallNormal * speed; move.Velocity = velocity; //撞墙特效 Util.CastWallStaticEffect(GameConst.EffectHitWall2, entity.ID(), move.CrashWallPosition, move.CrashWallNormal); //缩放 Util.EntityScale(entity, Vector3.up * 3); } } private static void CheckHit(GameEntity entity) { var move = entity.move; var view = entity.view; var bodySize = view.Collider.bounds.size; const float checkOffset = 0.1f; const float checkLength = 0.2f; //检查落地 var checkDir = Vector3.down; var startPos = move.Position + Vector3.up * checkOffset; move.IsGround = Physics.Raycast(startPos, checkDir, out var hitInfo, checkLength, UtilPhysics.LayerMaskDefault); move.IsGroundLogic = move.IsGround && move.JumpState == EJumpState.OnGround; if (move.IsGround) { move.GroundPosition = hitInfo.point; } Util.Draw(startPos, startPos + checkDir * checkLength, move.IsGround ? Color.red : Color.green); //检查移动贴墙 checkDir = move.MoveDir; startPos = move.Position + Vector3.up * bodySize.y / 2 + checkDir * (bodySize.x / 2 - checkOffset); move.IsAgainstWall = Physics.Raycast(startPos, checkDir, out hitInfo, checkLength, UtilPhysics.LayerMaskWall); Util.Draw(startPos, startPos + checkDir * checkLength, move.IsAgainstWall ? Color.red : Color.green); //检查冲撞贴墙 checkDir = move.Velocity.normalized; startPos = move.Position + Vector3.up * bodySize.y / 2 + checkDir * (bodySize.x / 2 - checkOffset); move.IsCrashToWall = Physics.Raycast(startPos, checkDir, out hitInfo, checkLength, UtilPhysics.LayerMaskWall); if (move.IsCrashToWall) { move.CrashWallPosition = hitInfo.point; move.CrashWallNormal = hitInfo.normal; } Util.Draw(startPos, startPos + checkDir * checkLength, move.IsCrashToWall ? Color.red : Color.green); } }