最近写了一个Unity优化工具,主要是搜索某一个文件夹中所有的场景和预设。如果是场景的话,就遍历场景中的所有对象,观察对象身上是否绑定了AudioListener组件,如果有的话移除该组件并保存场景。如果是预设的话,就遍历预设中的所有对象,观察预设中的对象是否绑定AudioListener组件,如果有的话移除该组件。
脚本如下:
增加:过滤非指定资源的执行(动画代码修改:)
using ML_Animation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
class BlendAnimation : EditorWindow
{
public static string[] saveLimitKey = new string[] {
//"Bip001 Footsteps",
"Bip001 Pelvis","Bip001 Spine",
"Bip001 L Thigh","Bip001 R Thigh",
"Bip001 L Calf", "Bip001 R Calf",
//"Bip001 L Foot", "Bip001 R Foot",
//"Bip001 L Toe0","Bip001 R Toe0", "Bip001 L Toe0Nub","Bip001 R Toe0Nub",
//"Bip001 Spine1","Bone017","Bone021",
//"Bip001 Prop1","Dummy001"
};
private static StringBuilder strBuilder;
private static OptimizeAnimationClipProperty optAnimProperty = null;
[MenuItem("Assets/优化/动画/选中AnimationClip-ModifyHeroCameraFOV", true, 0)]
public static bool AnimationAddProperty_()
{
AnimationClip clip = Selection.activeObject as AnimationClip;
if (clip == null)
return false;
else
return true;
}
[MenuItem("Assets/优化/动画/选中AnimationClip-ModifyHeroCameraFOV", false, 0)]
public static void AnimationAddProperty()
{
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.DeepAssets);
int count = 0;
foreach (UnityEngine.Object obj in objs)
{
++count;
EditorUtility.DisplayProgressBar("正在修改动画,请勿操作Unity!!!", count + "/" + objs.Length, count * 1.0f / objs.Length);
AnimationClip clip = obj as AnimationClip;
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
for (int i = 0; i < curveBindings.Length; i++)
{
EditorCurveBinding curveBind = curveBindings[i];
if (curveBind.type == typeof(Camera))
{
AnimationCurve animCurve = AnimationUtility.GetEditorCurve(clip, curveBind);
AnimationUtility.SetEditorCurve(clip, curveBind, null);
curveBind.path = "cam/m_3DHeroCamera";
AnimationUtility.SetEditorCurve(clip, curveBind, animCurve);
AnimationCurve addCurve = new AnimationCurve();
addCurve.AddKey(0, 0);
addCurve.AddKey(clip.length, 0);
clip.SetCurve("cam/m_3DHeroCamera", typeof(Transform), "m_LocalRotation.x", addCurve);
clip.SetCurve("cam/m_3DHeroCamera", typeof(Transform), "m_LocalRotation.y", addCurve);
clip.SetCurve("cam/m_3DHeroCamera", typeof(Transform), "m_LocalRotation.z", addCurve);
}
}
}
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
}
[MenuItem("Assets/优化/动画/选中AnimationClip-优化动画", false, 1)]
public static void AnimOptimizeTrilogy()
{
int count = 0;
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.DeepAssets);
foreach (UnityEngine.Object o in objs)
{
count++;
EditorUtility.DisplayProgressBar("优化动画三部曲...", AssetDatabase.GetAssetPath(o), count * 1.0f / objs.Length);
AnimationClip clip = RemoveAnimationSameKeyframe(o as AnimationClip);
ExecuteOptimaze_(clip);
ReduceAnimationCurve(ref clip);
}
AssetDatabase.SaveAssets();
EditorUtility.ClearProgressBar();
}
[MenuItem("Assets/优化/动画/选中Prefab-优化动画", false, 2)]
public static void OptimizeAnimation()
{
strBuilder = new StringBuilder();
optAnimProperty = new OptimizeAnimationClipProperty();
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets);
for (int i = 0; i < objs.Length; i++)
{
EditorUtility.DisplayProgressBar("优化动画三部曲...", AssetDatabase.GetAssetPath(objs[i]), i * 1.0f / objs.Length);
string path = AssetDatabase.GetAssetPath(objs[i]);
string suffix = Path.GetExtension(path);
if (suffix == ".prefab")
{
optAnimProperty.AllPrefabNum++;
OptimizeAnimationClips(path);
}
}
PrintLog();
AssetDatabase.SaveAssets();
EditorUtility.ClearProgressBar();
}
public static void OptimizeAnimationClips(string path)
{
bool isModifyAnimClip = false;
List<string> optAnims = new List<string>();
string[] depends = AssetDatabase.GetDependencies(path);
for (int i = 0; i < depends.Length; i++)
{
if (Path.GetExtension(depends[i]) == ".anim")
{
if (optAnimProperty.hadOperation.Contains(depends[i]))
{
continue;
}
else
{
optAnimProperty.hadOperation.Add(depends[i]);
optAnims.Add(depends[i]);
}
AnimationClip clip = AssetDatabase.LoadAssetAtPath(depends[i], typeof(AnimationClip)) as AnimationClip;
if (clip == null)
{
Debug.LogError(depends[i] + " is not Exist");
continue;
}
clip = RemoveAnimationSameKeyframe(clip);
ExecuteOptimaze_(clip);
ReduceAnimationCurve(ref clip);
optAnimProperty.ModifyAnimNum++;
isModifyAnimClip = true;
}
}
if (optAnims.Count > 0)
{
optAnimProperty.dicLog.Add(path, optAnims);
}
if (isModifyAnimClip)
optAnimProperty.ModifyPrefabNum++;
}
//[MenuItem("Assets/优化/动画/精简动画小数点")]
private static void AnimationDataOptimaze()
{
int number = 0;
DateTime time = DateTime.Now;
foreach (UnityEngine.Object o in Selection.GetFiltered(typeof(AnimationClip), SelectionMode.DeepAssets))
{
number++;
ExecuteOptimaze(Instantiate(o) as AnimationClip, AssetDatabase.GetAssetPath(o));
}
AssetDatabase.SaveAssets();
Debug.Log("一共压缩了" + number + "个动画文件!");
Debug.Log("耗时:" + (DateTime.Now - time).TotalMilliseconds / 1000 + "秒.");
}
//[MenuItem("Assets/优化/动画/优化动画小数点,不对动画重新创建")]
public static void OptimazeAnimationDecimalPoint()
{
int count = 0;
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.DeepAssets);
foreach (UnityEngine.Object o in objs)
{
count++;
EditorUtility.DisplayProgressBar("优化动画小数点,不重新创建动画", count + "/" + objs.Length, count * 1.0f / objs.Length);
ExecuteOptimaze_(o as AnimationClip);
}
EditorUtility.ClearProgressBar();
}
private static AnimationClip ExecuteOptimaze_(AnimationClip clip)
{
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
for (int i = 0; i < curveBindings.Length; i++)
{
AnimationCurve animCurve = AnimationUtility.GetEditorCurve(clip, curveBindings[i]);
var keyFrames = animCurve.keys;
for (int j = 0; j < keyFrames.Length; j++)
{
var key = keyFrames[j];
key.value = float.Parse(key.value.ToString("f4"));
key.inTangent = float.Parse(key.inTangent.ToString("f4"));
key.outTangent = float.Parse(key.outTangent.ToString("f4"));
keyFrames[j] = key;
}
animCurve.keys = keyFrames;
AnimationUtility.SetEditorCurve(clip, curveBindings[i], animCurve);
}
//AssetDatabase.SaveAssets();
return clip;
}
private static AnimationClip ExecuteOptimaze(AnimationClip clip, string clipName)
{
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
AnimationClipCurveData[] curves = new AnimationClipCurveData[curveBindings.Length];
for (int index = 0; index < curves.Length; ++index)
{
curves[index] = new AnimationClipCurveData(curveBindings[index]);
curves[index].curve = AnimationUtility.GetEditorCurve(clip, curveBindings[index]);
}
foreach (AnimationClipCurveData curveDate in curves)
{
var keyFrames = curveDate.curve.keys;
for (int i = 0; i < keyFrames.Length; i++)
{
var key = keyFrames[i];
key.value = float.Parse(key.value.ToString("f4"));
key.inTangent = float.Parse(key.inTangent.ToString("f4"));
key.outTangent = float.Parse(key.outTangent.ToString("f4"));
keyFrames[i] = key;
}
curveDate.curve.keys = keyFrames;
clip.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);
}
AssetDatabase.CreateAsset(clip, clipName);
return clip;
}
private static void ControlAnimationMetaFile(string metaPath, bool bRead)
{
if (bRead)
{
strBuilder = new StringBuilder();
FileStream fs = new FileStream(metaPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
while (!sr.EndOfStream)
{
strBuilder.AppendLine(sr.ReadLine());
}
sr.Dispose();
}
else
{
if (File.Exists(metaPath))
File.Delete(metaPath);
StreamWriter sw = new StreamWriter(metaPath);
sw.Write(strBuilder);
sw.Dispose();
}
}
//[MenuItem("Assets/优化/动画/移除相同关键帧")]
public static void AnimationRemoveKeyFrame()
{
UnityEngine.Object[] objs = Selection.objects;
for (int i = 0; i < objs.Length; i++)
{
UnityEngine.Object obj = objs[i];
if (obj.GetType() == typeof(AnimationClip))
{
EditorUtility.DisplayProgressBar("移除动画相同关键帧...", AssetDatabase.GetAssetPath(obj), i * 1.0f / objs.Length);
RemoveAnimationSameKeyframe(obj as AnimationClip);
}
}
AssetDatabase.SaveAssets();
EditorUtility.ClearProgressBar();
}
public static AnimationClip RemoveAnimationSameKeyframe(AnimationClip clip)
{
string path = AssetDatabase.GetAssetPath(clip);
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
foreach (var curve in curveBindings)
{
AnimationCurve animCurve = AnimationUtility.GetEditorCurve(clip, curve);
if (animCurve.keys.Length > 1 && !curve.isPPtrCurve)
{
Keyframe cntKeyframe = animCurve.keys[0];
List<Keyframe> m_Keyframes = new List<Keyframe>();
m_Keyframes.Add(cntKeyframe);
int sameIndex = 0;
for (int i = 1; i < animCurve.keys.Length; ++i)
{
Keyframe item = animCurve.keys[i];
m_Keyframes.Add(item);
if (Mathf.Abs(item.value - cntKeyframe.value) > 0.00001f
|| i == animCurve.keys.Length - 1
|| Math.Abs(item.inTangent - cntKeyframe.inTangent) > 0.00001f
|| Math.Abs(item.outTangent - cntKeyframe.outTangent) > 0.00001f
|| item.tangentMode != cntKeyframe.tangentMode)
{
sameIndex = 0;
}
else
{
sameIndex += 1;
}
cntKeyframe = item;
if (sameIndex > 1)
{
m_Keyframes.RemoveAt(m_Keyframes.Count - 2);
}
}
animCurve.keys = m_Keyframes.ToArray();
AnimationUtility.SetEditorCurve(clip, curve, animCurve);
}
}
return clip;
}
[MenuItem("Assets/优化/动画/根据FBX(原始资源)生成混合动画", false, 3)]
public static void AnimationOptimization()
{
List<AnimationClip> animClips = new List<AnimationClip>();
UnityEngine.Object[] animObjs = Selection.objects;
for (int i = 0; i < animObjs.Length; i++)
{
AnimationClip anim = animObjs[i] as AnimationClip;
if (anim)
{
animClips.Add(anim);
}
}
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets);
for (int i = 0; i < objs.Length; i++)
{
string path = AssetDatabase.GetAssetPath(objs[i]);
string suffix = Path.GetExtension(path).ToLower();
if (suffix == ".fbx")
{
GetAnimationClip(path, animClips);
}
}
}
public static void GetAnimationClip(string fbxPath, List<AnimationClip> animClips)
{
UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(fbxPath);
AnimationClip idleClip = null;
for (int i = 0; i < objs.Length; i++)
{
idleClip = objs[i] as AnimationClip;
if (idleClip != null && !idleClip.name.ToLower().Contains("action"))
{
if (animClips.Count > 0)
{
if (animClips.Contains(idleClip))
CreateBlendAnimation(idleClip, fbxPath);
else
continue;
}
else
{
CreateBlendAnimation(idleClip, fbxPath);
}
}
else
continue;
}
}
public static void CreateBlendAnimation(AnimationClip idleClip, string fbxPath)
{
List<AnimationClipCurveData> lstAnimClipCurve = new List<AnimationClipCurveData>();
List<AnimationClipCurveData> lstAnimCompressClipCurve = new List<AnimationClipCurveData>();
List<AnimationClipCurveData> lstAnimBlendClipCurve = new List<AnimationClipCurveData>();
//AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(fbxPath);
ModelImporter importer = AssetImporter.GetAtPath(fbxPath) as ModelImporter;
if (idleClip == null || importer == null)
return;
if (importer.animationCompression != ModelImporterAnimationCompression.Off)
{
importer.animationCompression = ModelImporterAnimationCompression.Off;
importer.SaveAndReimport();
}
AnimationClip blendAnimClip = UnityEngine.Object.Instantiate(idleClip);
blendAnimClip.ClearCurves();
lstAnimClipCurve = RecordAnimationCurve(idleClip);
importer.animationCompression = ModelImporterAnimationCompression.KeyframeReduction;
importer.SaveAndReimport();
lstAnimCompressClipCurve = RecordAnimationCurve(idleClip);
for (int i = 0; i < lstAnimClipCurve.Count; i++)
{
string[] splitPath = lstAnimClipCurve[i].path.Split('/');
string keys = splitPath[splitPath.Length - 1];
if (saveLimitKey.ToList().Contains(keys))
{
lstAnimBlendClipCurve.Add(lstAnimClipCurve[i]);
}
else
{
lstAnimBlendClipCurve.Add(lstAnimCompressClipCurve[i]);
}
}
for (int i = 0; i < lstAnimBlendClipCurve.Count; i++)
{
AnimationClipCurveData data = lstAnimBlendClipCurve[i];
blendAnimClip.SetCurve(data.path, data.type, data.propertyName, data.curve);
}
ReduceAnimationCurve(ref blendAnimClip);
string path2 = string.Format("{0}/{1}.anim", Path.GetDirectoryName(fbxPath), idleClip.name);
SaveAnim(blendAnimClip, path2);
}
/// <summary>
/// 记录AnimationClip的曲线
/// </summary>
/// <param name="clip"></param>
/// <returns></returns>
public static List<AnimationClipCurveData> RecordAnimationCurve(AnimationClip clip)
{
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);
List<AnimationClipCurveData> curveDatas = new List<AnimationClipCurveData>();
for (int i = 0; i < curveBindings.Length; i++)
{
AnimationCurve animCurve = AnimationUtility.GetEditorCurve(clip, curveBindings[i]);
AnimationClipCurveData curveData = new AnimationClipCurveData(curveBindings[i]);
curveData.curve = animCurve;
curveDatas.Add(curveData);
}
return curveDatas;
}
/// <summary>
/// 移除动画不必要的曲线
/// </summary>
/// <param name="clip"></param>
public static void ReduceAnimationCurve(ref AnimationClip clip)
{
SerializedObject serializedObject = new SerializedObject(clip);
serializedObject.FindProperty("m_EditorCurves").arraySize = 0;
serializedObject.FindProperty("m_EulerEditorCurves").arraySize = 0;
//serializedObject.FindProperty("m_FloatCurves").arraySize = 0;
serializedObject.ApplyModifiedProperties();
}
public static void SaveAnim(AnimationClip clip, string clipName)
{
if (!Directory.Exists(Path.GetDirectoryName(clipName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(clipName));
}
//clip.legacy = true;
//clip.wrapMode = WrapMode.Loop;
AssetDatabase.CreateAsset(clip, clipName);
AssetDatabase.Refresh();
}
private static void PrintLog()
{
string path = Application.dataPath.Replace("Assets", "ProfilerData/AnimOptimize.txt");
Debug.Log(path);
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
}
if (File.Exists(path))
File.Delete(path);
foreach (var item in optAnimProperty.dicLog)
{
string labelName = string.Empty;
for (int i = 0; i < item.Value.Count; i++)
{
labelName += item.Value[i] + ",";
}
strBuilder.Append(string.Format("{0}:{1}\n", item.Key, labelName));
}
strBuilder.Append(string.Format("检索Prefab数量:{0}\n需要修改的Prefab数量:{1},占总量的:{2}%\n修改的Animation数量:{3}"
, optAnimProperty.AllPrefabNum, optAnimProperty.ModifyPrefabNum, optAnimProperty.ModifyPrefabNum * 1.0f / optAnimProperty.AllPrefabNum * 100, optAnimProperty.ModifyAnimNum));
using (StreamWriter sw = new StreamWriter(path))
{
sw.Write(strBuilder);
sw.Dispose();
}
}
}
public class OptimizeAnimationClipProperty
{
public int AllPrefabNum;
public int ModifyAnimNum;
public int ModifyPrefabNum;
public Dictionary<string, List<string>> dicLog = null;
public List<string> hadOperation = null;
public OptimizeAnimationClipProperty()
{
dicLog = new Dictionary<string, List<string>>();
hadOperation = new List<string>();
}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
public class SceneOptimize : Editor {
#region 场景优化
//某一文件夹中的所有场景的路径,复制的场景路径用于把所有场景都复制到另一个文件夹中
public static List<string> optimizedScenePaths;
//某一文件夹中的所有场景的路径
public static List<string> optimizedOriginalScenePaths;
[MenuItem("Tools/场景优化")]
public static void CopyAndOptimizeScenes()
{
//复制的场景路径
optimizedScenePaths = new List<string>();
//原来的场景路径
optimizedOriginalScenePaths = new List<string>();
//项目的路径,eg:D:/Project/Test/Assets
string headPath = Application.dataPath;
//Debug.Log(headPath);
//Debug.Log(headPath.IndexOf("Assets"));
//eg:D:/Project/Test/
headPath = headPath.Substring(0, headPath.IndexOf("Assets"));
Debug.Log(headPath);
try
{
//复制场景到另一个文件夹中
//CopyAllScenes("Assets/Level", "Assets/Level_optimized", headPath);
//获取某一文件夹中所有场景的Path信息
AddRootSourcePathToList("Assets/Level", headPath, "Scene", ref optimizedOriginalScenePaths);
}
catch (System.Exception e)
{
PlayerPrefs.SetInt("ModifySaving", 0);
Debug.LogError(e);
}
//遍历出所有场景的路径
for (int i = 0; i < optimizedOriginalScenePaths.Count; i++)
{
PlayerPrefs.SetInt("ModifySaving", 0);
//显示遍历场景时候的进度条
EditorUtility.DisplayCancelableProgressBar("Scene Optimizing Bar", "Save And Optimize Scenes" + i + "/" + optimizedOriginalScenePaths.Count, (float)i / optimizedOriginalScenePaths.Count);
try
{
Debug.Log(optimizedOriginalScenePaths[i]);
//获取到场景的完整路径
string tempPath = headPath + "Assets/Level/";
Debug.Log("tempPath :" + tempPath);
//只获取场景的名字(eg:Main.unity,Main场景的全称)
string tempScene = optimizedOriginalScenePaths[i].Substring(tempPath.Length);
Debug.Log("tempScene:" + tempScene);
//增加判断条件,对于不需要做修改的场景
if(tempScene == "Main.unity")
{
Debug.Log("Continue");
continue;
}
//打开场景
EditorSceneManager.OpenScene(optimizedOriginalScenePaths[i], OpenSceneMode.Single);
//开始优化
AudioListenerOptimize();
PlayerPrefs.SetInt("ModifySaving", 1);
//保存修改之后的场景
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
}
catch (System.Exception e)
{
PlayerPrefs.SetInt("ModifySaving", 0);
//如果发生错误,要关闭加载时候显示的滚动条
EditorUtility.ClearProgressBar();
Debug.Log(e);
}
}
//加载完毕,关闭滚动条
EditorUtility.ClearProgressBar();
Debug.Log("finished");
PlayerPrefs.SetInt("ModifySaving", 0);
}
//对于要修改的内容
public static void AudioListenerOptimize()
{
//获取一个场景中所有的绑定了AudioListener对象
AudioListener[] audios = FindObjectsOfType<AudioListener>();
for (int i = 0; i < audios.Length; i++)
{
if (audios[i] is AudioListener)
{
//移除对象身上的AudioListener组件
DestroyImmediate(audios[i].GetComponent<AudioListener>(),true);
}
}
}
/// <summary>
/// 复制场景到另一个文件夹中
/// </summary>
/// <param name="rootPath"></param>
/// <param name="targetPath"></param>
/// <param name="headPath"></param>
public static void CopyAllScenes(string rootPath, string targetPath, string headPath)
{
if (Directory.Exists(rootPath))
{
string[] guids;
guids = AssetDatabase.FindAssets("t:Scene", new[] { rootPath });
foreach (string guid in guids)
{
Debug.Log("guid: " + guid);
string source = AssetDatabase.GUIDToAssetPath(guid);
Debug.Log("source: " + source);
string dest = source;
Debug.Log("dest: " + dest);
for (int i = 0; i < CountSubString("Level", "/") + 2; i++)
{
Debug.Log("dest.IndexOf: " + dest.IndexOf("/"));
dest = dest.Substring(dest.IndexOf("/") + 1);
}
dest = "/" + dest;
Debug.Log("dest: " + dest);
dest = targetPath + dest;
Debug.Log("dest: " + dest);
CopySingleScene(source, dest, headPath);
}
}
else
{
Debug.Log("No source path");
}
}
public static void CopySingleScene(string source, string dest, string headPath)
{
source = headPath + source;
dest = headPath + dest;
string destDirectory = dest.Substring(0, dest.LastIndexOf("/"));
if (!Directory.Exists(destDirectory))
{
Directory.CreateDirectory(destDirectory);
}
dest = dest.Substring(0, dest.LastIndexOf(".")) + "_Optimized.unity";
File.Copy(source, dest, true);
optimizedScenePaths.Add(dest);
}
public static int CountSubString(string targetString, string subString)
{
int p = 0;
while (targetString.Contains(subString))
{
p++;
targetString = targetString.Substring(targetString.IndexOf(subString) + 1);
}
Debug.Log("p:" + p);
return p;
}
#endregion
/// <summary>
/// 根据在固定文件夹中的路径,根据类型(type)搜索该文件夹中的所符合的对象,然后把这些对象的路径添加到array中
/// </summary>
/// <param name="rootPath">目标文件路径(eg:Assets/Scenes)</param>
/// <param name="headPath">项目路径(eg:D:Project/Test/)</param>
/// <param name="searchType">搜索类型(Scene(搜索的是场景),Prefab(搜多的是预设))</param>
/// <param name="array"></param>
public static void AddRootSourcePathToList(string rootPath, string headPath, string searchType, ref List<string> array)
{
if (Directory.Exists(rootPath))
{
string[] guids;
//搜索
guids = AssetDatabase.FindAssets("t:" + searchType, new[] { rootPath });
foreach (string guid in guids)
{
string source = AssetDatabase.GUIDToAssetPath(guid);
//path:(D:Project/Test/Assets/Scenes/Main.unity)
string path = headPath + source;
array.Add(path);
}
}
else
{
Debug.LogError("No Find Source Path");
}
}
#region Prefab优化
public static List<string> optimizePrefabsList;
[MenuItem("Tools/预设优化")]
public static void OptimizePrefabs()
{
optimizePrefabsList = new List<string>();
string headPath = Application.dataPath;
headPath = headPath.Substring(0, headPath.IndexOf("Assets"));
Debug.Log(headPath);
try
{
AddRootSourcePathToList("Assets/CurPrefabs", headPath,"Prefab",ref optimizePrefabsList);
}
catch (System.Exception e)
{
Debug.LogError(e);
}
Debug.Log("optimizePrefabsList:" + optimizePrefabsList.Count);
for (int i = 0; i < optimizePrefabsList.Count; i++)
{
Debug.Log(optimizePrefabsList[i]);
EditorUtility.DisplayCancelableProgressBar("Prefabs Optimizing Bar", "Save And Optimize Prefabs" + i + "/" + optimizePrefabsList.Count, (float)i / optimizePrefabsList.Count);
//tempPath(eg:Assets/Prefabs/Cube.prefab)
string tempPath = optimizePrefabsList[i].Substring(headPath.Length);
//根据路径找到对象
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(tempPath);
//Debug.Log(tempPath);
//Debug.Log(prefab.name);
OptimizePrefabRemoveAudioListener(prefab);
}
EditorUtility.ClearProgressBar();
Debug.Log("finished");
}
public static void OptimizePrefabRemoveAudioListener(GameObject prefab)
{
AudioListener[] audios = prefab.GetComponentsInChildren<AudioListener>();
Debug.Log(audios.Length);
for (int i = 0; i < audios.Length; i++)
{
Debug.Log(audios[i].name);
DestroyImmediate(audios[i].GetComponent<AudioListener>(),true);
}
}
#endregion
}
下面分析Editor中的问题:
1,Unity中的Editor的基础篇:
2,Unity编辑器不用实例化Prefab获取,删除,更新组件:
Unity3D研究院编辑器之不实例化Prefab获取删除更新组件(十五) | 雨松MOMO程序研究院
3,根据对象名字,标签或者类型查找某一个文件夹中所有对象的路径
AssetDatabase-FindAssets的解析:AssetDatabase-FindAssets_京畿小李_新浪博客
4,游戏运行的时候对场景中对象的修改,通过代码控制保存的方法
5,脚本自动定位选择Hierarchy或Project下的对象
6,Unity编辑器扩展(自动保存当前打开的场景)
7,移除某个对象身上绑定的组件:
DestroyImmediate(audios[i].GetComponent<AudioListener>());
为了安全起见,我们移除的时候要添加一个参数:
对于Prefab身上的组件我们不能用DestroyImmediate(audios[i].GetComponent<AudioListener>());
方法,会报错。用DestroyImmediate(audios[i].GetComponent<AudioListener>(), true);方法