2
0
Fork 0
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#

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