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