mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-04 14:11:02 +03:00
Merge branch 'master' into 3.2
This commit is contained in:
@@ -51,12 +51,15 @@ when needed:
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
var import_plugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
import_plugin = preload("import_plugin.gd").new()
|
||||
add_import_plugin(import_plugin)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_import_plugin(import_plugin)
|
||||
import_plugin = null
|
||||
@@ -90,6 +93,7 @@ Let's begin to code our plugin, one method at time:
|
||||
tool
|
||||
extends EditorImportPlugin
|
||||
|
||||
|
||||
func get_importer_name():
|
||||
return "demos.sillymaterial"
|
||||
|
||||
@@ -178,8 +182,10 @@ good practice to use an enum so you can refer to them using names.
|
||||
tool
|
||||
extends EditorImportPlugin
|
||||
|
||||
|
||||
enum Presets { DEFAULT }
|
||||
|
||||
|
||||
...
|
||||
|
||||
Now that the enum is defined, let's keep looking at the methods of an import
|
||||
|
||||
@@ -20,16 +20,19 @@ getting a ``plugin.cfg`` file created, and start with our
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
# MyEditorPlugin.gd
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
tool extends EditorPlugin
|
||||
|
||||
var plugin: EditorInspectorPlugin
|
||||
var plugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
# EditorInspectorPlugin is a resource, so we use `new()` instead of `instance()`.
|
||||
plugin = preload("res://addons/MyPlugin/MyInspectorPlugin.gd").new()
|
||||
add_inspector_plugin(plugin)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_inspector_plugin(plugin)
|
||||
|
||||
@@ -53,9 +56,9 @@ overriding or changing existing property editors.
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
# MyInspectorPlugin.gd
|
||||
|
||||
extends EditorInspectorPlugin
|
||||
|
||||
|
||||
func can_handle(object):
|
||||
# Here you can specify which object types (classes) should be handled by
|
||||
# this plugin. For example if the plugin is specific to your player
|
||||
@@ -64,6 +67,7 @@ overriding or changing existing property editors.
|
||||
# In this example we'll support all objects, so:
|
||||
return true
|
||||
|
||||
|
||||
func parse_property(object, type, path, hint, hint_text, usage):
|
||||
# We will handle properties of type integer.
|
||||
if type == TYPE_INT:
|
||||
@@ -91,9 +95,11 @@ the inspector.
|
||||
extends EditorProperty
|
||||
class_name MyIntEditor
|
||||
|
||||
|
||||
var updating = false
|
||||
var spin = EditorSpinSlider.new()
|
||||
|
||||
|
||||
func _init():
|
||||
# We'll add an EditorSpinSlider control, which is the same that the
|
||||
# inspector already uses for integer and float edition.
|
||||
@@ -108,11 +114,13 @@ the inspector.
|
||||
spin.set_max(1000)
|
||||
spin.connect("value_changed", self, "_spin_changed")
|
||||
|
||||
|
||||
func _spin_changed(value):
|
||||
if (updating):
|
||||
return
|
||||
emit_changed(get_edited_property(), value)
|
||||
|
||||
|
||||
func update_property():
|
||||
var new_value = get_edited_object()[get_edited_property()]
|
||||
updating = true
|
||||
|
||||
@@ -91,12 +91,14 @@ like this:
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
# Initialization of the plugin goes here
|
||||
# Initialization of the plugin goes here.
|
||||
pass
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
# Clean-up of the plugin goes here
|
||||
# Clean-up of the plugin goes here.
|
||||
pass
|
||||
|
||||
.. code-tab:: csharp
|
||||
@@ -110,12 +112,12 @@ like this:
|
||||
{
|
||||
public override void _EnterTree()
|
||||
{
|
||||
// Initialization of the plugin goes here
|
||||
// Initialization of the plugin goes here.
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
// Clean-up of the plugin goes here
|
||||
// Clean-up of the plugin goes here.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -136,7 +138,7 @@ custom behavior.
|
||||
Nodes added via an EditorPlugin are "CustomType" nodes. While they work
|
||||
with any scripting language, they have fewer features than
|
||||
:ref:`the Script Class system <doc_scripting_continued_class_name>`. If you
|
||||
are writing GDScript or NativeScript, we recommend using them instead.
|
||||
are writing GDScript or NativeScript, we recommend using Script Classes instead.
|
||||
|
||||
To create a new node type, you can use the function
|
||||
:ref:`add_custom_type() <class_EditorPlugin_method_add_custom_type>` from the
|
||||
@@ -156,9 +158,11 @@ clicked. For that, we'll need a simple script that extends from
|
||||
tool
|
||||
extends Button
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
connect("pressed", self, "clicked")
|
||||
|
||||
|
||||
func clicked():
|
||||
print("You clicked me!")
|
||||
|
||||
@@ -198,14 +202,16 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
# Initialization of the plugin goes here
|
||||
# Add the new type with a name, a parent type, a script and an icon
|
||||
# Initialization of the plugin goes here.
|
||||
# Add the new type with a name, a parent type, a script and an icon.
|
||||
add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png"))
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
# Clean-up of the plugin goes here
|
||||
# Always remember to remove it from the engine when deactivated
|
||||
# Clean-up of the plugin goes here.
|
||||
# Always remember to remove it from the engine when deactivated.
|
||||
remove_custom_type("MyButton")
|
||||
|
||||
.. code-tab:: csharp
|
||||
@@ -219,8 +225,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
|
||||
{
|
||||
public override void _EnterTree()
|
||||
{
|
||||
// Initialization of the plugin goes here
|
||||
// Add the new type with a name, a parent type, a script and an icon
|
||||
// Initialization of the plugin goes here.
|
||||
// Add the new type with a name, a parent type, a script and an icon.
|
||||
var script = GD.Load<Script>("MyButton.cs");
|
||||
var texture = GD.Load<Texture>("icon.png");
|
||||
AddCustomType("MyButton", "Button", script, texture);
|
||||
@@ -228,8 +234,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following:
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
// Clean-up of the plugin goes here
|
||||
// Always remember to remove it from the engine when deactivated
|
||||
// Clean-up of the plugin goes here.
|
||||
// Always remember to remove it from the engine when deactivated.
|
||||
RemoveCustomType("MyButton");
|
||||
}
|
||||
}
|
||||
@@ -312,23 +318,26 @@ The script could look like this:
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
# A class member to hold the dock during the plugin life cycle
|
||||
|
||||
# A class member to hold the dock during the plugin life cycle.
|
||||
var dock
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
# Initialization of the plugin goes here
|
||||
# Load the dock scene and instance it
|
||||
# Initialization of the plugin goes here.
|
||||
# Load the dock scene and instance it.
|
||||
dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
|
||||
|
||||
# Add the loaded scene to the docks
|
||||
# Add the loaded scene to the docks.
|
||||
add_control_to_dock(DOCK_SLOT_LEFT_UL, dock)
|
||||
# Note that LEFT_UL means the left of the editor, upper-left dock
|
||||
# Note that LEFT_UL means the left of the editor, upper-left dock.
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
# Clean-up of the plugin goes here
|
||||
# Remove the dock
|
||||
# Clean-up of the plugin goes here.
|
||||
# Remove the dock.
|
||||
remove_control_from_docks(dock)
|
||||
# Erase the control from the memory
|
||||
# Erase the control from the memory.
|
||||
dock.free()
|
||||
|
||||
.. code-tab:: csharp
|
||||
@@ -350,10 +359,10 @@ The script could look like this:
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
// Clean-up of the plugin goes here
|
||||
// Remove the dock
|
||||
// Clean-up of the plugin goes here.
|
||||
// Remove the dock.
|
||||
RemoveControlFromDocks(dock);
|
||||
// Erase the control from the memory
|
||||
// Erase the control from the memory.
|
||||
dock.Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ This would be a basic setup:
|
||||
::
|
||||
|
||||
# MyCustomGizmoPlugin.gd
|
||||
|
||||
extends EditorSpatialGizmoPlugin
|
||||
|
||||
|
||||
func get_name():
|
||||
return "CustomNode"
|
||||
|
||||
@@ -39,17 +39,19 @@ This would be a basic setup:
|
||||
::
|
||||
|
||||
# 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)
|
||||
|
||||
@@ -69,8 +71,11 @@ method so that it returns ``true`` when the spatial parameter is of our target t
|
||||
|
||||
# ...
|
||||
|
||||
|
||||
func has_gizmo(spatial):
|
||||
return spatial is MyCustomSpatial
|
||||
|
||||
|
||||
# ...
|
||||
|
||||
Then we can override methods like :ref:`redraw()<class_EditorSpatialGizmoPlugin_method_redraw>`
|
||||
@@ -80,10 +85,12 @@ or all the handle related ones.
|
||||
|
||||
# ...
|
||||
|
||||
|
||||
func _init():
|
||||
create_material("main", Color(1, 0, 0))
|
||||
create_handle_material("handles")
|
||||
|
||||
|
||||
func redraw(gizmo):
|
||||
gizmo.clear()
|
||||
|
||||
@@ -102,6 +109,7 @@ or all the handle related ones.
|
||||
gizmo.add_lines(lines, get_material("main", gizmo), false)
|
||||
gizmo.add_handles(handles, get_material("handles", gizmo))
|
||||
|
||||
|
||||
# ...
|
||||
|
||||
Note that we created a material in the `_init` method, and retrieved it in the `redraw`
|
||||
@@ -115,15 +123,19 @@ So the final plugin would look somewhat like this:
|
||||
|
||||
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()
|
||||
|
||||
@@ -142,8 +154,9 @@ So the final plugin would look somewhat like this:
|
||||
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()...)
|
||||
|
||||
# You should implement the rest of handle-related callbacks
|
||||
# (get_handle_name(), get_handle_value(), commit_handle()...).
|
||||
|
||||
Note that we just added some handles in the redraw method, but we still need to implement
|
||||
the rest of handle-related callbacks in :ref:`EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>`
|
||||
@@ -165,13 +178,16 @@ for the Spatial nodes we want to target.
|
||||
# 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()
|
||||
@@ -184,12 +200,13 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
|
||||
::
|
||||
|
||||
# MyCustomGizmo.gd
|
||||
|
||||
extends EditorSpatialGizmo
|
||||
|
||||
# You can store data in the gizmo itself (more useful when working with handles)
|
||||
|
||||
# You can store data in the gizmo itself (more useful when working with handles).
|
||||
var gizmo_size = 3.0
|
||||
|
||||
|
||||
func redraw():
|
||||
clear()
|
||||
|
||||
@@ -211,8 +228,9 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
|
||||
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()...)
|
||||
|
||||
# You should implement the rest of handle-related callbacks
|
||||
# (get_handle_name(), get_handle_value(), commit_handle()...).
|
||||
|
||||
Note that we just added some handles in the redraw method, but we still need to implement
|
||||
the rest of handle-related callbacks in :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`
|
||||
|
||||
@@ -33,26 +33,31 @@ all you need to initialize your plugin.
|
||||
::
|
||||
|
||||
# PerlinNoise3D.gd
|
||||
|
||||
tool
|
||||
extends VisualShaderNodeCustom
|
||||
class_name VisualShaderNodePerlinNoise3D
|
||||
|
||||
|
||||
func _get_name():
|
||||
return "PerlinNoise3D"
|
||||
|
||||
|
||||
func _get_category():
|
||||
return "MyShaderNodes"
|
||||
|
||||
|
||||
func _get_description():
|
||||
return "Classic Perlin-Noise-3D function (by Curly-Brace)"
|
||||
|
||||
|
||||
func _get_return_icon_type():
|
||||
return VisualShaderNode.PORT_TYPE_SCALAR
|
||||
|
||||
|
||||
func _get_input_port_count():
|
||||
return 4
|
||||
|
||||
|
||||
func _get_input_port_name(port):
|
||||
match port:
|
||||
0:
|
||||
@@ -64,6 +69,7 @@ all you need to initialize your plugin.
|
||||
3:
|
||||
return "time"
|
||||
|
||||
|
||||
func _get_input_port_type(port):
|
||||
match port:
|
||||
0:
|
||||
@@ -75,15 +81,19 @@ all you need to initialize your plugin.
|
||||
3:
|
||||
return VisualShaderNode.PORT_TYPE_SCALAR
|
||||
|
||||
|
||||
func _get_output_port_count():
|
||||
return 1
|
||||
|
||||
|
||||
func _get_output_port_name(port):
|
||||
return "result"
|
||||
|
||||
|
||||
func _get_output_port_type(port):
|
||||
return VisualShaderNode.PORT_TYPE_SCALAR
|
||||
|
||||
|
||||
func _get_global_code(mode):
|
||||
return """
|
||||
vec3 mod289_3(vec3 x) {
|
||||
@@ -106,7 +116,7 @@ all you need to initialize your plugin.
|
||||
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
// Classic Perlin noise
|
||||
// Classic Perlin noise.
|
||||
float cnoise(vec3 P) {
|
||||
vec3 Pi0 = floor(P); // Integer part for indexing.
|
||||
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1.
|
||||
@@ -176,6 +186,7 @@ all you need to initialize your plugin.
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
func _get_code(input_vars, output_vars, mode, type):
|
||||
return output_vars[0] + " = cnoise(vec3((%s.xy + %s.xy) * %s, %s)) * 0.5 + 0.5" % [input_vars[0], input_vars[1], input_vars[2], input_vars[3]]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user