@tool extends Node3D @export var refresh_now: bool = false: set(value): if value: refresh_now = false # 自动弹回 _apply_materials() @export var cartoon_material: ShaderMaterial: set(value): cartoon_material = value _apply_materials() @export var base_tex: Texture2D: set(value): base_tex = value _apply_materials() @export_group("Instance Overrides") @export var use_custom_color: bool = false: set(value): use_custom_color = value _apply_materials() @export var custom_color: Color = Color(1, 1, 1, 1): set(value): custom_color = value if use_custom_color: # 只有开启时才实时刷新 _apply_materials() func _ready() -> void: _apply_materials() func _apply_materials(): if not is_inside_tree() or cartoon_material == null: return for node in find_children("*", "MeshInstance3D", true, false): if not node is MeshInstance3D: continue # 1. 复制一份全新的独立材质,它自带模板 (toon.tres) 的默认颜色和贴图 var unique_mat = cartoon_material.duplicate() # 2. 安全地获取原模型自带的贴图,并赋给独立材质 if node.mesh != null and node.mesh.get_surface_count() > 0: var original_mat = node.mesh.surface_get_material(0) if original_mat != null: var final_tex: Texture2D = null # 兼容 StandardMaterial3D if original_mat is StandardMaterial3D: final_tex = original_mat.albedo_texture # 兼容原模型自带的其他 ShaderMaterial(如从 Blender 导入的材质) elif original_mat.has_method("get_shader_parameter"): final_tex = original_mat.get_shader_parameter("base_texture") if final_tex != null: unique_mat.set_shader_parameter("base_texture", final_tex) if final_tex == null: unique_mat.set_shader_parameter("base_texture", base_tex) # 3. 处理颜色覆盖 # 如果勾选了自定义颜色,直接在独立材质上修改 # 如果没勾选,则什么都不做,保留从模板复制来的默认颜色 if use_custom_color: unique_mat.set_shader_parameter("color", custom_color) # 4. 最后,把配置好的独立材质一次性赋予模型 node.material_override = unique_mat