diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/ActivityObjectTemplate.cs b/DungeonShooting_Godot/addons/dungeonShooting_plugin/ActivityObjectTemplate.cs
index 8ef405b..4f13314 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/ActivityObjectTemplate.cs
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/ActivityObjectTemplate.cs
@@ -35,6 +35,7 @@
public override void _Ready()
{
+#if TOOLS
// 在工具模式下创建的 template 节点自动创建对应的必要子节点
if (Engine.EditorHint)
{
@@ -127,6 +128,7 @@
}
}
}
+#endif
}
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
index f56c18f..1ebb968 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
@@ -50,5 +50,5 @@
}*/
}
-#endif
}
+#endif
diff --git a/DungeonShooting_Godot/export_presets.cfg b/DungeonShooting_Godot/export_presets.cfg
index b17065f..f80e572 100644
--- a/DungeonShooting_Godot/export_presets.cfg
+++ b/DungeonShooting_Godot/export_presets.cfg
@@ -1,72 +1,5 @@
[preset.0]
-name="UWP"
-platform="UWP"
-runnable=true
-custom_features=""
-export_filter="all_resources"
-include_filter=""
-exclude_filter=""
-export_path=""
-script_export_mode=1
-script_encryption_key=""
-
-[preset.0.options]
-
-custom_template/debug=""
-custom_template/release=""
-architecture/target=1
-command_line/extra_args=""
-package/display_name=""
-package/short_name=""
-package/unique_name=""
-package/description=""
-package/publisher=""
-package/publisher_display_name=""
-identity/product_guid=""
-identity/publisher_guid=""
-signing/certificate=""
-signing/password=""
-signing/algorithm=2
-version/major=1
-version/minor=0
-version/build=0
-version/revision=0
-orientation/landscape=true
-orientation/portrait=true
-orientation/landscape_flipped=true
-orientation/portrait_flipped=true
-images/background_color="transparent"
-tiles/show_name_on_square150x150=false
-tiles/show_name_on_wide310x150=false
-tiles/show_name_on_square310x310=false
-capabilities/allJoyn=false
-capabilities/codeGeneration=false
-capabilities/internetClient=false
-capabilities/internetClientServer=false
-capabilities/privateNetworkClientServer=false
-capabilities/appointments=false
-capabilities/blockedChatMessages=false
-capabilities/chat=false
-capabilities/contacts=false
-capabilities/enterpriseAuthentication=false
-capabilities/musicLibrary=false
-capabilities/objects3D=false
-capabilities/picturesLibrary=false
-capabilities/phoneCall=false
-capabilities/removableStorage=false
-capabilities/sharedUserCertificates=false
-capabilities/userAccountInformation=false
-capabilities/videosLibrary=false
-capabilities/voipCall=false
-capabilities/bluetooth=false
-capabilities/location=false
-capabilities/microphone=false
-capabilities/proximity=false
-capabilities/webcam=false
-
-[preset.1]
-
name="Android"
platform="Android"
runnable=true
@@ -78,7 +11,7 @@
script_export_mode=1
script_encryption_key=""
-[preset.1.options]
+[preset.0.options]
custom_template/debug=""
custom_template/release=""
@@ -271,7 +204,7 @@
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
-[preset.2]
+[preset.1]
name="Windows Desktop"
platform="Windows Desktop"
@@ -280,11 +213,11 @@
export_filter="all_resources"
include_filter=""
exclude_filter=""
-export_path=""
+export_path="../../export/test/test.exe"
script_export_mode=1
script_encryption_key=""
-[preset.2.options]
+[preset.1.options]
custom_template/debug=""
custom_template/release=""
@@ -314,7 +247,7 @@
application/copyright=""
application/trademarks=""
-[preset.3]
+[preset.2]
name="iOS"
platform="iOS"
@@ -327,7 +260,7 @@
script_export_mode=1
script_encryption_key=""
-[preset.3.options]
+[preset.2.options]
custom_template/debug=""
custom_template/release=""
diff --git a/DungeonShooting_Godot/prefab/role/Enemy.tscn b/DungeonShooting_Godot/prefab/role/Enemy.tscn
index ae7b5d5..39588f5 100644
--- a/DungeonShooting_Godot/prefab/role/Enemy.tscn
+++ b/DungeonShooting_Godot/prefab/role/Enemy.tscn
@@ -36,3 +36,5 @@
position = Vector2( 0, -5 )
[node name="NavigationAgent2D" type="NavigationAgent2D" parent="NavigationPoint" index="0"]
+avoidance_enabled = true
+radius = 20.0
diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs
index 7e59f96..ec25a87 100644
--- a/DungeonShooting_Godot/src/game/event/EventEnum.cs
+++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs
@@ -4,8 +4,5 @@
///
public enum EventEnum
{
- ///
- /// 敌人发现玩家
- ///
- OnEnemyFindPlayer,
+ Test,
}
diff --git a/DungeonShooting_Godot/src/game/role/Characters/CPlusPlus.cs b/DungeonShooting_Godot/src/game/role/Characters/CPlusPlus.cs
index 6b8a91d..b963240 100644
--- a/DungeonShooting_Godot/src/game/role/Characters/CPlusPlus.cs
+++ b/DungeonShooting_Godot/src/game/role/Characters/CPlusPlus.cs
@@ -14,7 +14,7 @@
// 每个角色都应该有对应的被动 属性 专属武器
#endregion
-public class CPlusPlus : Role
+public class CPlusPlus : Player
{
diff --git a/DungeonShooting_Godot/src/game/role/Player.cs b/DungeonShooting_Godot/src/game/role/Player.cs
index 19836f6..8f08799 100644
--- a/DungeonShooting_Godot/src/game/role/Player.cs
+++ b/DungeonShooting_Godot/src/game/role/Player.cs
@@ -1,8 +1,16 @@
using System.Collections.Generic;
using Godot;
+
+///
+/// 玩家角色基类, 所有角色都必须继承该类
+///
public class Player : Role
{
+ ///
+ /// 获取当前操作的角色
+ ///
+ public static Player Current => GameApplication.Instance.Room.Player;
///
/// 移动加速度
diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs
index 3d9a920..0d21d27 100644
--- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs
@@ -21,9 +21,14 @@
{
///
- /// 公共属性, 是否找到玩家, 如果找到玩家, 则所有敌人都会知道玩家的位置
+ /// 公共属性, 是否找到目标, 如果找到目标, 则所有敌人都会知道玩家的位置
///
- public static bool IsFindPlayer { get; set; }
+ public static bool IsFindTarget { get; private set; }
+
+ ///
+ /// 找到的目标的位置, 如果目标在视野内, 则一直更新
+ ///
+ public static Vector2 FindTargetPosition { get; private set; }
private static readonly List _enemies = new List();
@@ -63,7 +68,6 @@
public Position2D NavigationPoint { get; }
private float _enemyAttackTimer = 0;
- private EventBinder _eventBinder;
public Enemy() : base(ResourcePath.prefab_role_Enemy_tscn)
{
@@ -96,6 +100,9 @@
public override void _Ready()
{
base._Ready();
+ //防撞速度计算
+ NavigationAgent2D.Connect("velocity_computed", this, nameof(OnVelocityComputed));
+
//默认状态
StateController.ChangeState(AiStateEnum.AiNormal);
@@ -108,14 +115,11 @@
{
_enemies.Add(this);
}
- _eventBinder = EventManager.AddEventListener(EventEnum.OnEnemyFindPlayer, OnEnemyFindPlayer);
}
public override void _ExitTree()
{
_enemies.Remove(this);
- _eventBinder.RemoveEventListener();
- _eventBinder = null;
}
public override void _PhysicsProcess(float delta)
@@ -130,11 +134,15 @@
///
public static void UpdateEnemiesView()
{
+ IsFindTarget = false;
for (var i = 0; i < _enemies.Count; i++)
{
var enemy = _enemies[i];
-
- //enemy.StateController.GetState()
+ if (enemy.StateController.CurrState == AiStateEnum.AiTargetInView) //目标在视野内
+ {
+ IsFindTarget = true;
+ FindTargetPosition = Player.Current.GetCenterPosition();
+ }
}
}
@@ -213,15 +221,9 @@
{
ViewRay.Enabled = false;
}
-
- //其他敌人发现玩家
- private void OnEnemyFindPlayer(object obj)
+
+ private void OnVelocityComputed(Vector2 velocity)
{
- var state = StateController.CurrState;
- if (state != AiStateEnum.AiLeaveFor && state != AiStateEnum.AiTailAfter && state != AiStateEnum.AiTargetInView)
- {
- //前往指定地点
- StateController.ChangeStateLate(AiStateEnum.AiLeaveFor, GameApplication.Instance.Room.Player.GetCenterPosition());
- }
+ GD.Print("velocity: " + velocity);
}
}
diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs
index 6cb48a9..23cce4e 100644
--- a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs
+++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs
@@ -6,29 +6,46 @@
///
public class AiLeaveForState : StateBase
{
- private Vector2 _targetPosition;
-
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
public AiLeaveForState() : base(AiStateEnum.AiLeaveFor)
{
}
public override void Enter(AiStateEnum prev, params object[] args)
{
- if (args.Length > 0 && args[0] is Vector2 pos)
+ if (Enemy.IsFindTarget)
{
- UpdateTargetPosition(pos);
+ Master.NavigationAgent2D.SetTargetLocation(Enemy.FindTargetPosition);
}
else
{
- ChangeState(AiStateEnum.AiNormal);
+ ChangeStateLate(prev);
}
}
public override void PhysicsProcess(float delta)
{
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ if (Master.NavigationAgent2D.GetTargetLocation() != Enemy.FindTargetPosition)
+ {
+ Master.NavigationAgent2D.SetTargetLocation(Enemy.FindTargetPosition);
+ }
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
//计算移动
var nextPos = Master.NavigationAgent2D.GetNextLocation();
- Master.LookTargetPosition(_targetPosition);
+ Master.LookTargetPosition(Enemy.FindTargetPosition);
Master.AnimatedSprite.Animation = AnimatorNames.Run;
Master.Velocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
Master.MoveSpeed;
@@ -44,8 +61,6 @@
Master.TestViewRayCastOver();
//切换成发现目标状态
ChangeStateLate(AiStateEnum.AiTargetInView);
- //派发发现玩家事件
- EventManager.EmitEvent(EventEnum.OnEnemyFindPlayer);
return;
}
else
@@ -62,9 +77,8 @@
}
}
- public void UpdateTargetPosition(Vector2 pos)
+ public override void DebugDraw()
{
- _targetPosition = pos;
- Master.NavigationAgent2D.SetTargetLocation(pos);
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.GetTargetLocation()), Colors.Yellow);
}
}
diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs
index 9e51c18..3752b51 100644
--- a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs
+++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs
@@ -39,7 +39,13 @@
public override void PhysicsProcess(float delta)
{
-
+ //其他敌人发现玩家
+ if (Enemy.IsFindTarget)
+ {
+ ChangeStateLate(AiStateEnum.AiLeaveFor);
+ return;
+ }
+
if (_isFindPlayer) //已经找到玩家了
{
//现临时处理, 直接切换状态
diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs
index 9e610d1..ba9c11d 100644
--- a/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs
+++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs
@@ -7,4 +7,14 @@
public AiProbeState() : base(AiStateEnum.AiProbe)
{
}
+
+ public override void PhysicsProcess(float delta)
+ {
+ //其他敌人发现玩家
+ if (Enemy.IsFindTarget)
+ {
+ ChangeStateLate(AiStateEnum.AiLeaveFor);
+ return;
+ }
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs
index 1bd0e91..5e140d3 100644
--- a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs
+++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs
@@ -64,8 +64,6 @@
Master.TestViewRayCastOver();
//切换成发现目标状态
ChangeStateLate(AiStateEnum.AiTargetInView);
- //派发发现玩家事件
- EventManager.EmitEvent(EventEnum.OnEnemyFindPlayer);
return;
}
else
diff --git a/DungeonShooting_Godot/src/game/room/RoomManager.cs b/DungeonShooting_Godot/src/game/room/RoomManager.cs
index 9643006..8fca170 100644
--- a/DungeonShooting_Godot/src/game/room/RoomManager.cs
+++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs
@@ -11,7 +11,7 @@
///
/// 玩家对象
///
- public Role Player { get; private set; }
+ public Player Player { get; private set; }
///
/// 导航区域形状
@@ -112,6 +112,7 @@
public override void _Process(float delta)
{
+ Enemy.UpdateEnemiesView();
if (GameApplication.Instance.Debug)
{
Update();