Newer
Older
DungeonShooting / DungeonShooting_Godot / addons / dungeonShooting_plugin / NodeMonitor.cs
@小李xl 小李xl on 19 Mar 2023 3 KB 创建新的Ui后打开场景
  1. #if TOOLS
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. namespace Plugin;
  7.  
  8. /// <summary>
  9. /// 场景监听器, 一旦当前节点内容发生改变, 则直接调用 SceneNodeChangeEvent 事件
  10. /// </summary>
  11. public class NodeMonitor
  12. {
  13. private class SceneNode : IEquatable<SceneNode>
  14. {
  15. public SceneNode(string type, string name)
  16. {
  17. Type = type;
  18. Name = name;
  19. }
  20.  
  21. public string Type;
  22. public string Name;
  23. public List<SceneNode> Children = new List<SceneNode>();
  24.  
  25. public bool Equals(SceneNode other)
  26. {
  27. if (other == null)
  28. {
  29. return false;
  30. }
  31.  
  32. if (other.Name != Name || other.Type != Type)
  33. {
  34. return false;
  35. }
  36.  
  37. if (other.Children.Count != Children.Count)
  38. {
  39. return false;
  40. }
  41.  
  42. for (var i = 0; i < Children.Count; i++)
  43. {
  44. if (!Children[i].Equals(other.Children[i]))
  45. {
  46. return false;
  47. }
  48. }
  49.  
  50. return true;
  51. }
  52. }
  53.  
  54. /// <summary>
  55. /// 场景节点有变化时的回调事件
  56. /// </summary>
  57. public event Action<Node> SceneNodeChangeEvent;
  58.  
  59. private SceneNode _sceneNode;
  60. private Node _targetNode;
  61.  
  62.  
  63. private double _checkTreeTimer = 0;
  64.  
  65. /// <summary>
  66. /// 更新监听的节点
  67. /// </summary>
  68. public void ChangeCurrentNode(Node node)
  69. {
  70. //更新前检查旧的节点是否发生改变
  71. if (node != _targetNode && _targetNode != null)
  72. {
  73. try
  74. {
  75. var tempNode = ParseNodeTree(_targetNode);
  76. if (!_sceneNode.Equals(tempNode))
  77. {
  78. OnSceneNodeChange(_targetNode);
  79. }
  80. }
  81. catch (Exception e)
  82. {
  83. //检查节点存在报错, 直接跳过该节点的检查
  84. GD.Print(e.Message);
  85. }
  86. }
  87.  
  88. if (node != null)
  89. {
  90. _sceneNode = ParseNodeTree(node);
  91. _targetNode = node;
  92. }
  93. else
  94. {
  95. _targetNode = null;
  96. }
  97. _checkTreeTimer = 0;
  98. }
  99.  
  100. public void Process(float delta)
  101. {
  102. if (_targetNode == null)
  103. return;
  104. _checkTreeTimer += delta;
  105. if (_checkTreeTimer >= 5) //5秒检查一次
  106. {
  107. try
  108. {
  109. var tempNode = ParseNodeTree(_targetNode);
  110. if (!_sceneNode.Equals(tempNode))
  111. {
  112. OnSceneNodeChange(_targetNode);
  113. _sceneNode = tempNode;
  114. }
  115. }
  116. catch (Exception e)
  117. {
  118. //检查节点存在报错, 直接跳过该节点的检查
  119. GD.Print(e.Message);
  120. _targetNode = null;
  121. }
  122. _checkTreeTimer = 0;
  123. }
  124. }
  125. private SceneNode ParseNodeTree(Node node)
  126. {
  127. var uiNode = new SceneNode(node.GetType().FullName, node.Name);
  128. var count = node.GetChildCount();
  129. for (var i = 0; i < count; i++)
  130. {
  131. uiNode.Children.Add(ParseNodeTree(node.GetChild(i)));
  132. }
  133.  
  134. return uiNode;
  135. }
  136.  
  137. private void OnSceneNodeChange(Node node)
  138. {
  139. if (SceneNodeChangeEvent != null)
  140. {
  141. SceneNodeChangeEvent(node);
  142. }
  143. }
  144. }
  145. #endif