公司有需求,把暫時(shí)有的四十多個(gè)模型,都添加一個(gè)animator組件并且給添加動(dòng)畫狀態(tài)控制,并且打出ab包。這就很煩了,于是花了一個(gè)下午把工具寫完,最近也在搗鼓editor工具,公司加密軟件沒(méi)帶不出demo來(lái),思路還在,回家復(fù)盤,并且加上窗口!
win.PNG
private static string PrefabEndsWith = ".prefab";
/// <summary>
/// 創(chuàng)建預(yù)制體
/// </summary>
/// <param name="選擇的物體"></param>
/// <param name="預(yù)制體存放路徑"></param>
/// <param name="預(yù)制體父物體路徑"></param>
public static void MyCreationPrefab(GameObject[] objs, string rootPath, string parent)
{
try
{
string path = rootPath + parent + "/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
for (int i = 0; i < objs.Length; i++)
{
EditorUtility.DisplayProgressBar("制作預(yù)制體", "名字:" + objs[i].name, i * 1.0f / objs.Length);
#if UNITY_2018
GameObject TempPrefab = PrefabUtility.CreatePrefab(path + name + ".prefab", objs[i]);
#elif UNITY_2019
GameObject TempPrefab = PrefabUtility.SaveAsPrefabAsset((GameObject)PrefabUtility.InstantiatePrefab(objs[i]), path + GetPrefabName(objs[i].name) + PrefabEndsWith);
#endif
}
EditorUtility.ClearProgressBar();
}
catch (System.Exception e)
{
Debug.LogError($"創(chuàng)建預(yù)制體失??!{e}");
EditorUtility.ClearProgressBar();
}
}
/// <summary>
/// 創(chuàng)建預(yù)制體重載
/// </summary>
/// <param name="modelPath"></param>
/// <param name="paefabRoot"></param>
/// <param name="是否給模型添加動(dòng)畫狀態(tài)機(jī)"></param>
/// <param name="動(dòng)畫狀態(tài)機(jī)存放地址"></param>
public static void MyCreationPrefab(List<string> modelPath, string paefabRoot, bool setAnim, string animPath)
{
try
{
for (int i = 0; i < modelPath.Count; i++)
{
if (modelPath[i] == "") continue;
string path = paefabRoot + PathToPrefabParent(modelPath[i]) + "/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
List<string> mPath = GetModels(modelPath[i]);
for (int j = 0; j < mPath.Count; j++)
{
EditorUtility.DisplayProgressBar("制作預(yù)制體", "模型路徑:" + mPath[j], j * 1.0f / mPath.Count);
#if UNITY_2018
PrefabUtility.CreatePrefab(path + name + ".prefab", objs[i]);
#elif UNITY_2019
GameObject TempPrefab = PrefabUtility.SaveAsPrefabAsset((GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>(mPath[j])), path + PathToPrefabName(mPath[j]) + PrefabEndsWith);
#endif
if (setAnim)
{
SetAnimatorController(TempPrefab, mPath[j], animPath, PathToPrefabName(mPath[j]));
}
}
EditorUtility.ClearProgressBar();
}
}
catch (System.Exception e)
{
Debug.LogError($"創(chuàng)建預(yù)制體失敗!{e}");
EditorUtility.ClearProgressBar();
}
}
/// <summary>
/// 獲取模型的名字
/// </summary>
/// <param name="pathList"></param>
/// <returns></returns>
public static List<string> GetModels(string pathList)
{
try
{
List<string> modelPath = new List<string>();
string[] allStr = AssetDatabase.FindAssets("t:model", new string[] { pathList });
for (int i = 0; i < allStr.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(allStr[i]);
if (allStr.Length > 100)
{
EditorUtility.DisplayProgressBar("查找模型", "ModelPath:" + path, i * 1.0f / allStr.Length);
}
modelPath.Add(path);
}
EditorUtility.ClearProgressBar();
return modelPath;
}
catch (System.Exception e)
{
EditorUtility.ClearProgressBar();
Debug.LogError($"查找模型失敗{e}!");
return null;
}
}
/// <summary>
/// 給預(yù)制體添加動(dòng)畫
/// </summary>
/// <param name="obj"></param>
/// <param name="modelPath"></param>
/// <param name="animatorControllerPath"></param>
/// <param name="name"></param>
public static void SetAnimatorController(GameObject obj, string modelPath, string animatorControllerPath, string name)
{
Animator anim = obj.GetComponent<Animator>();
if (anim)
{
AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(animatorControllerPath + name + ".controller");
AnimatorController.SetAnimatorController(anim, controller);
AnimatorControllerLayer layer = controller.layers[0];
AnimatorStateMachine machine = layer.stateMachine;
controller.AddParameter("e", AnimatorControllerParameterType.Bool);
AnimatorState IdleState = machine.AddState("Idle", new Vector3(300, 0, 0));
machine.defaultState = IdleState;
AnimatorState behaviorState = machine.AddState("behavior", new Vector3(550, 0, 0));
behaviorState.motion = GetAnimationClip(modelPath);
AnimatorStateTransition behaviorTrue = IdleState.AddTransition(behaviorState);
behaviorTrue.AddCondition(AnimatorConditionMode.If, 1f, "e");
AnimatorStateTransition behaviorFlas = behaviorState.AddTransition(IdleState);
behaviorFlas.AddCondition(AnimatorConditionMode.IfNot, 1F, "e");
}
else
{
Debug.Log(obj.name + "沒(méi)有掛載動(dòng)畫狀態(tài)機(jī)組件");
}
}
/// <summary>
/// 獲取動(dòng)畫片段
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static AnimationClip GetAnimationClip(string path)
{
Object[] objects = AssetDatabase.LoadAllAssetsAtPath(path);
for (int m = 0; m < objects.Length; m++)
{
if (objects[m].GetType() == typeof(AnimationClip))
{
AnimationClip clip = (AnimationClip)objects[m];
return clip;
}
}
return null;
}
/// <summary>
/// 獲取動(dòng)畫片段
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static AnimationClip GetAnimationClip(GameObject go)
{
return go.GetComponent<Animation>().clip;
}
/// <summary>
/// 給模型名字返回預(yù)制的名字
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
static string GetPrefabName(string name)
{
return name.Replace("_", "");
}
/// <summary>
/// 得到模型的名字
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
static string PathToPrefabName(string path)
{
string[] str = path.Split('/');
string result = str[str.Length - 1];
result = result.Replace("_", "");
result = result.Replace(".fbx", "");
return result;
}
/// <summary>
/// 得到模型父物體名字 "Assets/Model"
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
static string PathToPrefabParent(string path)
{
string[] str = path.Split('/');
string result = str[str.Length - 1];
return result;
}
```swift
可以選擇把鼠標(biāo)選擇的模型制作為預(yù)制體,和根據(jù)傳入一個(gè)地址,查找該目錄下的模型進(jìn)行處理。這里可以,拓展為配表,為多個(gè)模型添加動(dòng)畫,添加什么動(dòng)畫,這個(gè)時(shí)候成功的給產(chǎn)品增加了工作,但是可以增加一些效率,需要處理的模型越多,越省時(shí)間。
```swift
AnimBool m_SelectionGameobjectWinWin;
private string m_PrefabsRootPath = null;
private string m_PrafabsParent = null;
private string m_AnimatorControllerPath = null;
private bool m_SetAnimatorController = false;
AnimBool m_Win;
private List<string> list = new List<string>();
void OnEnable()
{
m_Win = new AnimBool(true);
m_Win.valueChanged.AddListener(Repaint);
m_SelectionGameobjectWinWin = new AnimBool(true);
m_SelectionGameobjectWinWin.valueChanged.AddListener(Repaint);
}
void OnGUI()
{
m_SelectionGameobjectWinWin.target = EditorGUILayout.ToggleLeft("選擇模型制作為預(yù)制體", m_SelectionGameobjectWinWin.target);
if (EditorGUILayout.BeginFadeGroup(m_SelectionGameobjectWinWin.faded))
{
EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel("預(yù)制體存放根路徑");
m_PrefabsRootPath = EditorGUILayout.TextField(m_PrefabsRootPath ?? "Assets/Prefabs/");
EditorGUILayout.PrefixLabel("預(yù)制體存放文件夾名稱");
m_PrafabsParent = EditorGUILayout.TextField(m_PrafabsParent ?? "Other");
m_SetAnimatorController = EditorGUILayout.Toggle("為該模型添加動(dòng)畫控制", m_SetAnimatorController);
if (EditorGUILayout.BeginFadeGroup(m_SetAnimatorController == true ? 1.0f : 0))
{
EditorGUILayout.PrefixLabel("動(dòng)畫狀態(tài)機(jī)存放文件夾名稱");
m_AnimatorControllerPath = EditorGUILayout.TextField(m_AnimatorControllerPath ?? "Assets/AnimatorControllers");
}
EditorGUILayout.EndFadeGroup();
if (GUILayout.Button("把選擇的模型制作為預(yù)制體", GUILayout.Width(200)))
{
if (Selection.gameObjects.Length > 0)
{
Debug.LogError("根據(jù)CreationPrefabTool.GetAnimationClip()適配");
Close();
}
else
{
Debug.LogError("請(qǐng)選擇至少大于一個(gè)模型進(jìn)行預(yù)制體制作!");
Close();
}
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
m_Win.target = EditorGUILayout.ToggleLeft("批量模型制作為預(yù)制體", m_Win.target);
if (EditorGUILayout.BeginFadeGroup(m_Win.faded))
{
EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel("預(yù)制體存放根路徑");
m_PrefabsRootPath = EditorGUILayout.TextField(m_PrefabsRootPath ?? "Assets/Prefabs/");
EditorGUILayout.PrefixLabel("模型存放根路徑");
for (int i = 0; i < list.Count; i++)
{
EditorGUILayout.BeginHorizontal("box");
m_SetAnimatorController = EditorGUILayout.Toggle("為該模型添加動(dòng)畫控制", m_SetAnimatorController);
if (EditorGUILayout.BeginFadeGroup(m_SetAnimatorController == true ? 1.0f : 0))
{
EditorGUILayout.PrefixLabel("動(dòng)畫狀態(tài)機(jī)存放文件夾名稱");
m_AnimatorControllerPath = EditorGUILayout.TextField(m_AnimatorControllerPath ?? "Assets/AnimatorControllers");
}
EditorGUILayout.EndFadeGroup();
list[i] = EditorGUILayout.TextField(list[i]);
if (GUILayout.Button("Remove", GUILayout.Width(70)))
{
list.RemoveAt(i);
}
EditorGUILayout.EndHorizontal();
}
if (GUILayout.Button("Add", GUILayout.Width(200)))
{
list.Add("");
}
if (GUILayout.Button("批量制作預(yù)制體", GUILayout.Width(200)))
{
CreationPrefabTool.MyCreationPrefab(list, m_PrefabsRootPath, m_SetAnimatorController, m_AnimatorControllerPath);
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
}
```swift
這個(gè)窗口不是很完善,暫時(shí)沒(méi)有需求就懶得完善了,啥是需要的在回來(lái)完善,暫時(shí)使用,沒(méi)有出現(xiàn)bug。