プレハブミススクリプトコンポーネントの統一を達成するためのバッチ削除

ありがとう:https://www.cnblogs.com/AaronBlogs/p/7976054.html 

マイUnityバージョン:unity2017.2.0p4

この記事では、いくつかのケースでは、それは考慮に入れられないかもしれない、私の個人的な練習を記録します。アップグレード版のUnityと、準備APIが直接実装することができますがあるかもしれません(GameObjectUtility.RemoveMonoBehavioursWithMissingScript(GO)でunity2019のように、具体的なテストはありません)

目標:

   図の次の動作の場合には復元されません。

最初のスクリプトを欠場両方のケースでは、説明します。

   、対応するプレハブファイルを開くようInpsectorパネルのルックスで、ダウン特有の違いを見続けています。

実行後の工具交換プレハブ文書には、次のような構造になりました。

以下のコードを貼り付けます。

  1 using System;
  2 using System.IO;
  3 using System.Collections;
  4 using System.Collections.Generic;
  5 using UnityEngine;
  6 using UnityEditor;
  7 using System.Text.RegularExpressions;
  8 
  9 namespace LgsProject
 10 {
 11     public partial class LgsTools_Optimization
 12     {
 13         [MenuItem("LgsTools/智能检测/Remove Missing-MonoBehavior Component")]
 14         static public void RemoveMissComponent()
 15         {
 16             string fullPath = Application.dataPath + "/Art/Prefabs";
 17             fullPath = fullPath.Replace("/", @"\");
 18             List<string> pathList = GetAssetsPath(fullPath, "*.prefab", SearchOption.AllDirectories);
 19             int counter = 0;
 20             for (int i = 0, iMax = pathList.Count; i < iMax; i++)
 21             {
 22                 EditorUtility.DisplayProgressBar("处理进度", string.Format("{0}/{1}", i + 1, iMax), (i + 1f) / iMax);
 23                 if (CheckMissMonoBehavior(pathList[i]))
 24                     ++counter;
 25             }
 26             EditorUtility.ClearProgressBar();
 27             EditorUtility.DisplayDialog("处理结果", "完成修改,修改数量 : " + counter, "确定");
 28             AssetDatabase.Refresh();
 29         }
 30 
 31         /// <summary>
 32         /// 获取某种资源的路径
 33         /// </summary>
 34         /// <param name="fullPath">例如 : Application.dataPath + "/Art/Prefabs" </param>
 35         /// <param name="filter">例如 : *.prefab</param>
 36         /// <param name="searchOption">目录的搜索方式</param>
 37         /// <returns></returns>
 38         static List<string> GetAssetsPath(string fullPath, string filter, SearchOption searchOption)
 39         {
 40             List<string> pathList = new List<string>();
 41             string[] files = Directory.GetFiles(fullPath, filter, searchOption);
 42             for (int i = 0; i < files.Length; i++)
 43             {
 44                 string path = files[i];
 45                 path = "Assets" + path.Substring(Application.dataPath.Length, path.Length - Application.dataPath.Length);
 46                 pathList.Add(path);
 47             }
 48 
 49             return pathList;
 50         }
 51 
 52         /// <summary>  
 53         /// 删除一个Prefab上的空脚本  
 54         /// </summary>  
 55         /// <param name="path">prefab路径 例Assets/Resources/FriendInfo.prefab</param>  
 56         static bool CheckMissMonoBehavior(string path)
 57         {
 58             bool isNull = false;
 59             string s = File.ReadAllText(path);
 60             Regex regBlock = new Regex("MonoBehaviour");
 61             // 以"---"划分组件  
 62             string[] strArray = s.Split(new string[] { "---" }, StringSplitOptions.RemoveEmptyEntries);
 63             for (int i = 0; i < strArray.Length; i++)
 64             {
 65                 string blockStr = strArray[i];
 66                 if (regBlock.IsMatch(blockStr))
 67                 {
 68                     // 模块是 MonoBehavior  
 69                     Match guidMatch = Regex.Match(blockStr, "m_Script: {fileID: (.*), guid: (?<GuidValue>.*?), type:");
 70                     Match guidMatch_1 = Regex.Match(blockStr, "m_Script: {fileID: (.*)");
 71 
 72                     if (guidMatch.Success || guidMatch_1.Success)
 73                     {
 74                         // 获取 MonoBehavior的guid  
 75                         string guid = guidMatch.Groups["GuidValue"].Value;
 76                         Debug.Log("Guid:" + guid);
 77                         string tempPath = AssetDatabase.GUIDToAssetPath(guid);
 78 
 79                         if (string.IsNullOrEmpty(tempPath) || !File.Exists(tempPath))
 80                         {
 81                             isNull = true;
 82                             // 删除操作  
 83                             // 删除MonoScript  
 84                             s = s.Replace("---" + blockStr, "");
 85                             Match idMatch = Regex.Match(blockStr, "!u!(.*) &(?<idValue>.*?)\n");
 86                             if (idMatch.Success)
 87                             {
 88                                 // 获取 MonoBehavior的guid  
 89                                 string id = idMatch.Groups["idValue"].Value;
 90                                 // 删除MonoScript的引用
 91                                 Regex quote = new Regex("  - (.*): {fileID: " + id + "}\n");
 92                                 s = quote.Replace(s, "");
 93                             }
 94                         }
 95                     }
 96                 }
 97             }
 98             if (isNull)
 99             {
100                 // 有空脚本 写回prefab  
101                 File.WriteAllText(path, s);
102             }
103             return isNull;
104         }
105     }
106 }

另外,在实践的过程中遇到了一个报错,顺便记录一下:

CheckConsistency: GameObject does not reference component MonoBehaviour. Fixing.

看下图,正常情况下prefab文件中区域1和区域2是对应的,如果不对应会报以上错误。

おすすめ

転載: www.cnblogs.com/luguoshuai/p/12323186.html