空间变换轴插件

简介

Spatial gizmo[空间辅助线框]插件是由编辑器和自定义插件来定义附加到任何类型的Spatial节点的辅助线框.

本教程将向您展示定义您自己的自定义辅助线框的两种主要方法.第一种方法对于简单的辅助线框来说效果很好,并且在你的插件结构中较少的混乱,而第二种方法将让你存储每个辅助线框的一些数据.

注解

本教程假设您已经知道如何制作通用插件. 如有疑问,请参阅 :参考:`文档_制作插件` 页面.

编辑器空间变换轴插件

不管我们选择什么方式,我们需要创建一个新的 EditorSpatialGizmoPlugin .我们可以为新建的变换轴类型设置名称并定义其他行为,比如是否可以隐藏.

这是一个基本设置:

  1. # MyCustomGizmoPlugin.gd
  2. extends EditorSpatialGizmoPlugin
  3. func get_name():
  4. return "CustomNode"
  1. # MyCustomEditorPlugin.gd
  2. tool
  3. extends EditorPlugin
  4. const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")
  5. var gizmo_plugin = MyCustomGizmoPlugin.new()
  6. func _enter_tree():
  7. add_spatial_gizmo_plugin(gizmo_plugin)
  8. func _exit_tree():
  9. remove_spatial_gizmo_plugin(gizmo_plugin)

对于简单的辅助线框,只要继承 EditorSpatialGizmoPlugin 就足够了.如果你想存储每个线框的一些数据,或者你要把一个Godot 3.0的线框移植到3.1+,你应该选择第二种方法.

简单方法

第一步,在我们的自定义变换轴插件中,重写 has_gizmo() 方法,当空间参数为目标类型时,它将返回 true .

  1. # ...
  2. func has_gizmo(spatial):
  3. return spatial is MyCustomSpatial
  4. # ...

我们可以重写譬如 redraw() 的方法,或所有与句柄相关的方法.

  1. # ...
  2. func _init():
  3. create_material("main", Color(1, 0, 0))
  4. create_handle_material("handles")
  5. func redraw(gizmo):
  6. gizmo.clear()
  7. var spatial = gizmo.get_spatial_node()
  8. var lines = PoolVector3Array()
  9. lines.push_back(Vector3(0, 1, 0))
  10. lines.push_back(Vector3(0, spatial.my_custom_value, 0))
  11. var handles = PoolVector3Array()
  12. handles.push_back(Vector3(0, 1, 0))
  13. handles.push_back(Vector3(0, spatial.my_custom_value, 0))
  14. gizmo.add_lines(lines, get_material("main", gizmo), false)
  15. gizmo.add_handles(handles, get_material("handles", gizmo))
  16. # ...

请注意,我们在 _init 方法中创建了一个材质,并在 redraw 方法中使用 get_material() 取得它.该方法根据变换轴的状态(选择中和/或可编辑)来获取材质的变体.

您最后的场景应该是这样的:

  1. extends EditorSpatialGizmoPlugin
  2. const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
  3. func _init():
  4. create_material("main", Color(1,0,0))
  5. create_handle_material("handles")
  6. func has_gizmo(spatial):
  7. return spatial is MyCustomSpatial
  8. func redraw(gizmo):
  9. gizmo.clear()
  10. var spatial = gizmo.get_spatial_node()
  11. var lines = PoolVector3Array()
  12. lines.push_back(Vector3(0, 1, 0))
  13. lines.push_back(Vector3(0, spatial.my_custom_value, 0))
  14. var handles = PoolVector3Array()
  15. handles.push_back(Vector3(0, 1, 0))
  16. handles.push_back(Vector3(0, spatial.my_custom_value, 0))
  17. gizmo.add_lines(lines, get_material("main", gizmo), false)
  18. gizmo.add_handles(handles, get_material("handles", gizmo))
  19. # You should implement the rest of handle-related callbacks
  20. # (get_handle_name(), get_handle_value(), commit_handle()...).

注意,我们只是在重绘方法中添加了一些句柄,但是我们仍然需要在:参考:`编辑器空间变换轴插件<类_编辑器空间变换轴插件>`中实现其他与句柄相关的回调,以获得正确的工作句柄.

替代方法

在某些情况下,我们希望提供自己的:参考:`编辑器空间变换轴<类_编辑器空间变换轴>`实现,也许是因为我们想要在每个变换轴中存储一些状态,或者正在移植一个旧的变换轴插件,而不想经历重写过程.

在这些情况下,我们需要做的就是在我们的新变换轴插件中覆盖:参考:创建变换轴()<类_编辑器空间变换轴插件_方法_创建变换轴>,因此它返回我们想要实现的目标空间节点的自定义变换轴.

  1. # MyCustomGizmoPlugin.gd
  2. extends EditorSpatialGizmoPlugin
  3. const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
  4. const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
  5. func _init():
  6. create_material("main", Color(1, 0, 0))
  7. create_handle_material("handles")
  8. func create_gizmo(spatial):
  9. if spatial is MyCustomSpatial:
  10. return MyCustomGizmo.new()
  11. else:
  12. return null

这样,所有的gizmo逻辑和绘图方法都可以在一个新的类中实现,扩展为 EditorSpatialGizmo ,像这样:

  1. # MyCustomGizmo.gd
  2. extends EditorSpatialGizmo
  3. # You can store data in the gizmo itself (more useful when working with handles).
  4. var gizmo_size = 3.0
  5. func redraw():
  6. clear()
  7. var spatial = get_spatial_node()
  8. var lines = PoolVector3Array()
  9. lines.push_back(Vector3(0, 1, 0))
  10. lines.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))
  11. var handles = PoolVector3Array()
  12. handles.push_back(Vector3(0, 1, 0))
  13. handles.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))
  14. var material = get_plugin().get_material("main", self)
  15. add_lines(lines, material, false)
  16. var handles_material = get_plugin().get_material("handles", self)
  17. add_handles(handles, handles_material)
  18. # You should implement the rest of handle-related callbacks
  19. # (get_handle_name(), get_handle_value(), commit_handle()...).

请注意,我们刚刚在重绘方法中添加了一些句柄,但我们仍然需要在:参考:`编辑器空间变换轴<类_编辑器空间变换轴>`中实现其余的与句柄相关的回调,以获得正确工作的句柄.