做3D方面的同学们不知道是否会频繁碰见这样的问题:
1.美术给的模型或者动画的材质因为第三方渲染器的原因导入unity后就只剩下无贴图的原始材质球,只好苦逼的一个个上贴图材质,上了一个也就罢了,后面的一个个都要上。
2.为了整理工程资源一不下心把材质球和模型关联全搞无了,大量重复的去一个个拖材质球。
3.存在多维材质的模型无法用传统的右键复制材质球属性然后粘贴过去。
我就碰到了。。。。。。美术那边给的人物动画是多维材质,一个物体上20多个材质球,因为动画好几个,所以有多个存在多维材质的FBX。我们知道FBX导入unity后你要修改导入材质的Location,要不然材质没法修改属性,但是这样的话就会生成一套材质球,如果这些FBX所用材质球完全不一样那倒没什么,但是如果他们用的材质大部分都是一样的,那生成的多套材质球就造成了空间和性能上的浪费。
因此我选择自己生成材质球然后其余的FBX都不导入材质,痛苦的事情就来了,我需要一个个的去把材质球赋给它们该在的模型上。光上材质有时候就能花费一天的时间,时间的浪费、重复的工作,那这些是万万不能忍受的啊,除非你忍受的住。于是我就想啊,既然代码可以复制材质球属性,我直接代码复制不就行了?
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Material mat;
void Start() {
GetComponent<Renderer>().material.CopyPropertiesFromMaterial(mat);
}
}
但是这个复制只能在运行的时候搞,那我总不能运行的时候花费一段时间和性能去干这个事情啊,于是又想到了编辑器扩展。于是,靠百度大法写了一个复制材质、多维材质的编辑器脚本,也分享给有需要的小伙伴们。
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CopyMaterials : EditorWindow
{
public GameObject mOrigin;
public GameObject mTarget;
protected GUIStyle mFirstTitleLabelStyle = new GUIStyle();
protected GUIStyle mSecondTitleLabelStyle = new GUIStyle();
[MenuItem("Window/CopyMaterials")]
protected static void OnMenuClick()
{
OpenWindow();
}
protected static void OpenWindow()
{
EditorWindow window = EditorWindow.GetWindow<CopyMaterials>();
window.autoRepaintOnSceneChange = true;
window.titleContent = new GUIContent("CopyWindow");
int screenWidthInt = 1920;
int screenHeightInt = 1080;
int windowWidthInt = 480;
int windowHeightInt = 400;
window.position = new Rect(screenWidthInt / 2 - windowWidthInt / 2,
screenHeightInt / 2 - windowHeightInt / 2,
windowWidthInt,
windowHeightInt);
}
private void OnGUI()
{
mOrigin = Selection.activeGameObject;
mFirstTitleLabelStyle.fontSize = 14;
mFirstTitleLabelStyle.normal.textColor = Color.white;
mSecondTitleLabelStyle.fontSize = 12;
mSecondTitleLabelStyle.fontStyle = FontStyle.Bold;
mSecondTitleLabelStyle.normal.textColor = Color.white;
EditorGUILayout.BeginVertical();
EditorGUILayout.Space();
EditorGUILayout.LabelField("[ 目标物体 ]", mSecondTitleLabelStyle);
EditorGUILayout.Space();
EditorGUILayout.LabelField("当前选中物体");
mOrigin = (GameObject)EditorGUILayout.ObjectField(mOrigin, typeof(GameObject), true, GUILayout.MaxWidth(200));
EditorGUILayout.Space();
EditorGUILayout.LabelField("[ 复制物体 ]", mSecondTitleLabelStyle);
mTarget = (GameObject)EditorGUILayout.ObjectField(mTarget, typeof(GameObject), true, GUILayout.MaxWidth(200));
EditorGUILayout.Space();
EditorGUILayout.Space();
if (GUILayout.Button("复制")) CopyButtonClick();
EditorGUILayout.EndVertical();
}
void CopyButtonClick()
{
if (mOrigin.transform.childCount == 0)
{
List<Material> materials = new List<Material>();
mOrigin.GetComponent<Renderer>().GetSharedMaterials(materials);
mTarget.GetComponent<Renderer>().materials = materials.ToArray();
}
else
{
foreach (Transform item in mOrigin.transform)
{
if (item.GetComponent<Renderer>() == null) continue;
if (mTarget.transform.Find(item.name))
{
List<Material> materials = new List<Material>();
item.GetComponent<Renderer>().GetSharedMaterials(materials);
mTarget.transform.Find(item.name).GetComponent<Renderer>().materials = materials.ToArray();
}
}
}
}
}
打开的选项放在unity window下面了。脚本是根据判断名字是否一致来进行材质复制粘贴的。