123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- using System;
- using System.Collections.Generic;
- using Godot;
- using Godot.Collections;
- namespace TBL.GodotSharp
- {
- /// <summary>
- /// Godot 扩展工具类
- /// </summary>
- public static class Extension
- {
- /// <summary>
- /// 使节点在世界变换下保持只有八方向旋转
- /// </summary>
- public static void SetDir8(this Spatial node)
- {
- node.Rotation = new Vector3(node.Rotation.x, 0, node.Rotation.z);
- var angle = node.GlobalTransform.basis.GetEuler().y;
- var diff = Mathf.PosMod(angle, Mathf.Deg2Rad(45.0f));
- node.RotateY(-diff);
- if (Mathf.Abs(diff) > Mathf.Deg2Rad(22.5f))
- {
- node.RotateY(Mathf.Deg2Rad(45.0f) * Mathf.Sign(diff));
- }
- }
- /// <summary>
- /// 使节点在世界变换下保持只有八方向旋转
- /// </summary>
- public static void SetDir8(this Node node)
- {
- if (node is Spatial spatial)
- SetDir8(spatial);
- }
- /// <summary>
- /// 遍历所有子节点
- /// </summary>
- public static IEnumerable<T> EnumChildrenNodes<T>(this Node node, bool recursive = true)
- where T : Node
- {
- for (int i = 0, count = node.GetChildCount(); i < count; i++)
- {
- var child = node.GetChild(i);
- if (child == null)
- continue;
- if (child is T target)
- yield return target;
- if (recursive)
- foreach (var next in EnumChildrenNodes<T>(child, true))
- yield return next;
- }
- }
- /// <summary>
- /// 获取所有此类型的子节点到列表中
- /// <para>获取前不会清空 <see cref="result"/> 请留意</para>
- /// </summary>
- public static void GetAllNodesOfType<T>(this Node root, Array<T> result, bool recursive = true)
- where T : Node
- {
- foreach ( var node in EnumChildrenNodes<T>(root, recursive) )
- result.Add(node);
- }
- /// <summary>
- /// 设置铺满父节点
- /// </summary>
- public static void SetFullParent(this Control canvasItem)
- {
- canvasItem.AnchorLeft = canvasItem.AnchorTop = 0;
- canvasItem.AnchorRight = canvasItem.AnchorBottom = 1;
- canvasItem.MarginLeft = canvasItem.MarginRight = canvasItem.MarginTop = canvasItem.MarginBottom = 0;
- }
-
- /// <summary>
- /// 设置铺满父节点
- /// </summary>
- public static void SetCenterParent(this Control canvasItem, bool withMargin = false)
- {
- canvasItem.AnchorLeft = canvasItem.AnchorTop = canvasItem.AnchorRight = canvasItem.AnchorBottom = 0.5f;
- if (withMargin)
- {
- var size = canvasItem.GetParentControl().RectSize;
- canvasItem.MarginLeft = -size.x * 0.5f;
- canvasItem.MarginRight = size.x * 0.5f;
- canvasItem.MarginTop = -size.y * 0.5f;
- canvasItem.MarginBottom = size.y * 0.5f;
- }
- else
- canvasItem.MarginLeft = canvasItem.MarginRight = canvasItem.MarginTop = canvasItem.MarginBottom = 0;
- }
- /// <summary>
- /// 退出场景树并销毁
- /// </summary>
- public static void QueueFreeAndExitTree(this Node node)
- {
- try
- {
- node.GetParent()?.RemoveChild(node);
- node.QueueFree();
- }
- catch (ObjectDisposedException)
- {
- }
- }
-
- /// <summary>
- /// 获取完整路径
- /// </summary>
- public static string GetFullPath(this string name, string dir, string ext) => $"{dir}/{name}{ext}";
- /// <summary>
- /// 削除所有动画
- /// </summary>
- public static void RemoveAllAnimations(this AnimationPlayer animationPlayer)
- {
- foreach (var name in animationPlayer.GetAnimationList())
- {
- animationPlayer.RemoveAnimation(name);
- }
- }
- /// <summary>
- /// 将本地节点变为 <see cref="PackedScene"/>
- /// 多用作快捷预制体
- /// </summary>
- public static PackedScene MakePrefab(this Godot.Node node, bool deferredFree = true)
- {
- var prefab = new PackedScene();
- prefab.Pack(node);
- if (deferredFree)
- node.QueueFreeAndExitTree();
- else
- node.Free();
- return prefab;
- }
- }
- }
|