diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs index d12ee12..8eed250 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs @@ -20,6 +20,11 @@ public partial class Enemy : Role { /// + /// 目标是否在视野内 + /// + public bool TargetInView { get; set; } = true; + + /// /// 敌人身上的状态机控制器 /// public StateController StateController { get; private set; } @@ -59,6 +64,11 @@ /// public AiAttackState AttackState { get; private set; } + /// + /// Ai瞄准辅助线 + /// + public Line2D SubLine { get; private set; } + //锁定目标时间 private float _lockTargetTime = 0; @@ -95,6 +105,47 @@ //默认状态 StateController.ChangeStateInstant(AiStateEnum.AiNormal); + + InitSubLine(); + } + + /// + /// 初始化瞄准辅助线 + /// + public void InitSubLine() + { + if (SubLine != null) + { + return; + } + SubLine = new Line2D(); + SubLine.Width = 1; + SubLine.DefaultColor = Colors.Red; + AddChild(SubLine); + } + + /// + /// 更新瞄准辅助线信息, length 为辅助线长度 + /// + private void UpdateSubLine(float length) + { + var weapon = WeaponPack.ActiveItem; + var position = SubLine.ToLocal(weapon.FirePoint.GlobalPosition); + Vector2 position2; + if (Face == FaceDirection.Right) + { + position2 = Vector2.FromAngle(MountPoint.RealRotation) * length; + } + else + { + position2 = Vector2.FromAngle(Mathf.Pi - MountPoint.RealRotation) * length; + } + + SubLine.Points = new Vector2[] + { + position, + position + position2 + }; } public override void EnterTree() @@ -160,6 +211,26 @@ { _lockTargetTime = 0; } + + //更新瞄准辅助线 + if (AttackState == AiAttackState.LockingTime) + { + SubLine.Visible = true; + float len; + if (!TargetInView) + { + len = GlobalPosition.DistanceTo(ViewRay.GetCollisionPoint()); + } + else + { + len = 200; + } + UpdateSubLine(len); + } + else + { + SubLine.Visible = false; + } } else { @@ -171,7 +242,13 @@ _lockTargetTime = 0; } + //拾起武器操作 EnemyPickUpWeapon(); + // //更新瞄准辅助线 + // if (SubLine != null && SubLine.Visible && WeaponPack.ActiveItem != null) + // { + // UpdateSubLine(); + // } } protected override void OnHit(int damage, bool realHarm) diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs index 15c1933..50003ec 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs @@ -6,12 +6,6 @@ /// public class AiFollowUpState : StateBase { - - /// - /// 目标是否在视野内 - /// - public bool IsInView; - //导航目标点刷新计时器 private float _navigationUpdateTimer = 0; private float _navigationInterval = 0.3f; @@ -23,7 +17,7 @@ public override void Enter(AiStateEnum prev, params object[] args) { _navigationUpdateTimer = 0; - IsInView = true; + Master.TargetInView = true; } public override void Process(float delta) @@ -98,17 +92,17 @@ //检测玩家是否在视野内 if (Master.IsInTailAfterViewRange(playerPos)) { - IsInView = !Master.TestViewRayCast(playerPos); + Master.TargetInView = !Master.TestViewRayCast(playerPos); //关闭射线检测 Master.TestViewRayCastOver(); } else { - IsInView = false; + Master.TargetInView = false; } //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 - if (IsInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) + if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) { if (inAttackRange) //在攻击范围内 { diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs index 6d48ee4..321419f 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs @@ -6,11 +6,6 @@ /// public class AiSurroundState : StateBase { - /// - /// 目标是否在视野内 - /// - public bool IsInView = true; - //是否移动结束 private bool _isMoveOver; @@ -32,7 +27,7 @@ public override void Enter(AiStateEnum prev, params object[] args) { - IsInView = true; + Master.TargetInView = true; _isMoveOver = true; _pauseTimer = 0; _moveFlag = false; @@ -61,17 +56,17 @@ //检测玩家是否在视野内 if (Master.IsInTailAfterViewRange(playerPos)) { - IsInView = !Master.TestViewRayCast(playerPos); + Master.TargetInView = !Master.TestViewRayCast(playerPos); //关闭射线检测 Master.TestViewRayCastOver(); } else { - IsInView = false; + Master.TargetInView = false; } //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 - if (IsInView || + if (Master.TargetInView || (weapon != null && weapon.Attribute.AiAttackAttr.FiringStand && (Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) )) @@ -124,16 +119,17 @@ } else { + //判断开火状态, 进行移动 if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) - { + { //正常移动 //计算移动 var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); Master.AnimatedSprite.Play(AnimatorNames.Run); Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * Master.RoleState.MoveSpeed; } - else + else //站立不动 { Master.AnimatedSprite.Play(AnimatorNames.Idle); Master.BasisVelocity = Vector2.Zero; diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index ef8e123..aadd48b 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -154,6 +154,7 @@ /// 上一次触发改武器开火的触发开火攻击的层级, 数据源自于: /// public long TriggerRoleAttackLayer { get; private set; } + //-------------------------------------------------------------------------------------------- //用于记录是否有角色操作过这把武器 @@ -438,7 +439,6 @@ protected override void Process(float delta) { - //未开火时间 _noAttackTime += delta; @@ -1918,7 +1918,7 @@ } //-------------------------------- Ai相关 ----------------------------- - + /// /// Ai 调用, 刷新 Ai 攻击状态并返回, 并不会调用相应的函数 ///