A simple GDScript code to show variants of one kind of model inside the Editor.
It’s a component to be added as child to something that asks for a CollisionShape3D.
The paths of the models must be for scenes where we have one “main” node that has, as children, one MeshInstance3D and one CollisionShape3D. Here’s an example:
Let me know if there is something strange or bugs. I actually had quite some trouble to get it to work.
@tool
class_name VariantModelComponent extends Node
@export var parent: Node
@export var model_paths: Array[String] = []
@export var selected_model_index := 0:
set(value):
selected_model_index = value
if model_paths.size() > 0 and is_inside_tree():
selected_model_index = clamp(value, 0, model_paths.size()-1)
load_and_apply_model()
# To save what to queue_free when we change model
var _mesh: MeshInstance3D
var _collision_shape: CollisionShape3D
func _ready():
if not parent:
push_warning("Warning: parent not set for VariantModelComponent")
parent = get_parent()
if model_paths.size() > 0:
load_and_apply_model()
func load_and_apply_model():
if not is_inside_tree():
return
if _mesh:
_mesh.queue_free()
_mesh = null
if _collision_shape:
_collision_shape.queue_free()
_collision_shape = null
if selected_model_index >= model_paths.size():
return
var path = model_paths[selected_model_index]
if not ResourceLoader.exists(path):
push_error("Error: mesh not found at path: ", path)
return
var packed_scene: PackedScene = load(path)
var mesh_instance = packed_scene.instantiate()
# We temporarily add it to avoid errors about ownership
add_child(mesh_instance)
mesh_instance.owner = null
for c in mesh_instance.get_children():
if c is MeshInstance3D:
_mesh = c
elif c is CollisionShape3D:
_collision_shape = c
else:
# We don't add to scene nodes that are not meshes nor collision shapes
continue
c.reparent.call_deferred(parent, false)
mesh_instance.queue_free()
