unity 程式碼批量修改Remove Missing Script和批量修改指定元件的內容
阿新 • • 發佈:2019-01-30
昨天在專案開發中,發現一個問題,就是一些指令碼已經被廢棄,但是這些廢棄指令碼還是被繫結在某些預製體中,這時候執行就會產生很多Missing Script的警告資訊,這些警告雖不影響程式碼的實際執行,但是一個大專案肯定不能出現的N多的警告資訊,並且這裡通過手動去找肯定不現實,所以這裡我們就同一個指令碼去實現自動去遍歷所有的prefab然後移除Missing的元件,下面是具體的程式碼資訊。
1.首先在工程中建立一個Editro資料夾,將指令碼放在Editor資料夾下
2.通過選中檔案,通過編輯器實現遍歷該資料夾下的所有prefab:
[MenuItem("工具/物件移除丟失指令碼")] static void GetAllGo() { //尋找你選中資料夾下的所有檔案 object[] obj = Selection.GetFiltered(typeof(object), SelectionMode.DeepAssets); for (int i = 0; i < obj.Length; i++) { //獲取檔案的字尾資訊 string ext = System.IO.Path.GetExtension(obj[i].ToString()); //這裡篩選出不是預製體的物體 if (!ext.Contains(".GameObject")) { continue; } GameObject go = (GameObject)obj[i]; // 移除子物體下的指令碼丟失 foreach (Transform trans in go.GetComponentsInChildren<Transform>(true)) { CleanMissingScript(trans.gameObject, go); } } }
3.找到prefab,去遍歷她的所有子物體,並實現直接移除相應的空元件:
static void CleanMissingScript(GameObject go, GameObject parentGO) { var components = go.GetComponents<Component>(); var serializedObject = new SerializedObject(go); var prop = serializedObject.FindProperty("m_Component"); int r = 0; for (int j = 0; j < components.Length; j++) { if (components[j] == null) { prop.DeleteArrayElementAtIndex(j - r); MyDebug.Log("成功移除丟失指令碼,gameObject name: " + go.name + " ---父類prefab name:" + parentGO.name); r++; } } serializedObject.ApplyModifiedProperties(); }
4.如果還要做其他操作,比如我們寫了一個擴充套件的button指令碼,這時候我們不可能通過手動去把所有之前的button換成新的butonPlus,所以這時候就需要去程式碼自動實現:
static void CleanMissingScript(GameObject go, GameObject parentGO) { var components = go.GetComponents<Component>(); //如果當前元件有按鈕 if (go.GetComponent<UnityEngine.UI.Button>() != null) { Button btn = go.GetAddComponent<Button>(); //copy之前的元件資訊 UnityEditorInternal.ComponentUtility.CopyComponent(btn); //移除元件資訊 GameObject.DestroyImmediate(btn); //TODO:新增新的元件資訊 } serializedObject.ApplyModifiedProperties(); }
5.下面是完整指令碼:
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
/// <summary>
/// 移除專案中go上丟失的指令碼
/// </summary>
public class RemoveMissingScript
{
[MenuItem("SlgTool/程式工具/物件移除丟失指令碼")]
static void GetAllGo()
{
object[] obj = Selection.GetFiltered(typeof(object), SelectionMode.DeepAssets);
for (int i = 0; i < obj.Length; i++)
{
string ext = System.IO.Path.GetExtension(obj[i].ToString());
Debug.Log("name:" + ext);
if (!ext.Contains(".GameObject"))
{
continue;
}
GameObject go = (GameObject)obj[i];
// 移除子物體下的指令碼丟失
foreach (Transform trans in go.GetComponentsInChildren<Transform>(true))
{
CleanMissingScript(trans.gameObject, go);
}
}
}
static void CleanMissingScript(GameObject go, GameObject parentGO)
{
var components = go.GetComponents<Component>();
var serializedObject = new SerializedObject(go);
var prop = serializedObject.FindProperty("m_Component");
int r = 0;
for (int j = 0; j < components.Length; j++)
{
if (components[j] == null)
{
prop.DeleteArrayElementAtIndex(j - r);
MyDebug.Log("成功移除丟失指令碼,gameObject name: " + go.name + " ---父類prefab name:" + parentGO.name);
r++;
}
}
serializedObject.ApplyModifiedProperties();
}
}
這裡就是一個完整的程式碼自動查詢prefab下的空元件,然後移除的程式碼。
想了解更多請新增下方公眾號,或者新增QQ群:879354767