空间Gizmo插件

介绍

编辑器和自定义插件使用空间Gizmo插件来定义附加到任何类型空间节点的Gizmo。

本教程将向您展示定义自己自定义小控件的两种主要方法。第一个选项适用于简单的小控件,并在插件结构中创建较少的混乱,而第二个选项将允许您存储每个小控件的一些数据。

注解

本教程假设您已经知道如何制作通用插件。如果有疑问,请参阅 制作插件 页。

编辑Patiligzmoplugin

无论我们选择哪种方法,我们都需要创建一个新的 EditorSpatialGizmoPlugin . 这将允许我们为新的gizmo类型设置名称,并定义其他行为,例如是否可以隐藏gizmo。

这将是一个基本设置:

# MyCustomGizmoPlugin.gd

extends EditorSpatialGizmoPlugin

func get_name():
    return "CustomNode"
# MyCustomEditorPlugin.gd

tool
extends EditorPlugin

const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")

var gizmo_plugin = MyCustomGizmoPlugin.new()

func _enter_tree():
    add_spatial_gizmo_plugin(gizmo_plugin)

func _exit_tree():
    remove_spatial_gizmo_plugin(gizmo_plugin)

对于简单的小发明,只需继承 EditorSpatialGizmoPlugin 就够了。如果要存储每个gizmo的一些数据,或者要将godot 3.0 gizmo移植到3.1+,则应使用第二种方法。

简单方法

第一步是,在我们的自定义gizmo插件中,重写 has_gizmo() 方法,以便它返回 true 当空间参数为目标类型时。

# ...

func has_gizmo(spatial):
    return spatial is MyCustomSpatial
# ...

然后我们可以重写如下方法 redraw() 或所有手柄相关的。

# ...

func _init():
    create_material("main", Color(1, 0, 0))
    create_handles_material("handles")

func redraw(gizmo):
    gizmo.clear()

    var spatial = gizmo.get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(0, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(0, spatial.my_custom_value, 0))

    gizmo.add_lines(lines, get_material("main", gizmo), false)
    gizmo.add_handles(handles, get_material("handles", gizmo))

# ...

请注意,我们在 _init 方法,并在 redraw 方法应用 get_material() . 此方法根据gizmo的状态(选中和/或可编辑)检索材质的一个变体。

所以最后的插件看起来有点像这样:

extends EditorSpatialGizmoPlugin

const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")

func _init():
    create_material("main", Color(1,0,0))
    create_handles_material("handles")

func has_gizmo(spatial):
    return spatial is MyCustomSpatial

func redraw(gizmo):
    gizmo.clear()

    var spatial = gizmo.get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(0, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(0, spatial.my_custom_value, 0))

    gizmo.add_lines(lines, get_material("main", gizmo), false)
    gizmo.add_handles(handles, get_material("handles", gizmo))

# you should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...)

注意,我们只是在redraw方法中添加了一些句柄,但是我们仍然需要在 EditorSpatialGizmoPlugin 以获得正确的操作手柄。

替代方法

在某些情况下,我们希望提供自己的 EditorSpatialGizmo ,可能是因为我们想要在每个gizmo中存储一些状态,或者因为我们正在移植一个旧的gizmo插件,而不想经历重写过程。

在这些情况下,我们需要做的就是,在我们的新gizmo插件中,重写 create_gizmo() ,因此它返回我们要针对的空间节点的自定义gizmo实现。

# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin

const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")

func _init():
    create_material("main", Color(1, 0, 0))
    create_handles_material("handles")

func create_gizmo(spatial):
    if spatial is MyCustomSpatial:
        return MyCustomGizmo.new()
    else:
        return null

这样,所有Gizmo逻辑和绘图方法都可以在新的CLA扩展中实现。 EditorSpatialGizmo ,就像这样:

# MyCustomGizmo.gd

extends EditorSpatialGizmo

# You can store data in the gizmo itself (more useful when working with handles)
var gizmo_size = 3.0

func redraw():
    clear()

    var spatial = get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))

    var material = get_plugin().get_material("main", self)
    add_lines(lines, material, false)

    var handles_material = get_plugin().get_material("handles", self)
    add_handles(handles, handles_material)

# you should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...)

注意,我们只是在redraw方法中添加了一些句柄,但是我们仍然需要在 EditorSpatialGizmo 以获得正确的操作手柄。