Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / ActivityInstance.cs
@王晗智 王晗智 on 5 Mar 2024 9 KB 2
  1.  
  2. using System;
  3. using System.IO;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 用于在预制场景中创建 ActivityObject
  8. /// </summary>
  9. [Tool]
  10. public partial class ActivityInstance : Node2D
  11. {
  12. private const string GroupName = "Editor";
  13. /// <summary>
  14. /// 物体Id
  15. /// </summary>
  16. [Export]
  17. public string Id
  18. {
  19. get => _id;
  20. set
  21. {
  22. _id = value;
  23. _dirty = true;
  24. }
  25. }
  26.  
  27. /// <summary>
  28. /// 默认所在层级
  29. /// </summary>
  30. [Export]
  31. public RoomLayerEnum DefaultLayer { get; set; } = RoomLayerEnum.NormalLayer;
  32.  
  33. /// <summary>
  34. /// 是否显示阴影
  35. /// </summary>
  36. [Export]
  37. public bool ShowShadow
  38. {
  39. get => _showShadow;
  40. set
  41. {
  42. _showShadow = value;
  43. if (_activityObject != null)
  44. {
  45. if (value)
  46. {
  47. _activityObject.ShowShadowSprite();
  48. }
  49. else
  50. {
  51. _activityObject.HideShadowSprite();
  52. }
  53. }
  54. }
  55. }
  56.  
  57. /// <summary>
  58. /// 阴影偏移
  59. /// </summary>
  60. [Export]
  61. public Vector2 ShowOffset
  62. {
  63. get => _showOffset;
  64. set
  65. {
  66. _showOffset = value;
  67. if (_activityObject != null)
  68. {
  69. _activityObject.ShadowOffset = value;
  70. }
  71. }
  72. }
  73.  
  74. /// <summary>
  75. /// 初始海拔高度
  76. /// </summary>
  77. [Export]
  78. public float Altitude
  79. {
  80. get => _altitude;
  81. set
  82. {
  83. _altitude = value;
  84. if (_activityObject != null)
  85. {
  86. _activityObject.Altitude = value;
  87. _activityObject.Collision.Position = _collPos;
  88. _activityObject.UpdateShadowSprite((float)GetProcessDeltaTime());
  89. _activityObject.CalcThrowAnimatedPosition();
  90. }
  91. }
  92. }
  93.  
  94. /// <summary>
  95. /// 动画精灵的z轴索引
  96. /// </summary>
  97. [Export]
  98. public int SpriteZIndex
  99. {
  100. get => _spriteZIndex;
  101. set
  102. {
  103. _spriteZIndex = value;
  104. if (_activityObject != null)
  105. {
  106. _activityObject.AnimatedSprite.ZIndex = value;
  107. }
  108. }
  109. }
  110. /// <summary>
  111. /// 阴影z轴索引
  112. /// </summary>
  113. [Export]
  114. public int ShadowZIndex
  115. {
  116. get => _shadowZIndex;
  117. set
  118. {
  119. _shadowZIndex = value;
  120. if (_activityObject != null)
  121. {
  122. _activityObject.ShadowSprite.ZIndex = value;
  123. }
  124. }
  125. }
  126. /// <summary>
  127. /// 是否启用垂直运动模拟
  128. /// </summary>
  129. [Export]
  130. public bool VerticalMotion { get; private set; } = true;
  131.  
  132. /// <summary>
  133. /// 是否启用碰撞器
  134. /// </summary>
  135. [Export]
  136. public bool CollisionEnabled
  137. {
  138. get => _collisionEnabled;
  139. set
  140. {
  141. _collisionEnabled = value;
  142. if (_activityObject != null)
  143. {
  144. _activityObject.Collision.Disabled = !value;
  145. }
  146. }
  147. }
  148. /// <summary>
  149. /// 编辑器属性, 物体子碰撞器在编辑器中是否可见
  150. /// </summary>
  151. [Export]
  152. public bool CollisionVisible
  153. {
  154. get => _collisionVisible;
  155. set
  156. {
  157. _collisionVisible = value;
  158. OnChangeCollisionVisible();
  159. }
  160. }
  161.  
  162. private bool _dirty = false;
  163. private bool _collisionVisible = true;
  164. private string _prevId;
  165. private string _id;
  166. private ActivityObject _activityObject;
  167. private Sprite2D _errorSprite;
  168. private bool _showShadow = true;
  169. private Vector2 _showOffset = new Vector2(0, 2);
  170. private float _altitude;
  171. private int _spriteZIndex = 0;
  172. private int _shadowZIndex = -1;
  173. private bool _collisionEnabled = true;
  174.  
  175. private Vector2 _collPos;
  176. private bool _createFlag = false;
  177. //嵌套Instance相关
  178. private bool _isNested = false;
  179. private ActivityObject _activityInstance;
  180. private static string _jsonText;
  181.  
  182. /// <summary>
  183. /// 清空缓存的json
  184. /// </summary>
  185. public static void ClearCacheJson()
  186. {
  187. _jsonText = null;
  188. }
  189. public override void _Ready()
  190. {
  191. #if TOOLS
  192. if (!Engine.IsEditorHint())
  193. {
  194. #endif
  195. var world = World.Current;
  196. if (world != null && world.YSortLayer != null && world.NormalLayer != null)
  197. {
  198. DoCreateObject();
  199. }
  200. #if TOOLS
  201. }
  202. #endif
  203. }
  204.  
  205. public override void _Process(double delta)
  206. {
  207. #if TOOLS
  208. if (Engine.IsEditorHint())
  209. {
  210. if (_dirty || (_activityObject != null && _activityObject.GetParent() != this))
  211. {
  212. _dirty = false;
  213. if (_prevId != _id)
  214. {
  215. OnChangeActivityId(_id);
  216. }
  217. else if (string.IsNullOrEmpty(_id))
  218. {
  219. ShowErrorSprite();
  220. }
  221.  
  222. OnChangeCollisionVisible();
  223. }
  224.  
  225. if (_activityObject != null)
  226. {
  227. _activityObject.Collision.Position = _collPos;
  228. _activityObject.UpdateShadowSprite((float)delta);
  229. _activityObject.CalcThrowAnimatedPosition();
  230. }
  231. }
  232. else
  233. {
  234. #endif
  235. var world = World.Current;
  236. if (world != null && world.YSortLayer != null && world.NormalLayer != null)
  237. {
  238. DoCreateObject();
  239. }
  240. #if TOOLS
  241. }
  242. #endif
  243. }
  244.  
  245. public override void _EnterTree()
  246. {
  247. #if TOOLS
  248. if (Engine.IsEditorHint())
  249. {
  250. _dirty = true;
  251. var children = GetChildren();
  252. foreach (var child in children)
  253. {
  254. if (child is ActivityObject)
  255. {
  256. child.QueueFree();
  257. }
  258. }
  259. if (_activityObject != null)
  260. {
  261. _activityObject.QueueFree();
  262. }
  263. _activityObject = null;
  264. _prevId = null;
  265. }
  266. #endif
  267. }
  268.  
  269. public override void _ExitTree()
  270. {
  271. #if TOOLS
  272. if (Engine.IsEditorHint() && _activityObject != null)
  273. {
  274. _activityObject.QueueFree();
  275. _activityObject = null;
  276. }
  277. #endif
  278. }
  279.  
  280. private ActivityObject DoCreateObject()
  281. {
  282. if (_createFlag)
  283. {
  284. return _activityInstance;
  285. }
  286.  
  287. _createFlag = true;
  288. var activityObject = ActivityObject.Create(Id);
  289. if (_isNested)
  290. {
  291. activityObject.Position = Position - new Vector2(0, 1);
  292. activityObject.Scale = Scale;
  293. activityObject.Rotation = Rotation;
  294. }
  295. else
  296. {
  297. activityObject.Position = GlobalPosition + new Vector2(0, 1);
  298. activityObject.Scale = GlobalScale;
  299. activityObject.Rotation = GlobalRotation;
  300. }
  301. activityObject.Visible = Visible;
  302. activityObject.ShadowOffset = _showOffset;
  303. activityObject.Altitude = _altitude;
  304. activityObject.AnimatedSprite.ZIndex = _spriteZIndex;
  305. activityObject.ShadowSprite.ZIndex = _shadowZIndex;
  306. activityObject.EnableVerticalMotion = VerticalMotion;
  307. activityObject.Collision.Disabled = !_collisionEnabled;
  308. if (!_isNested)
  309. {
  310. activityObject.PutDown(DefaultLayer, _showShadow);
  311. }
  312. else
  313. {
  314. activityObject.DefaultLayer = DefaultLayer;
  315. activityObject.ShowShadowSprite();
  316. }
  317.  
  318. var children = GetChildren();
  319. foreach (var child in children)
  320. {
  321. if (!child.IsInGroup(GroupName))
  322. {
  323. if (child is ActivityInstance o)
  324. {
  325. o._isNested = true;
  326. var instance = o.DoCreateObject();
  327. activityObject.AddChild(instance);
  328. if (instance is IMountItem mountItem)
  329. {
  330. activityObject.AddMountObject(mountItem);
  331. }
  332. else if (instance is IDestroy destroy)
  333. {
  334. activityObject.AddDestroyObject(destroy);
  335. }
  336. }
  337. else
  338. {
  339. child.Reparent(activityObject);
  340. if (child is Node2D node2D && activityObject.GetCurrentTexture().GetHeight() % 2 == 0)
  341. {
  342. node2D.Position += new Vector2(0, 1);
  343. }
  344. }
  345. }
  346. }
  347.  
  348. QueueFree();
  349. _activityInstance = activityObject;
  350. return activityObject;
  351. }
  352.  
  353. private void OnChangeActivityId(string id)
  354. {
  355. _prevId = id;
  356.  
  357. if (_activityObject != null)
  358. {
  359. _activityObject.QueueFree();
  360. _activityObject = null;
  361. }
  362.  
  363. if (string.IsNullOrEmpty(id))
  364. {
  365. ShowErrorSprite();
  366. return;
  367. }
  368.  
  369. if (_jsonText == null)
  370. {
  371. _jsonText = File.ReadAllText("resource/config/ActivityBase.json");
  372. }
  373. var str = $"\"Id\": \"{id}\",";
  374. var index = _jsonText.IndexOf(str, StringComparison.Ordinal);
  375. if (index > -1)
  376. {
  377. const string s = "\"Prefab\": \"";
  378. var startIndex = _jsonText.IndexOf(s, index, StringComparison.Ordinal);
  379. if (startIndex > -1)
  380. {
  381. var endIndex = _jsonText.IndexOf('"', startIndex + s.Length + 1);
  382. if (endIndex > -1)
  383. {
  384. var prefab = _jsonText.Substring(startIndex + s.Length, endIndex - (startIndex + s.Length));
  385. var instance = ResourceManager.LoadAndInstantiate<ActivityObject>(prefab);
  386. _activityObject = instance;
  387. _collPos = instance.Collision.Position - instance.AnimatedSprite.Position - instance.AnimatedSprite.Offset;
  388. instance.IsCustomShadowSprite = instance.ShadowSprite.Texture != null;
  389. instance.Altitude = _altitude;
  390. instance.ShadowOffset = _showOffset;
  391. _activityObject.Position = _activityObject.AnimatedSprite.Position;
  392. if (_showShadow)
  393. {
  394. instance.ShowShadowSprite();
  395. var shadowSpriteMaterial = instance.ShadowSprite.Material as ShaderMaterial;
  396. if (shadowSpriteMaterial != null)
  397. {
  398. shadowSpriteMaterial.SetShaderParameter(
  399. ShaderParamNames.ShowOutline,
  400. ((ShaderMaterial)instance.AnimatedSprite.Material).GetShaderParameter(ShaderParamNames
  401. .ShowOutline)
  402. );
  403. }
  404. }
  405. AddChild(instance);
  406. MoveChild(instance, 0);
  407. HideErrorSprite();
  408. return;
  409. }
  410. }
  411. }
  412. GD.PrintErr($"未找到Id为'{id}'的物体!");
  413. ShowErrorSprite();
  414. }
  415.  
  416. private void OnChangeCollisionVisible()
  417. {
  418. if (_activityObject != null)
  419. {
  420. Utils.EachNode(_activityObject, node =>
  421. {
  422. if (node is CollisionShape2D collisionShape2D)
  423. {
  424. collisionShape2D.Visible = _collisionVisible;
  425. }
  426. else if (node is CollisionPolygon2D collisionPolygon2D)
  427. {
  428. collisionPolygon2D.Visible = _collisionVisible;
  429. }
  430. });
  431. }
  432. }
  433.  
  434. private void ShowErrorSprite()
  435. {
  436. if (_errorSprite == null)
  437. {
  438. _errorSprite = new Sprite2D();
  439. _errorSprite.AddToGroup(GroupName);
  440. _errorSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Error_mini_png);
  441. AddChild(_errorSprite);
  442. MoveChild(_errorSprite, GetChildCount() - 1);
  443. }
  444. }
  445.  
  446. private void HideErrorSprite()
  447. {
  448. if (_errorSprite != null)
  449. {
  450. _errorSprite.QueueFree();
  451. _errorSprite = null;
  452. }
  453. }
  454. }