diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002.png b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002.png
index 8d930ae..0f1a4ed 100644
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002.png
+++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_idle.png b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_idle.png
index cd69636..5c65a43 100644
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_idle.png
+++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_idle.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_run.png b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_run.png
index eec38ac..c8dc00b 100644
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_run.png
+++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_run.png
Binary files differ
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs
index be5d336..05dbbc5 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs
@@ -10,6 +10,10 @@
// ///
// AiProbe,
///
+ /// 找到玩家,准备通知其他敌人
+ ///
+ AiFind,
+ ///
/// 收到其他敌人通知, 前往发现目标的位置
///
AiLeaveFor,
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
index f80fe8d..46b5c5c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
@@ -65,7 +65,7 @@
public Marker2D NavigationPoint { get; private set; }
///
- /// Ai攻击状态, 调用 EnemyAttack() 函数后会刷新
+ /// Ai攻击状态, 调用 Attack() 函数后会刷新
///
public AiAttackState AttackState { get; private set; }
@@ -354,10 +354,7 @@
return false;
}
- ///
- /// Ai触发的攻击
- ///
- public void EnemyAttack()
+ public override void Attack()
{
var weapon = WeaponPack.ActiveItem;
if (weapon != null)
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
index f1f7d3b..a27cedc 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
@@ -51,6 +51,11 @@
[Export, ExportFillNode]
public Marker2D NavigationPoint { get; private set; }
+ ///
+ /// Ai攻击状态, 调用 Attack() 函数后会刷新
+ ///
+ public AiAttackState AttackState { get; private set; }
+
//锁定目标时间
private float _lockTargetTime = 0;
@@ -70,6 +75,8 @@
Hp = 20;
StateController.Register(new AiNormalState());
+ StateController.Register(new AiTailAfterState());
+ StateController.Register(new AiFollowUpState());
StateController.ChangeState(AiStateEnum.AiNormal);
}
@@ -85,4 +92,140 @@
{
World.Enemy_InstanceList.Remove(this);
}
+
+ public override void Attack()
+ {
+ Debug.Log("触发攻击");
+ }
+
+ protected override void OnHit(int damage, bool realHarm)
+ {
+ //受到伤害
+ var state = StateController.CurrState;
+ if (state == AiStateEnum.AiNormal || state == AiStateEnum.AiLeaveFor) //|| state == AiStateEnum.AiProbe
+ {
+ StateController.ChangeState(AiStateEnum.AiTailAfter);
+ }
+ }
+
+ protected override void OnDie()
+ {
+ var effPos = Position + new Vector2(0, -Altitude);
+ //血液特效
+ var blood = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_enemy_EnemyBloodEffect_tscn);
+ blood.Position = effPos - new Vector2(0, 12);
+ blood.AddToActivityRoot(RoomLayerEnum.NormalLayer);
+ blood.PlayEffect();
+
+ //创建敌人碎片
+ var count = Utils.Random.RandomRangeInt(3, 6);
+ for (var i = 0; i < count; i++)
+ {
+ var debris = Create(Ids.Id_effect0001);
+ debris.PutDown(effPos, RoomLayerEnum.NormalLayer);
+ debris.InheritVelocity(this);
+ }
+
+ //派发敌人死亡信号
+ EventManager.EmitEvent(EventEnum.OnEnemyDie, this);
+ Destroy();
+ }
+
+ ///
+ /// 检查是否能切换到 AiStateEnum.AiLeaveFor 状态
+ ///
+ public bool CanChangeLeaveFor()
+ {
+ if (!World.Enemy_IsFindTarget)
+ {
+ return false;
+ }
+
+ var currState = StateController.CurrState;
+ if (currState == AiStateEnum.AiNormal)// || currState == AiStateEnum.AiProbe)
+ {
+ //判断是否在同一个房间内
+ return World.Enemy_FindTargetAffiliationSet.Contains(AffiliationArea);
+ }
+
+ return false;
+ }
+
+ ///
+ /// 返回目标点是否在视野范围内
+ ///
+ public bool IsInViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= ViewRange * ViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 返回目标点是否在跟随状态下的视野半径内
+ ///
+ public bool IsInTailAfterViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= TailAfterViewRange * TailAfterViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回被挡住视野的物体对象, 视野无阻则返回 null
+ ///
+ public bool TestViewRayCast(Vector2 target)
+ {
+ ViewRay.Enabled = true;
+ ViewRay.TargetPosition = ViewRay.ToLocal(target);
+ ViewRay.ForceRaycastUpdate();
+ return ViewRay.IsColliding();
+ }
+
+ ///
+ /// 调用视野检测完毕后, 需要调用 TestViewRayCastOver() 来关闭视野检测射线
+ ///
+ public void TestViewRayCastOver()
+ {
+ ViewRay.Enabled = false;
+ }
+
+ ///
+ /// 获取锁定目标的时间
+ ///
+ public float GetLockTime()
+ {
+ return _lockTargetTime;
+ }
+
+ ///
+ /// 强制设置锁定目标时间
+ ///
+ public void SetLockTargetTime(float time)
+ {
+ _lockTargetTime = time;
+ }
+
+ ///
+ /// 获取攻击范围
+ ///
+ /// 从最小到最大距离的过渡量, 0 - 1, 默认 0.5
+ public float GetAttackRange(float weight = 0.5f)
+ {
+ return 200;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
index f635a9d..904b327 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs
@@ -109,7 +109,7 @@
if (inAttackRange) //在攻击范围内
{
//发起攻击
- Master.EnemyAttack();
+ Master.Attack();
//距离够近, 可以切换到环绕模式
if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange), 2) * 0.7f)
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs
index 77cf398..5f469d1 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs
@@ -11,7 +11,7 @@
//是否发现玩家
private bool _isFindPlayer;
- //下一个运动的角度
+ //下一个运动的坐标
private Vector2 _nextPos;
//是否移动结束
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
index a7b2fe4..39cdf6c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs
@@ -158,7 +158,7 @@
else
{
//发起攻击
- Master.EnemyAttack();
+ Master.Attack();
}
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs
new file mode 100644
index 0000000..35c2caa
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs
@@ -0,0 +1,108 @@
+
+using Godot;
+
+namespace NnormalState;
+
+///
+/// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火
+///
+public class AiFollowUpState : StateBase
+{
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ public AiFollowUpState() : base(AiStateEnum.AiFollowUp)
+ {
+ }
+
+ public override void Enter(AiStateEnum prev, params object[] args)
+ {
+ _navigationUpdateTimer = 0;
+ Master.TargetInView = true;
+ }
+
+ public override void Process(float delta)
+ {
+ var playerPos = Player.Current.GetCenterPosition();
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ Master.NavigationAgent2D.TargetPosition = playerPos;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ var masterPosition = Master.GlobalPosition;
+
+ //是否在攻击范围内
+ var inAttackRange = masterPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Master.GetAttackRange(0.7f), 2);
+
+ //枪口指向玩家
+ Master.LookTargetPosition(playerPos);
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)
+ {
+ //计算移动
+ var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
+ Master.AnimatedSprite.Play(AnimatorNames.Run);
+ Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() *
+ Master.RoleState.MoveSpeed;
+ }
+ else
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ }
+ else
+ {
+ Master.BasisVelocity = Vector2.Zero;
+ }
+
+ //检测玩家是否在视野内
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ Master.TargetInView = !Master.TestViewRayCast(playerPos);
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ else
+ {
+ Master.TargetInView = false;
+ }
+
+ //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
+ if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
+ {
+ if (inAttackRange) //在攻击范围内
+ {
+ //发起攻击
+ Master.Attack();
+
+ //距离够近, 可以切换到环绕模式
+ // if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange), 2) * 0.7f)
+ // {
+ // ChangeState(AiStateEnum.AiSurround);
+ // }
+ }
+ }
+ else //不在视野中
+ {
+ ChangeState(AiStateEnum.AiTailAfter);
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ var playerPos = Player.Current.GetCenterPosition();
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Red);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
index 0cdef1d..9cf340a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs
@@ -1,17 +1,177 @@
-namespace NnormalState;
+using Godot;
+
+namespace NnormalState;
///
/// AI 正常状态
///
public class AiNormalState : StateBase
{
+ //是否发现玩家
+ private bool _isFindPlayer;
+
+ //下一个运动的坐标
+ private Vector2 _nextPos;
+
+ //是否移动结束
+ private bool _isMoveOver;
+
+ //上一次移动是否撞墙
+ private bool _againstWall;
+
+ //撞墙法线角度
+ private float _againstWallNormalAngle;
+
+ //移动停顿计时器
+ private float _pauseTimer;
+ private bool _moveFlag;
+
+ //上一帧位置
+ private Vector2 _prevPos;
+ //卡在一个位置的时间
+ private float _lockTimer;
+
public AiNormalState() : base(AiStateEnum.AiNormal)
{
-
+ }
+
+ public override void Enter(AiStateEnum prev, params object[] args)
+ {
+ _isFindPlayer = false;
+ _isMoveOver = true;
+ _againstWall = false;
+ _againstWallNormalAngle = 0;
+ _pauseTimer = 0;
+ _moveFlag = false;
}
public override void Process(float delta)
{
- //Master.BasisVelocity = (Player.Current.Position - Master.Position).LimitLength(10);
+ //其他敌人发现玩家
+ if (Master.CanChangeLeaveFor())
+ {
+ ChangeState(AiStateEnum.AiLeaveFor);
+ return;
+ }
+
+ if (_isFindPlayer) //已经找到玩家了
+ {
+ //现临时处理, 直接切换状态
+ ChangeState(AiStateEnum.AiTailAfter);
+ }
+ else //没有找到玩家
+ {
+ //检测玩家
+ var player = Player.Current;
+ //玩家中心点坐标
+ var playerPos = player.GetCenterPosition();
+
+ if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
+ {
+ //发现玩家
+ _isFindPlayer = true;
+ }
+ else if (_pauseTimer >= 0)
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ _pauseTimer -= delta;
+ }
+ else if (_isMoveOver) //没发现玩家, 且已经移动完成
+ {
+ RunOver();
+ _isMoveOver = false;
+ }
+ else //移动中
+ {
+ if (_lockTimer >= 1) //卡在一个点超过一秒
+ {
+ RunOver();
+ _isMoveOver = false;
+ _lockTimer = 0;
+ }
+ else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0.3f, 2f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ else if (!_moveFlag)
+ {
+ _moveFlag = true;
+ var pos = Master.GlobalPosition;
+ //计算移动
+ var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
+ Master.AnimatedSprite.Play(AnimatorNames.Run);
+ Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
+ Master.RoleState.MoveSpeed;
+ _prevPos = pos;
+ }
+ else
+ {
+ var pos = Master.GlobalPosition;
+ var lastSlideCollision = Master.GetLastSlideCollision();
+ if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ else
+ {
+ //计算移动
+ var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
+ Master.AnimatedSprite.Play(AnimatorNames.Run);
+ Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() *
+ Master.RoleState.MoveSpeed;
+ }
+
+ if (_prevPos.DistanceSquaredTo(pos) <= 0.01f)
+ {
+ _lockTimer += delta;
+ }
+ else
+ {
+ _prevPos = pos;
+ }
+ }
+ }
+
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ }
+
+ //移动结束
+ private void RunOver()
+ {
+ float angle;
+ if (_againstWall)
+ {
+ angle = Utils.Random.RandomRangeFloat(_againstWallNormalAngle - Mathf.Pi * 0.5f,
+ _againstWallNormalAngle + Mathf.Pi * 0.5f);
+ }
+ else
+ {
+ angle = Utils.Random.RandomRangeFloat(0, Mathf.Pi * 2f);
+ }
+
+ var len = Utils.Random.RandomRangeInt(30, 200);
+ _nextPos = new Vector2(len, 0).Rotated(angle) + Master.GlobalPosition;
+ //获取射线碰到的坐标
+ if (Master.TestViewRayCast(_nextPos)) //碰到墙壁
+ {
+ _nextPos = Master.ViewRay.GetCollisionPoint();
+ _againstWall = true;
+ _againstWallNormalAngle = Master.ViewRay.GetCollisionNormal().Angle();
+ }
+ else
+ {
+ _againstWall = false;
+ }
+
+ Master.NavigationAgent2D.TargetPosition = _nextPos;
+ Master.LookTargetPosition(_nextPos);
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs
new file mode 100644
index 0000000..3d29972
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs
@@ -0,0 +1,124 @@
+
+using Godot;
+
+namespace NnormalState;
+
+///
+/// AI 发现玩家, 跟随玩家
+///
+public class AiTailAfterState : StateBase
+{
+ ///
+ /// 目标是否在视野半径内
+ ///
+ private bool _isInViewRange;
+
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ //目标从视野消失时已经过去的时间
+ private float _viewTimer;
+
+ public AiTailAfterState() : base(AiStateEnum.AiTailAfter)
+ {
+ }
+
+ public override void Enter(AiStateEnum prev, params object[] args)
+ {
+ _isInViewRange = true;
+ _navigationUpdateTimer = 0;
+ _viewTimer = 0;
+ }
+
+ public override void Process(float delta)
+ {
+ //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
+
+ var playerPos = Player.Current.GetCenterPosition();
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ Master.NavigationAgent2D.TargetPosition = playerPos;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ //枪口指向玩家
+ Master.LookTargetPosition(playerPos);
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)
+ {
+ //计算移动
+ var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
+ Master.AnimatedSprite.Play(AnimatorNames.Run);
+ Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
+ Master.RoleState.MoveSpeed;
+ }
+ else
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ }
+ else
+ {
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ if (!Master.TestViewRayCast(playerPos)) //看到玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //切换成发现目标状态
+ ChangeState(AiStateEnum.AiFollowUp);
+ return;
+ }
+ else
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ }
+
+ //检测玩家是否在穿墙视野范围内, 直接检测距离即可
+ _isInViewRange = Master.IsInViewRange(playerPos);
+ if (_isInViewRange)
+ {
+ _viewTimer = 0;
+ }
+ else //超出视野
+ {
+ if (_viewTimer > 10) //10秒
+ {
+ ChangeState(AiStateEnum.AiNormal);
+ }
+ else
+ {
+ _viewTimer += delta;
+ }
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ var playerPos = Player.Current.GetCenterPosition();
+ if (_isInViewRange)
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Orange);
+ }
+ else
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Blue);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs
index 6a64560..28dd63a 100644
--- a/DungeonShooting_Godot/src/game/event/EventEnum.cs
+++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs
@@ -7,7 +7,7 @@
public enum EventEnum
{
///
- /// 敌人死亡, 参数为死亡的敌人的实例, 参数类型为
+ /// 敌人死亡, 参数为死亡的敌人的实例, 参数类型为
///
OnEnemyDie,
///