Plugins de gizmos Spatial¶
Introducción¶
Los complementos de gizmos espaciales son utilizados por el editor y los complementos personalizados para definir los gizmos adjuntos a cualquier tipo de nodo espacial.
Este tutorial le mostrará los dos enfoques principales para definir sus propios gizmos personalizados. La primera opción funciona bien para gizmos simples y crea menos desorden en la estructura de su complemento, mientras que la segunda le permitirá almacenar algunos datos por gizmo.
Nota
Este tutorial asume que ya sabe cómo crear complementos genéricos. En caso de duda, consulte la página: ref: doc_making_plugins.
El EditorSpatialGizmoPlugin¶
Independientemente del enfoque que elijamos, necesitaremos crear un nuevo: ref: EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>. Esto nos permitirá establecer un nombre para el nuevo tipo de gizmo y definir otros comportamientos, como si el gizmo se puede ocultar o no.
Esta sería una configuración básica:
# 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)
Para gizmos simples, simplemente heredar: ref: EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin> es suficiente. Si desea almacenar algunos datos por gizmo o está transfiriendo un gizmo Godot 3.0 a 3.1+, debe optar por el segundo enfoque.
Enfoque simple¶
El primer paso es, en nuestro complemento de gizmo personalizado, anular el método: ref: has_gizmo () <class_EditorSpatialGizmoPlugin_method_has_gizmo> para que devuelva verdadero
cuando el parámetro espacial es de nuestro tipo de destino.
# ...
func has_gizmo(spatial):
return spatial is MyCustomSpatial
# ...
Entonces podemos anular métodos como: ref: redraw () <class_EditorSpatialGizmoPlugin_method_redraw> o todos los relacionados con el identificador.
# ...
func _init():
create_material("main", Color(1, 0, 0))
create_handle_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))
# ...
Note que creamos un material en el método _init, y lo recuperamos en el método` redraw` usando: ref: get_material () <class_EditorSpatialGizmoPlugin_method_get_material>. Este método recupera una de las variantes del material dependiendo del estado del gizmo (seleccionado y / o editable).
La escena final del plugin debería verse similar a esta:
extends EditorSpatialGizmoPlugin
const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
func _init():
create_material("main", Color(1,0,0))
create_handle_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()...).
Tenga en cuenta que acabamos de agregar algunos identificadores en el método de redibujo, pero aún necesitamos implementar el resto de devoluciones de llamada relacionadas con identificadores en: ref: EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin> para que los identificadores funcionen correctamente.
Enfoque alternativo¶
En algunos casos, queremos proporcionar nuestra propia implementación de: ref: EditorSpatialGizmo <class_EditorSpatialGizmo>, tal vez porque queremos tener algún estado almacenado en cada gizmo o porque estamos portando un complemento de gizmo antiguo y no queremos ir a través del proceso de reescritura.
En estos casos, todo lo que tenemos que hacer es, en nuestro nuevo complemento de gizmo, anular: ref: create_gizmo () <class_EditorSpatialGizmoPlugin_method_create_gizmo>, por lo que devuelve nuestra implementación de gizmo personalizada para los nodos espaciales que queremos apuntar.
# 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_handle_material("handles")
func create_gizmo(spatial):
if spatial is MyCustomSpatial:
return MyCustomGizmo.new()
else:
return null
De esta manera, toda la lógica del gizmo y los métodos de dibujo se pueden implementar en una nueva clase que se extiende: ref: EditorSpatialGizmo <class_EditorSpatialGizmo>, así:
# 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()...).
Tenga en cuenta que acabamos de agregar algunos identificadores en el método de redibujo, pero aún necesitamos implementar el resto de devoluciones de llamada relacionadas con identificadores en: ref: EditorSpatialGizmo <class_EditorSpatialGizmo> para que los identificadores funcionen correctamente.