You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			230 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			230 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C#
		
	
| using Entitas;
 | |
| using UnityEngine;
 | |
| using Game;
 | |
| 
 | |
| public class MoveSystem : IExecuteSystem, IInitializeSystem
 | |
| {
 | |
|     private IGroup<GameEntity> _entities;
 | |
| 
 | |
|     public void Initialize()
 | |
|     {
 | |
|         _entities = Util.GetGroup(GameMatcher.Move);
 | |
|         EventManager.Instance.AddEvent<PEntityMoveInput>(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);
 | |
|     }
 | |
| } |