material_creator.gd 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. @tool
  2. extends Panel
  3. # In this file, the word "silly" is used to make it obvious that the name is arbitrary.
  4. var silly_material_resource = preload("res://addons/material_creator/material_resource.gd")
  5. var editor_interface: EditorInterface
  6. func _ready() -> void:
  7. # Connect all of the signals we'll need to save and load silly materials.
  8. $VBoxContainer/ApplyButton.pressed.connect(apply_pressed)
  9. $VBoxContainer/SaveButton.pressed.connect(save_pressed)
  10. $VBoxContainer/LoadButton.pressed.connect(load_pressed)
  11. $SaveMaterialDialog.file_selected.connect(save_file_selected)
  12. $LoadMaterialDialog.file_selected.connect(load_file_selected)
  13. RenderingServer.canvas_item_set_clip(get_canvas_item(), true)
  14. func save_pressed() -> void:
  15. $SaveMaterialDialog.popup_centered_ratio()
  16. func load_pressed() -> void:
  17. $LoadMaterialDialog.popup_centered_ratio()
  18. func apply_pressed() -> void:
  19. # Using the passed in editor interface, get the selected nodes in the editor.
  20. var editor_selection: EditorSelection = editor_interface.get_selection()
  21. var selected_nodes := editor_selection.get_selected_nodes()
  22. if selected_nodes.is_empty():
  23. push_error("Material Creator: Can't apply the material, because there are no nodes selected!")
  24. var new_material: StandardMaterial3D = _silly_resource_from_values().make_material()
  25. # Go through the selected nodes and see if they have the "set_surface_override_material"
  26. # function (which only MeshInstance3D has by default). If they do, then set the material
  27. # to the silly material.
  28. for node in selected_nodes:
  29. if node.has_method("set_surface_override_material"):
  30. node.set_surface_override_material(0, new_material)
  31. func save_file_selected(path: String) -> bool:
  32. var silly_resource: Variant = _silly_resource_from_values()
  33. # Make a file, store the silly material as a JSON string.
  34. var file := FileAccess.open(path, FileAccess.WRITE)
  35. file.store_string(silly_resource.make_json())
  36. return true
  37. func load_file_selected(path: String) -> bool:
  38. var SpatialMaterial_Silly: StandardMaterial3D = null
  39. # Make a new silly resource (which in this case actually is a node)
  40. # and initialize it.
  41. var silly_resource: Variant = silly_material_resource.new()
  42. #silly_resource.init()
  43. # If the file exists, then open it.
  44. if FileAccess.file_exists(path):
  45. var file := FileAccess.open(path, FileAccess.READ)
  46. # Get the JSON string and convert it into a silly material.
  47. var json_dict_as_string := file.get_line()
  48. if json_dict_as_string != null:
  49. silly_resource.from_json(json_dict_as_string)
  50. else:
  51. return false
  52. $VBoxContainer/AlbedoColorPicker.color = silly_resource.albedo_color
  53. $VBoxContainer/MetallicSlider.value = silly_resource.metallic_strength
  54. $VBoxContainer/RoughnessSlider.value = silly_resource.roughness_strength
  55. # Return `true` to indicate success.
  56. return true
  57. # If the file does not exist, then return `false` to indicate failure.
  58. return false
  59. func _silly_resource_from_values() -> Variant:
  60. # Get the values from the sliders and color picker.
  61. var color: Color = $VBoxContainer/AlbedoColorPicker.color
  62. var metallic: float = $VBoxContainer/MetallicSlider.value
  63. var roughness: float = $VBoxContainer/RoughnessSlider.value
  64. # Make a new silly resource (which in this case actually is a node) and initialize it.
  65. var silly_resource: Variant = silly_material_resource.new()
  66. #silly_resource.init()
  67. # Assign the values.
  68. silly_resource.albedo_color = color
  69. silly_resource.metallic_strength = metallic
  70. silly_resource.roughness_strength = roughness
  71. return silly_resource