如果单纯的只是序列化一些属性,可以不用添加脚本,如下图所示,选中任意节点然后Add metadata就可以添加属性了。
而且metadata还可以在运行时添加,只需要获取任意节点对象都可以访问它。
1 2 3 4 5 6 7 8 9 10 11 12 |
public override void _Ready() { //获取值 var value = GetMeta("name",Variant.From("默认值")); GD.Print(value); //设置值 SetMeta("name2", 3); SetMeta("name3", "字符串"); } |
如果希望在编辑面板中监听数值的变化,比如设置某些数值修改后执行一些Editor下的逻辑就需要脚本了。如下图所示,这里就和unity很像了,可以添加点击按钮,监听属性值的变化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using Godot; [Tool] //表示代码可以在编辑器中运行 [ExportToolButton]需要用到 public partial class NewScript : Node { [Export] public int Number { get => _number; set { _number = value; GD.Print( $"Number value change: {_number}"); } } private int _number = 2; [ExportToolButton("点击按钮!")] public Callable ClickMeButton => Callable.From(() => { GD.Print("Hello world!"); }); [Export(PropertyHint.Enum, "低:30,中:60,高:200")] public int Speed { get; set; } [Export] private NodePath _nodePath; } |
目前已经可以拓展不少逻辑了,但是现在面板非常丑,无法进一步的定制面板,而且不能拓展已有属性的面板,比如我想给粒子系统单独加一些面板属性,而不影响粒子系统原有的布局。如下图所示,接着Project->Project Setting中间创建插件,选择C#版本,插件名字可以输入InspectorPlugin.cs
注意这里的#if TOOLS 插件代码不需要运行时,打包后宏里的代码会被剥离。 如果只是在类前面写了[Tool] 则打包不会剥离,含义是编辑器和运行时都可执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#if TOOLS using Godot; [Tool] public partial class InspectorPlugin : EditorPlugin { private CPUParticles3DInspector _cPUParticles3DInspector; public override void _EnterTree() { _cPUParticles3DInspector= new CPUParticles3DInspector(); AddInspectorPlugin(_cPUParticles3DInspector); } public override void _ExitTree() { RemoveInspectorPlugin(_cPUParticles3DInspector); } } #endif |
还需要继承EditorInspectorPlugin实现具体细节,这样就实现了拓展已有对象的面板。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using Godot; #if TOOLS public partial class CPUParticles3DInspector : EditorInspectorPlugin { public override bool _CanHandle(GodotObject @object) { return @object is CpuParticles3D; //判断是否是CPUParticles3D } public override void _ParseBegin(GodotObject @object) { base._ParseBegin(@object); var label = new Label(); label.Text = "你好世界!"; var button = new Button(); button.Text = "点击我!"; button.Pressed += () => GD.Print("click"); AddCustomControl(label); AddCustomControl(button); } } #endif |
这个面板的效果太丑了,我们最好可以继续自定义。如下图所示,创建一个界面,VBoxContainer(垂直布局)和HBoxContainer(水平布局)我们可以任意的自定义效果了,怎么样?有种unity的UIToolkit的感觉了吧。
接着在修改CPUParticles3DInspector.cs 加载布局这里改成从文件加载,大家注意.tscn的路径。
1 2 3 4 5 6 7 8 9 |
public override void _ParseBegin(GodotObject @object) { base._ParseBegin(@object); var node2D = GD.Load<PackedScene>("res://addons/myplugin/node_2d.tscn").Instantiate<Control>(); node2D.GetNode<Button>("Button").Pressed += () => GD.Print("Hello world!"); AddCustomControl(node2D); } |
这里在拓展一下.tscn的含义,它就相当于unity的prefab和scene文件,在godot中统一用.tscn保存,好比万物皆场景的感觉。这样粒子特效的拓展面板就可以按照我们标记的效果来了。
我们还可以做自定义窗口,类似unity的edtiorWindows,插件都必须处于开启状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#if TOOLS using Godot; [Tool] public partial class MyWindows : EditorPlugin { private Control _control; public override void _EnterTree() { _control = GD.Load<PackedScene>("res://addons/my_plugin/myWindows.tscn").Instantiate<Control>(); _control.GetNode<Button>("Button").Pressed += () => { }; AddControlToDock(DockSlot.LeftUl, _control); } public override void _ExitTree() { RemoveControlFromDocks(_control); _control.Free(); } } #endif |
目前的拓展方法以及可以解决很多问题,我使用的最新版本godot4.4并没有提供像unity那种MenuItem菜单的功能。
- 本文固定链接: https://www.xuanyusong.com/archives/5142
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表