diff --git a/prefab/roomTemplates/dungeon/chest.tscn b/prefab/roomTemplates/dungeon/chest.tscn
index b728ccd..2206510 100644
--- a/prefab/roomTemplates/dungeon/chest.tscn
+++ b/prefab/roomTemplates/dungeon/chest.tscn
@@ -55,7 +55,6 @@ shape = SubResource("RectangleShape2D_7tsse")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(260, 87)
script = ExtResource("1_y2vgj")
-ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_rh1gx")
diff --git a/prefab/roomTemplates/dungeon/horizontalCorridor.tscn b/prefab/roomTemplates/dungeon/horizontalCorridor.tscn
index ae366e1..454d1f1 100644
--- a/prefab/roomTemplates/dungeon/horizontalCorridor.tscn
+++ b/prefab/roomTemplates/dungeon/horizontalCorridor.tscn
@@ -54,7 +54,6 @@ shape = SubResource("RectangleShape2D_7tsse")
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(260, 87)
script = ExtResource("2_wamhd")
-ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_rh1gx")
diff --git a/prefab/roomTemplates/tutorials/spellEditor.tscn b/prefab/roomTemplates/tutorials/spellEditor.tscn
index fead826..b4880fc 100644
--- a/prefab/roomTemplates/tutorials/spellEditor.tscn
+++ b/prefab/roomTemplates/tutorials/spellEditor.tscn
@@ -37,7 +37,7 @@ position = Vector2(751.5, 289.438)
shape = SubResource("RectangleShape2D_jxmys")
debug_color = Color(0, 0.6, 0.701961, 0.419608)
-[node name="Marker2D" type="Marker2D" parent="."]
+[node name="PlayerSpawn" type="Marker2D" parent="."]
position = Vector2(54, 256)
script = ExtResource("1_q04qt")
@@ -73,16 +73,6 @@ position = Vector2(386, 178)
scale = Vector2(23.9375, 11.0625)
texture = ExtResource("3_atgj7")
-[node name="Marker2D2" type="Marker2D" parent="."]
-position = Vector2(100, 250)
-script = ExtResource("4_6ihp7")
-ItemId = "staff_necromancy"
-
-[node name="Marker2D3" type="Marker2D" parent="."]
-position = Vector2(134, 248)
-script = ExtResource("4_6ihp7")
-ItemId = "necromancy"
-
[node name="Label" type="Label" parent="."]
offset_left = 37.0
offset_top = 46.0
@@ -115,3 +105,15 @@ position = Vector2(715, 162)
[node name="WoodenBox4" parent="." instance=ExtResource("7_jybe6")]
position = Vector2(714, 122)
+
+[node name="AutoSpawn" type="Node2D" parent="."]
+
+[node name="necromancy" type="Marker2D" parent="AutoSpawn"]
+position = Vector2(134, 248)
+script = ExtResource("4_6ihp7")
+ItemId = "necromancy"
+
+[node name="staff_necromancy" type="Marker2D" parent="AutoSpawn"]
+position = Vector2(100, 250)
+script = ExtResource("4_6ihp7")
+ItemId = "staff_necromancy"
diff --git a/prefab/roomTemplates/tutorials/tripleShotSpell.tscn b/prefab/roomTemplates/tutorials/tripleShotSpell.tscn
index a340d0a..db85fef 100644
--- a/prefab/roomTemplates/tutorials/tripleShotSpell.tscn
+++ b/prefab/roomTemplates/tutorials/tripleShotSpell.tscn
@@ -91,11 +91,6 @@ offset_right = 453.0
offset_bottom = 151.0
text = "ui_tutorial_combine_more_powerful_spells"
-[node name="Marker2D" type="Marker2D" parent="."]
-position = Vector2(434, 105)
-script = ExtResource("4_fh50l")
-ItemId = "x3"
-
[node name="WoodenBox" parent="." instance=ExtResource("4_60glh")]
position = Vector2(711, 179)
@@ -129,3 +124,10 @@ position = Vector2(473, 285)
[node name="TripleShotSpell" type="Sprite2D" parent="."]
position = Vector2(637, 85)
texture = ExtResource("6_2qcf3")
+
+[node name="AutoSpawn" type="Node2D" parent="."]
+
+[node name="x3" type="Marker2D" parent="AutoSpawn"]
+position = Vector2(434, 105)
+script = ExtResource("4_fh50l")
+ItemId = "x3"
diff --git a/scripts/EventBus.cs b/scripts/EventBus.cs
index ab0e9fb..46da7a6 100644
--- a/scripts/EventBus.cs
+++ b/scripts/EventBus.cs
@@ -9,12 +9,6 @@ namespace ColdMint.scripts;
///
public static class EventBus
{
- ///
- /// Event when the AI character is generated
- /// AI角色生成事件
- ///
- public static Action? AiCharacterGenerateEvent;
-
///
/// Game Over Event
/// 游戏结束事件
diff --git a/scripts/map/AiCharacterSpawn.cs b/scripts/map/AiCharacterSpawn.cs
index 846b42e..3e6548d 100644
--- a/scripts/map/AiCharacterSpawn.cs
+++ b/scripts/map/AiCharacterSpawn.cs
@@ -1,5 +1,5 @@
using ColdMint.scripts.character;
-using ColdMint.scripts.map.events;
+using ColdMint.scripts.map.room;
using ColdMint.scripts.utils;
using Godot;
@@ -9,52 +9,45 @@ namespace ColdMint.scripts.map;
/// Ai character generation point
/// Ai角色生成点
///
-public partial class AiCharacterSpawn : Marker2D
+public partial class AiCharacterSpawn : Marker2D, ISpawnMarker
{
private PackedScene? _packedScene;
- [Export]
- public string? ResPath;
+ [Export] private string? _resPath;
public override void _Ready()
{
base._Ready();
- if (!string.IsNullOrEmpty(ResPath))
+ if (!string.IsNullOrEmpty(_resPath))
{
- _packedScene = GD.Load(ResPath);
+ _packedScene = GD.Load(_resPath);
}
-
- EventBus.AiCharacterGenerateEvent += OnAiCharacterGenerateEvent;
}
- ///
- /// When an event is triggered
- /// 当触发事件时
- ///
- ///
- public void OnAiCharacterGenerateEvent(AiCharacterGenerateEvent aiCharacterGenerateEvent)
+ public Node2D? Spawn()
{
- if (GameSceneDepend.AiCharacterContainer == null)
+ if (GameSceneDepend.AiCharacterContainer == null || _packedScene == null)
{
- return;
- }
-
- if (_packedScene == null)
- {
- return;
+ return null;
}
var aiCharacter = NodeUtils.InstantiatePackedScene(_packedScene);
if (aiCharacter == null)
{
- return;
+ return null;
}
NodeUtils.CallDeferredAddChild(GameSceneDepend.AiCharacterContainer, aiCharacter);
aiCharacter.GlobalPosition = GlobalPosition;
+ return aiCharacter;
}
- public override void _ExitTree()
+ public bool CanQueueFree()
{
- EventBus.AiCharacterGenerateEvent -= OnAiCharacterGenerateEvent;
+ return true;
+ }
+
+ public void DoQueueFree()
+ {
+ QueueFree();
}
}
\ No newline at end of file
diff --git a/scripts/map/ItemSpawn.cs b/scripts/map/ItemSpawn.cs
index 15c6495..a99008d 100644
--- a/scripts/map/ItemSpawn.cs
+++ b/scripts/map/ItemSpawn.cs
@@ -1,6 +1,6 @@
using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
-using ColdMint.scripts.map.events;
+using ColdMint.scripts.map.room;
using Godot;
namespace ColdMint.scripts.map;
@@ -9,36 +9,34 @@ namespace ColdMint.scripts.map;
/// ItemSpawn
/// 物品出生点
///
-public partial class ItemSpawn : Marker2D
+public partial class ItemSpawn : Marker2D, ISpawnMarker
{
- [Export] public string? ItemId { get; private set; }
+ [Export] private string? ItemId { get; set; }
- public override void _Ready()
+ public Node2D? Spawn()
{
- base._Ready();
- EventBus.MapGenerationCompleteEvent += MapGenerationCompleteEvent;
- }
-
- private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
- {
- //After the map is generated, create the item instance.
- //当地图生成完成后,创建物品实例。
- if (ItemId == null)
+ if (string.IsNullOrEmpty(ItemId))
{
- return;
+ return null;
}
var item = ItemTypeManager.CreateItem(ItemId, this);
- LogCat.LogWithFormat("generated_item_is_empty",LogCat.LogLabel.ItemSpawn,true,ItemId,item == null);
- if (item is Node2D node2D)
+ LogCat.LogWithFormat("generated_item_is_empty", LogCat.LogLabel.ItemSpawn, true, ItemId, item == null);
+ if (item is not Node2D node2D)
{
- node2D.GlobalPosition = GlobalPosition;
+ return null;
}
+ node2D.GlobalPosition = GlobalPosition;
+ return node2D;
}
- public override void _ExitTree()
+ public bool CanQueueFree()
{
- base._ExitTree();
- EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
+ return true;
+ }
+
+ public void DoQueueFree()
+ {
+ QueueFree();
}
}
\ No newline at end of file
diff --git a/scripts/map/MapGenerator.cs b/scripts/map/MapGenerator.cs
index 116a8bb..89247e9 100644
--- a/scripts/map/MapGenerator.cs
+++ b/scripts/map/MapGenerator.cs
@@ -311,11 +311,6 @@ public static class MapGenerator
RoomDictionary = roomDictionary
};
EventBus.MapGenerationCompleteEvent?.Invoke(eventObj);
- var aiCharacterGenerateEvent = new AiCharacterGenerateEvent
- {
- Tag = AiCharacterGenerateEvent.TagMapGenerationComplete
- };
- EventBus.AiCharacterGenerateEvent?.Invoke(aiCharacterGenerateEvent);
}
diff --git a/scripts/map/PlayerSpawn.cs b/scripts/map/PlayerSpawn.cs
index beaed5b..cbb76f8 100644
--- a/scripts/map/PlayerSpawn.cs
+++ b/scripts/map/PlayerSpawn.cs
@@ -2,6 +2,7 @@
using ColdMint.scripts.character;
using ColdMint.scripts.debug;
using ColdMint.scripts.map.events;
+using ColdMint.scripts.map.room;
using ColdMint.scripts.utils;
using Godot;
@@ -11,7 +12,7 @@ namespace ColdMint.scripts.map;
/// PlayerSpawn
/// 玩家出生点
///
-public partial class PlayerSpawn : Marker2D
+public partial class PlayerSpawn : Marker2D,ISpawnMarker
{
private PackedScene? _playerPackedScene;
@@ -31,32 +32,49 @@ public partial class PlayerSpawn : Marker2D
GameSceneDepend.Player.GlobalPosition = GlobalPosition;
return;
}
+ Spawn();
+ }
+
- SpawnPlayer();
+ private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
+ {
+ //After the map is generated, create the player instance.
+ //当地图生成完成后,创建玩家实例。
+ if (GameSceneDepend.Player != null)
+ {
+ //An existing player instance will not be created.
+ //已经存在玩家实例,不再创建。
+ return;
+ }
+
+ Spawn();
}
- ///
- /// Generate player instance
- /// 生成玩家实例
- ///
- private void SpawnPlayer()
+ public override void _ExitTree()
+ {
+ base._ExitTree();
+ EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
+ EventBus.GameReplayEvent -= GameReplayEvent;
+ }
+
+ public Node2D? Spawn()
{
if (GameSceneDepend.PlayerContainer == null)
{
- return;
+ return null;
}
if (_playerPackedScene == null)
{
LogCat.LogError("player_packed_scene_not_exist");
- return;
+ return null;
}
var playerNode =
NodeUtils.InstantiatePackedScene(_playerPackedScene);
if (playerNode == null)
{
- return;
+ return null;
}
//The player's parent node must be GameSceneDepend PlayerContainer.
@@ -73,26 +91,16 @@ public partial class PlayerSpawn : Marker2D
playerNode.ItemContainer = itemContainer;
GameSceneDepend.Player = playerNode;
playerNode.GlobalPosition = GlobalPosition;
+ return playerNode;
}
- private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
+ public bool CanQueueFree()
{
- //After the map is generated, create the player instance.
- //当地图生成完成后,创建玩家实例。
- if (GameSceneDepend.Player != null)
- {
- //An existing player instance will not be created.
- //已经存在玩家实例,不再创建。
- return;
- }
-
- SpawnPlayer();
+ return false;
}
- public override void _ExitTree()
+ public void DoQueueFree()
{
- base._ExitTree();
- EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
- EventBus.GameReplayEvent -= GameReplayEvent;
+ QueueFree();
}
}
\ No newline at end of file
diff --git a/scripts/map/events/AiCharacterGenerateEvent.cs b/scripts/map/events/AiCharacterGenerateEvent.cs
deleted file mode 100644
index 37ad9bd..0000000
--- a/scripts/map/events/AiCharacterGenerateEvent.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace ColdMint.scripts.map.events;
-
-///
-/// AiCharacterGenerateEvent
-/// Ai角色生成事件
-///
-public class AiCharacterGenerateEvent
-{
- ///
- /// Map generation completed Tag
- /// 地图生成完成的Tag
- ///
- public const string TagMapGenerationComplete = "MapGenerationComplete";
-
-
- ///
- /// The Tag used to generate the role
- /// 生成角色时使用的Tag
- ///
- // ReSharper disable UnusedAutoPropertyAccessor.Global
- public string? Tag { get; set; }
- // ReSharper restore UnusedAutoPropertyAccessor.Global
-}
\ No newline at end of file
diff --git a/scripts/map/room/IEnterRoomEventHandler.cs b/scripts/map/room/IEnterRoomEventHandler.cs
index 63e7008..3ec660f 100644
--- a/scripts/map/room/IEnterRoomEventHandler.cs
+++ b/scripts/map/room/IEnterRoomEventHandler.cs
@@ -19,7 +19,11 @@ public interface IEnterRoomEventHandler
/// When entering the room
/// 当进入房间时
///
+ ///
+ ///The number of times the player visits the room, 1 is the first visit.
+ ///玩家访问房间的次数,为1则代表首次访问。
+ ///
///
///
- void OnEnterRoom(Node node,Room room);
+ void OnEnterRoom(int playerRoomVisitCount,Node node,Room room);
}
\ No newline at end of file
diff --git a/scripts/map/room/ISpawnMarker.cs b/scripts/map/room/ISpawnMarker.cs
new file mode 100644
index 0000000..5950f58
--- /dev/null
+++ b/scripts/map/room/ISpawnMarker.cs
@@ -0,0 +1,33 @@
+using Godot;
+
+namespace ColdMint.scripts.map.room;
+
+///
+/// The tag of the generated entity
+/// 生成实体的标记
+///
+public interface ISpawnMarker
+{
+ ///
+ /// Generating entity
+ /// 生成实体
+ ///
+ ///
+ ///Return the result of the generation. If null is returned, the generation fails.
+ ///返回生成结果,为null则生成失败。
+ ///
+ Node2D? Spawn();
+
+ ///
+ /// Can Queue Free
+ /// 可释放节点吗
+ ///
+ ///
+ bool CanQueueFree();
+
+ ///
+ /// Execute Queue Free
+ /// 执行释放节点
+ ///
+ void DoQueueFree();
+}
\ No newline at end of file
diff --git a/scripts/map/room/Room.cs b/scripts/map/room/Room.cs
index a9f97a4..e26d383 100644
--- a/scripts/map/room/Room.cs
+++ b/scripts/map/room/Room.cs
@@ -28,6 +28,18 @@ public class Room
private CollisionShape2D? _collisionShape2D;
private bool _hasPlayer;
private readonly List _characterTemplateList = [];
+
+ ///
+ /// When the player first enters the room, all nodes under this node are executed
+ /// 当玩家首次进入房间时,会执行此节点下所有节点
+ ///
+ private Node2D? _autoSpawn;
+
+ ///
+ /// The number of times the player visits the room
+ /// 玩家访问房间的次数
+ ///
+ private int PlayerRoomVisitCount { get; set; }
public string? EnterRoomEventHandlerId { get; set; }
@@ -51,47 +63,31 @@ public class Room
}
///
- /// Places a barrier in a slot where a match has been found.
- /// 在找到匹配的槽位放置屏障。
+ /// Place barriers in all slots
+ /// 在所有的槽位放置屏障
///
- private void PlaceBarrierInMatchedSlot()
+ public void PlaceBarriersInAllSlots()
{
- ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
+ var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
+ if (barrier == null)
{
- if (!roomSlot.Matched)
- {
- return;
- }
- var cellSourceId = barrier.GetCellSourceId(i);
- if (cellSourceId == -1)
- {
- return;
- }
-
- ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
- });
+ return;
+ }
+ barrier.Enabled = true;
}
///
- /// Clear the barrier that finds a matching slot
- /// 清空找到匹配的槽位的屏障。
+ /// Clear all matched barriers
+ /// 清空所有已匹配位置的屏障
///
- private void ClearBarriersInMatchedSlots()
+ public void ClearAllMatchedBarriers()
{
- ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
+ var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
+ if (barrier == null)
{
- if (!roomSlot.Matched)
- {
- return;
- }
- var cellSourceId = barrier.GetCellSourceId(i);
- if (cellSourceId == -1)
- {
- return;
- }
-
- ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
- });
+ return;
+ }
+ barrier.Enabled = false;
}
///
@@ -99,32 +95,6 @@ public class Room
/// 在未匹配的槽位放置屏障。
///
public void PlaceBarrierInUnmatchedSlots()
- {
- ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
- {
- if (roomSlot.Matched)
- {
- return;
- }
- var cellSourceId = barrier.GetCellSourceId(i);
- if (cellSourceId == -1)
- {
- return;
- }
-
- ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
- });
- }
-
- ///
- /// Executes a callback for each room slot, providing the corresponding coordinates in the barrier and ground layers.
- /// 对每个房间槽位执行回调,提供barrier层和ground层对应的坐标。
- ///
- ///
- ///The callback action to be executed, which takes the barrier layer, ground layer, and coordinates as parameters.
- ///要执行的回调操作,它以屏障层、底层和坐标作为参数。
- ///
- private void ProcessRoomSlots(Action action)
{
var ground = GetTileMapLayer(Config.TileMapLayerName.Ground);
var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
@@ -144,17 +114,27 @@ public class Room
{
continue;
}
-
+
//Place the corresponding coordinate tiles of the barrier layer on the ground level.
//将屏障层的对应坐标瓦片放到地面层。
CoordinateUtils.ForEachCell(roomSlot.StartPosition, roomSlot.EndPosition, i =>
{
- action.Invoke(roomSlot, ground, barrier, i);
+ if (roomSlot.Matched)
+ {
+ return;
+ }
+ var cellSourceId = barrier.GetCellSourceId(i);
+ if (cellSourceId == -1)
+ {
+ return;
+ }
+ ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
});
}
- barrier.QueueFree();
+ barrier.Enabled = false;
}
+
///
/// ShowAllCharacterTemplate
/// 显示所有角色模板
@@ -200,6 +180,15 @@ public class Room
{
_characterTemplateList.Add(player);
_hasPlayer = true;
+ PlayerRoomVisitCount++;
+ if (PlayerRoomVisitCount == 1 && _autoSpawn != null)
+ {
+ NodeUtils.ForEachNode(_autoSpawn, marker =>
+ {
+ marker.Spawn();
+ return false;
+ });
+ }
//The player enters the room, opening up their view.
//玩家进入了房间,开放视野。
if (_pointLight2D != null)
@@ -231,7 +220,7 @@ public class Room
}
var enterRoomEventHandler = RoomEventManager.GetEnterRoomEventHandler(EnterRoomEventHandlerId);
- enterRoomEventHandler?.OnEnterRoom(node, this);
+ enterRoomEventHandler?.OnEnterRoom(PlayerRoomVisitCount, node, this);
}
@@ -260,8 +249,18 @@ public class Room
_pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White25;
}
-
HideAllCharacterTemplate();
+ if (PlayerRoomVisitCount == 1 && _autoSpawn != null)
+ {
+ NodeUtils.ForEachNode(_autoSpawn, marker =>
+ {
+ if (marker.CanQueueFree())
+ {
+ marker.DoQueueFree();
+ }
+ return false;
+ });
+ }
}
else if (node is CharacterTemplate characterTemplate && characterTemplate.Visible)
{
@@ -312,8 +311,8 @@ public class Room
return;
}
- var node2D = NodeUtils.InstantiatePackedScene(packedScene);
- if (node2D == null)
+ var rootNode = NodeUtils.InstantiatePackedScene(packedScene);
+ if (rootNode == null)
{
//The room node is not of Node2D type. An exception is thrown
//房间节点不是Node2D类型,抛出异常
@@ -321,15 +320,15 @@ public class Room
return;
}
- _rootNode = node2D;
- var tileMapNode = node2D.GetNode("TileMap");
+ _rootNode = rootNode;
+ var tileMapNode = rootNode.GetNode("TileMap");
NodeUtils.ForEachNode(tileMapNode, node =>
{
_tileMapLayers ??= [];
_tileMapLayers.Add(node);
return false;
});
- _area2D = node2D.GetNode("RoomArea");
+ _area2D = rootNode.GetNode("RoomArea");
_area2D.Monitoring = true;
_area2D.SetCollisionLayerValue(Config.LayerNumber.RoomArea, true);
//Sets the collision layer that can be detected in the current room area.
@@ -340,12 +339,13 @@ public class Room
_area2D.BodyEntered += OnEnterRoom;
_collisionShape2D = _area2D.GetChild(0);
_roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D,
- node2D.GetNode("RoomSlotList"));
- _pointLight2D = node2D.GetNodeOrNull("PointLight2D");
+ rootNode.GetNode("RoomSlotList"));
+ _pointLight2D = rootNode.GetNodeOrNull("PointLight2D");
if (_pointLight2D != null)
{
_pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix;
}
+ _autoSpawn = rootNode.GetNodeOrNull("AutoSpawn");
}
public Node2D? RootNode => _rootNode;
diff --git a/scripts/utils/NodeUtils.cs b/scripts/utils/NodeUtils.cs
index 0e65f7a..43b6200 100644
--- a/scripts/utils/NodeUtils.cs
+++ b/scripts/utils/NodeUtils.cs
@@ -131,17 +131,17 @@ public static class NodeUtils
///用于处理回调的函数,返回true终止遍历节点
///
///
- ///When the type is specified as Node, all child nodes are returned.
- ///当指定类型为Node时,将返回所有子节点。
+ ///Specifies the generic type
+ ///指定的泛型
///
- public static void ForEachNode(Node parent, Func func) where T : Node
+ public static void ForEachNode(Node parent, Func func) where T : class
{
var count = parent.GetChildCount();
if (count <= 0)
{
return;
}
-
+
for (var i = 0; i < count; i++)
{
var node = parent.GetChild(i);