diff --git a/plugins/custom_dock/custom_dock.scn b/plugins/custom_dock/custom_dock.scn new file mode 100644 index 00000000..452a8276 Binary files /dev/null and b/plugins/custom_dock/custom_dock.scn differ diff --git a/plugins/custom_dock/dock_plugin.gd b/plugins/custom_dock/dock_plugin.gd new file mode 100644 index 00000000..ce8a3bcd --- /dev/null +++ b/plugins/custom_dock/dock_plugin.gd @@ -0,0 +1,23 @@ +tool +extends EditorPlugin + +var dock = null + +func _enter_tree(): + # When this plugin node enters tree, add the custom type + + dock = preload("res://addons/custom_dock/custom_dock.scn").instance() + + add_control_to_dock( DOCK_SLOT_LEFT_UL, dock ) + +func _exit_tree(): + + # Remove from docks (must be called so layout is updated and saved) + remove_control_from_docks(dock) + # Remove the node + dock.free() + + + + + \ No newline at end of file diff --git a/plugins/custom_dock/plugin.cfg b/plugins/custom_dock/plugin.cfg new file mode 100644 index 00000000..e295384c --- /dev/null +++ b/plugins/custom_dock/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Custom Dock" +description="Adds a new Customizable Dock" +author="Juan Linietsky" +version="1.0" +script="dock_plugin.gd" + + + + + + + diff --git a/plugins/custom_import_plugin/Custom_material_dock.tscn b/plugins/custom_import_plugin/Custom_material_dock.tscn new file mode 100644 index 00000000..0ee1e79f --- /dev/null +++ b/plugins/custom_import_plugin/Custom_material_dock.tscn @@ -0,0 +1,308 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/custom_import_plugin/Silly_material_creator.gd" type="Script" id=1] + +[node name="Silly Material Creator" type="Panel"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_right = 220.0 +margin_bottom = 340.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +script = ExtResource( 1 ) +_sections_unfolded = [ "custom_styles" ] + +[node name="Label_dock_name" type="Label" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -110.0 +margin_top = 10.0 +margin_right = 73.0 +margin_bottom = 24.0 +rect_scale = Vector2( 1.2, 1.2 ) +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +size_flags_horizontal = 1 +size_flags_vertical = 4 +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_as_outline = 1 +text = "Silly material creator" +align = 1 +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 +_sections_unfolded = [ "Rect", "custom_colors" ] + +[node name="Label_albedo" type="Label" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 50.0 +margin_right = 100.0 +margin_bottom = 64.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +size_flags_horizontal = 1 +size_flags_vertical = 4 +text = "Albedo color" +align = 1 +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="ColorPicker_albedo" type="ColorPickerButton" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 70.0 +margin_right = 100.0 +margin_bottom = 90.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +group = null +flat = false +color = Color( 1, 1, 1, 1 ) +edit_alpha = true + +[node name="Label_metallic" type="Label" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 100.0 +margin_right = 100.0 +margin_bottom = 114.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +size_flags_horizontal = 1 +size_flags_vertical = 4 +text = "Metallic strength" +align = 1 +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="HSlider_metallic" type="HSlider" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 120.0 +margin_right = 100.0 +margin_bottom = 136.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 0 +min_value = 0.0 +max_value = 1.0 +step = 0.05 +page = 0.0 +value = 0.0 +exp_edit = false +rounded = false +editable = true +tick_count = 0 +ticks_on_borders = false +focus_mode = 2 + +[node name="Label_roughness" type="Label" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 150.0 +margin_right = 100.0 +margin_bottom = 164.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +size_flags_horizontal = 1 +size_flags_vertical = 4 +text = "Roughness strength" +align = 1 +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="HSlider_roughness" type="HSlider" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 170.0 +margin_right = 100.0 +margin_bottom = 186.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 0 +min_value = 0.0 +max_value = 1.0 +step = 0.05 +page = 0.0 +value = 0.0 +exp_edit = false +rounded = false +editable = true +tick_count = 0 +ticks_on_borders = false +focus_mode = 2 + +[node name="Button_save" type="Button" parent="."] + +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 210.0 +margin_right = 100.0 +margin_bottom = 260.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +group = null +text = "Save silly material" +flat = false + +[node name="Button_load" type="Button" parent="."] + +editor/display_folded = true +anchor_left = 0.5 +anchor_top = 0.0 +anchor_right = 0.5 +anchor_bottom = 0.0 +margin_left = -100.0 +margin_top = 270.0 +margin_right = 100.0 +margin_bottom = 330.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +toggle_mode = false +enabled_focus_mode = 2 +shortcut = null +group = null +flat = false +clip_text = true +__meta__ = { +"_edit_group_": true +} + +[node name="Label" type="Label" parent="Button_load"] + +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_right = 200.0 +margin_bottom = 60.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 2 +size_flags_horizontal = 1 +size_flags_vertical = 4 +text = "Load silly material +and apply to selected node(s)" +align = 1 +valign = 1 +autowrap = true +percent_visible = 1.0 +lines_skipped = 0 +max_lines_visible = -1 + +[node name="Save_FileDialog" type="FileDialog" parent="."] + +visible = false +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 150.0 +margin_top = 20.0 +margin_right = 600.0 +margin_bottom = 360.0 +rect_min_size = Vector2( 200, 70 ) +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +popup_exclusive = false +window_title = "Save a File" +resizable = true +dialog_hide_on_ok = false +mode = 4 +access = 0 +filters = PoolStringArray( "*.silly_mat" ) +show_hidden_files = false + +[node name="Load_FileDialog" type="FileDialog" parent="."] + +visible = false +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 150.0 +margin_top = 20.0 +margin_right = 600.0 +margin_bottom = 360.0 +rect_min_size = Vector2( 200, 70 ) +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 +popup_exclusive = false +window_title = "Open a File" +resizable = true +dialog_hide_on_ok = false +mode = 0 +access = 0 +filters = PoolStringArray( "*.silly_mat" ) +show_hidden_files = false + + diff --git a/plugins/custom_import_plugin/Silly_material_creator.gd b/plugins/custom_import_plugin/Silly_material_creator.gd new file mode 100644 index 00000000..7212e234 --- /dev/null +++ b/plugins/custom_import_plugin/Silly_material_creator.gd @@ -0,0 +1,97 @@ +tool +extends Panel + +var silly_material_resource = preload("res://addons/custom_import_plugin/Silly_material_resource.gd") +var editor_interface + +func _ready(): + # Connect all of the signals we'll need to save and load silly materials + get_node("Button_save").connect("pressed", self, "save_pressed") + get_node("Button_load").connect("pressed", self, "load_pressed") + get_node("Save_FileDialog").connect("file_selected", self, "save_file_selected") + get_node("Load_FileDialog").connect("file_selected", self, "load_file_selected") + + +func save_pressed(): + get_node("Save_FileDialog").popup_centered() + +func load_pressed(): + get_node("Load_FileDialog").popup_centered() + + +func save_file_selected(path): + + # Get the values from the sliders and color picker + var color = get_node("ColorPicker_albedo").color + var metallic = get_node("HSlider_metallic").value + var roughness = get_node("HSlider_roughness").value + + # Make a new silly resource (which in this case actually is a node) + # and initialize it + var silly_resource = silly_material_resource.new() + silly_resource.init() + + # Assign the values + silly_resource.albedo_color = color + silly_resource.metallic_strength = metallic + silly_resource.roughness_strength = roughness + + # Make a file, store the silly material as a json string, then close the file. + var file = File.new() + file.open(path, File.WRITE) + file.store_string(silly_resource.make_json()) + file.close() + + return true + + + +func load_file_selected(path): + + # Using the passed in editor interface, get the selected nodes in the editor + var editor_selection = editor_interface.get_selection() + var selected_nodes = editor_selection.get_selected_nodes() + + + var file = File.new() + var SpatialMaterial_Silly = null + + # Make a new silly resource (which in this case actually is a node) + # and initialize it + var silly_resource = silly_material_resource.new() + silly_resource.init() + + # If the file exists, then open it + if file.file_exists(path): + file.open(path, File.READ) + + # Get the JSON string and convert it into a silly material. + var json_dict_as_string = file.get_line() + if json_dict_as_string != null: + silly_resource.from_json(json_dict_as_string) + else: + file.close() + return false + + # Tell the silly resource (actually a node) to make a material + SpatialMaterial_Silly = silly_resource.make_material() + + # Go through the selected nodes and see if they have the 'set_surface_material' + # function (which only MeshInstance has by default). If they do, then set the material + # to the silly material. + for node in selected_nodes: + if node.has_method("set_surface_material"): + node.set_surface_material(0, SpatialMaterial_Silly) + + # Close the file and return true (success!) + file.close() + return true + + # If the file does not exist, then return false (failure) + else: + return false + + + # If we somehow get here, then return false (failure) + return false + diff --git a/plugins/custom_import_plugin/Silly_material_resource.gd b/plugins/custom_import_plugin/Silly_material_resource.gd new file mode 100644 index 00000000..008b5cf5 --- /dev/null +++ b/plugins/custom_import_plugin/Silly_material_resource.gd @@ -0,0 +1,61 @@ +tool +extends Node + +# NOTE: in theory this would extend from resource, but until saving and loading resources +# works in godot, we'll stick with extending from node +# and using JSON files to save/load data +# +# See material_import.gd for more information + + +var albedo_color +var metallic_strength +var roughness_strength + +func init(): + albedo_color = Color() + metallic_strength = 0 + roughness_strength = 0 + + +# Convert our data into an dictonary so we can convert it +# into the JSON format +func make_json(): + var json_dict = {} + + json_dict["albedo_color"] = {} + json_dict["albedo_color"]["r"] = albedo_color.r + json_dict["albedo_color"]["g"] = albedo_color.g + json_dict["albedo_color"]["b"] = albedo_color.b + + json_dict["metallic_strength"] = metallic_strength + json_dict["roughness_strength"] = roughness_strength + + return to_json(json_dict) + + +# Convert the passed in string to a json dictonary, and then +# fill in our data. +func from_json(json_dict_as_string): + var json_dict = parse_json(json_dict_as_string) + + albedo_color.r = json_dict["albedo_color"]["r"] + albedo_color.g = json_dict["albedo_color"]["g"] + albedo_color.b = json_dict["albedo_color"]["b"] + + metallic_strength = json_dict["metallic_strength"] + roughness_strength = json_dict["roughness_strength"] + + return + + +# Make a SpatialMaterial using our variables. +func make_material(): + var mat = SpatialMaterial.new() + + mat.albedo_color = albedo_color + mat.metallic = metallic_strength + mat.roughness = roughness_strength + + return mat + diff --git a/plugins/custom_import_plugin/material_import.gd b/plugins/custom_import_plugin/material_import.gd new file mode 100644 index 00000000..a952315a --- /dev/null +++ b/plugins/custom_import_plugin/material_import.gd @@ -0,0 +1,24 @@ +# A simple (and silly) material resource plugin. Allows you to make a really simple material +# from a custom dock, that you can save and load, and apply to selected MeshInstances. +# +# SPECIAL NOTE: This technically should be using EditorImportPlugin and EditorExportPlugin +# to handle the input and output of the silly material. However, currently you cannot export +# custom resources in Godot, so instead we're using JSON files instead. +# | +# This example should be replaced when EditorImportPlugin and EditorExportPlugin are both +# fully working and you can save custom resources. + +tool +extends EditorPlugin + +var io_material_dialog; + +func _enter_tree(): + + io_material_dialog = preload("res://addons/custom_import_plugin/Custom_material_dock.tscn").instance() + io_material_dialog.editor_interface = get_editor_interface(); + + add_control_to_dock( DOCK_SLOT_LEFT_UL, io_material_dialog ) + +func _exit_tree(): + remove_control_from_docks(io_material_dialog) \ No newline at end of file diff --git a/plugins/custom_import_plugin/plugin.cfg b/plugins/custom_import_plugin/plugin.cfg new file mode 100644 index 00000000..246b07f5 --- /dev/null +++ b/plugins/custom_import_plugin/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Silly Spatial Material Importer/Exporter" +description="Imports and exports a 3D Material from an external text file" +author="TwistedTwigleg" +version="1.0" +script="material_import.gd" + + + + + + + diff --git a/plugins/custom_node/heart.gd b/plugins/custom_node/heart.gd new file mode 100644 index 00000000..d53c92d8 --- /dev/null +++ b/plugins/custom_node/heart.gd @@ -0,0 +1,12 @@ +tool +extends Node2D + + +var heart = preload("res://addons/custom_node/heart.png") + +func _draw(): + draw_texture(heart,-heart.get_size()/2) + +func _get_item_rect(): + #override + return Rect2(-heart.get_size()/2,heart.get_size()) diff --git a/plugins/custom_node/heart.png b/plugins/custom_node/heart.png new file mode 100644 index 00000000..1dfd14a4 Binary files /dev/null and b/plugins/custom_node/heart.png differ diff --git a/plugins/custom_node/heart_icon.png b/plugins/custom_node/heart_icon.png new file mode 100644 index 00000000..2eb819aa Binary files /dev/null and b/plugins/custom_node/heart_icon.png differ diff --git a/plugins/custom_node/heart_plugin.gd b/plugins/custom_node/heart_plugin.gd new file mode 100644 index 00000000..01a6177c --- /dev/null +++ b/plugins/custom_node/heart_plugin.gd @@ -0,0 +1,18 @@ +tool +extends EditorPlugin + + +func _enter_tree(): + # When this plugin node enters tree, add the custom type + + add_custom_type("Heart","Node2D",preload("res://addons/custom_node/heart.gd"),preload("res://addons/custom_node/heart_icon.png")) + +func _exit_tree(): + # When the plugin node exits the tree, remove the custom type + + remove_custom_type("Heart") + + + + + \ No newline at end of file diff --git a/plugins/custom_node/plugin.cfg b/plugins/custom_node/plugin.cfg new file mode 100644 index 00000000..ebb4b564 --- /dev/null +++ b/plugins/custom_node/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Heart" +description="Adds a new Heart node in 2D" +author="Juan Linietsky" +version="1.0" +script="heart_plugin.gd" + + + + + + + diff --git a/plugins/readme.txt b/plugins/readme.txt new file mode 100644 index 00000000..963850dc --- /dev/null +++ b/plugins/readme.txt @@ -0,0 +1,13 @@ + +To install these, copy each of these folders to a folder: + +addons/ + +inside your projects, example: + +addons/custom_node + +To distribute and install from UI, make a zip that contains the folder, +example: + +zip -r custom_node.zip custom_node/* \ No newline at end of file