前言
下面是一个Unity编辑器扩展工具,可以批量替换场景中多个游戏对象的材质。这个工具提供了一个直观的界面,允许用户选择多个对象并快速替换它们的材质。
对惹,这里有一 个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!
功能特点
- 批量选择多个游戏对象
- 替换所有选定对象的材质
- 可选择仅替换特定索引的材质
- 支持撤销操作
- 界面简洁直观
代码实现
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
public class BatchMaterialReplacer : EditorWindow
{
private List<GameObject> selectedObjects = new List<GameObject>();
private Material sourceMaterial;
private Material targetMaterial;
private int materialIndex = 0;
private bool replaceAllMaterials = true;
private Vector2 scrollPosition;
[MenuItem("Tools/Batch Material Replacer")]
public static void ShowWindow()
{
GetWindow<BatchMaterialReplacer>("Material Replacer");
}
private void OnGUI()
{
GUILayout.Label("批量材质替换工具", EditorStyles.boldLabel);
EditorGUILayout.Space();
// 选择对象区域
EditorGUILayout.BeginVertical("box");
GUILayout.Label("选择对象:", EditorStyles.boldLabel);
if (GUILayout.Button("添加选中对象"))
{
AddSelectedObjects();
}
if (GUILayout.Button("清空列表"))
{
selectedObjects.Clear();
}
// 显示已选择的对象列表
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(150));
for (int i = 0; i < selectedObjects.Count; i++)
{
selectedObjects[i] = (GameObject)EditorGUILayout.ObjectField(
$"对象 {i + 1}", selectedObjects[i], typeof(GameObject), true);
}
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// 材质设置区域
EditorGUILayout.BeginVertical("box");
GUILayout.Label("材质设置:", EditorStyles.boldLabel);
sourceMaterial = (Material)EditorGUILayout.ObjectField(
"原材质 (可选)", sourceMaterial, typeof(Material), false);
targetMaterial = (Material)EditorGUILayout.ObjectField(
"目标材质", targetMaterial, typeof(Material), false);
replaceAllMaterials = EditorGUILayout.Toggle("替换所有材质", replaceAllMaterials);
if (!replaceAllMaterials)
{
materialIndex = EditorGUILayout.IntField("材质索引", materialIndex);
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// 操作按钮
EditorGUI.BeginDisabledGroup(targetMaterial == null || selectedObjects.Count == 0);
if (GUILayout.Button("替换材质", GUILayout.Height(30)))
{
ReplaceMaterials();
}
EditorGUI.EndDisabledGroup();
// 提示信息
if (selectedObjects.Count == 0)
{
EditorGUILayout.HelpBox("请先添加一些游戏对象到列表中。", MessageType.Info);
}
else if (targetMaterial == null)
{
EditorGUILayout.HelpBox("请选择目标材质。", MessageType.Warning);
}
}
private void AddSelectedObjects()
{
foreach (GameObject obj in Selection.gameObjects)
{
if (!selectedObjects.Contains(obj))
{
selectedObjects.Add(obj);
}
}
}
private void ReplaceMaterials()
{
if (targetMaterial == null) return;
Undo.RecordObjects(selectedObjects.Where(obj => obj != null).ToArray(), "Replace Materials");
int replacedCount = 0;
foreach (GameObject obj in selectedObjects)
{
if (obj == null) continue;
Renderer renderer = obj.GetComponent<Renderer>();
if (renderer == null) continue;
// 检查是否需要根据原材质过滤
if (sourceMaterial != null)
{
bool hasSourceMaterial = replaceAllMaterials ?
renderer.sharedMaterials.Any(m => m == sourceMaterial) :
renderer.sharedMaterials.Length > materialIndex &&
renderer.sharedMaterials[materialIndex] == sourceMaterial;
if (!hasSourceMaterial) continue;
}
// 替换材质
if (replaceAllMaterials)
{
Material[] newMaterials = new Material[renderer.sharedMaterials.Length];
for (int i = 0; i < newMaterials.Length; i++)
{
newMaterials[i] = targetMaterial;
}
renderer.sharedMaterials = newMaterials;
replacedCount++;
}
else if (materialIndex < renderer.sharedMaterials.Length)
{
Material[] newMaterials = renderer.sharedMaterials;
newMaterials[materialIndex] = targetMaterial;
renderer.sharedMaterials = newMaterials;
replacedCount++;
}
}
Debug.Log($"成功替换了 {replacedCount} 个对象的材质。");
}
}
使用说明
- 在Unity编辑器中,通过菜单栏 Tools > Batch Material Replacer 打开工具窗口
- 在场景中选择一个或多个游戏对象,然后点击"添加选中对象"按钮
- 选择要替换的"目标材质"
- (可选) 如果需要只替换特定材质,可以设置"原材质"和"材质索引"
- 点击"替换材质"按钮执行替换操作
注意事项
- 此工具会直接修改场景中对象的材质,建议在执行前保存场景
- 支持撤销操作(Ctrl+Z)
- 如果对象没有Renderer组件,将被自动跳过
这个工具可以大大提高在Unity中批量处理材质的工作效率,特别适用于需要为多个对象统一更换材质的场景。
更多教学视