BITFALL/Assets/_Scripts/GuidFix.cs

149 lines
4.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
public class FindMissingPrefabs : EditorWindow
{
[MenuItem("Tools/Find Missing Prefabs")]
static void Init()
{
GetWindow<FindMissingPrefabs>("Find Missing Prefabs").Show();
}
private List<GameObject> missingPrefabs = new List<GameObject>();
void OnGUI()
{
if (GUILayout.Button("Find Missing Prefabs in Scene"))
{
FindMissing();
}
if (missingPrefabs.Count > 0)
{
GUILayout.Label("Missing Prefabs Found:", EditorStyles.boldLabel);
foreach (var obj in missingPrefabs.Take(32))
{
if (GUILayout.Button(obj.name))
{
Selection.activeGameObject = obj;
AutoFix(obj);
}
}
}
else
{
GUILayout.Label("No missing prefabs found.");
}
}
void FindMissing()
{
missingPrefabs.Clear();
GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>();
foreach (GameObject obj in allObjects)
{
PrefabAssetType prefabType = PrefabUtility.GetPrefabAssetType(obj);
if (prefabType == PrefabAssetType.MissingAsset)
{
if (PrefabUtility.IsAnyPrefabInstanceRoot(obj) is false)continue;
AutoFix(obj);
missingPrefabs.Add(obj);
}
}
}
private bool AutoFix(GameObject obj)
{
// 解析 name括号前的部分
Match nameMatch = Regex.Match(obj.name, @"^(.+?)\s*\(");
var name = nameMatch.Success ? nameMatch.Groups[1].Value : "N/A";
if (nameMatch.Success is false)
{
Debug.LogWarning("未能解析到Name");
return false;
}
// 解析 guid
Match guidMatch = Regex.Match(obj.name, @"guid:\s*([a-f0-9]{32})");
if (guidMatch.Success is false)
{
Debug.LogWarning("未能解析到GUID");
return false;
}
var guid = guidMatch.Success ? guidMatch.Groups[1].Value : "N/A";
var searchStr =name+ @" t:prefab";
var searchPrefabs = AssetDatabase.FindAssets(searchStr);
Debug.Log($"找到:{name}有关的{searchStr}结果:\n"+string.Join("\n",searchPrefabs));
var errorGuid = string.Empty;
switch (searchPrefabs.Length)
{
case > 1:
{
try
{
foreach (var searchId in searchPrefabs)
{
var prefabName = AssetDatabase.GUIDToAssetPath(searchId);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabName);
if (prefab.name == name)
{
errorGuid = searchId;
throw new OperationCanceledException();
}
}
Debug.LogWarning($"找到的结果有:{searchPrefabs.Length},无法自动修复");
return false;
}
catch (OperationCanceledException)
{
}
}
break;
case 1:
{
errorGuid = searchPrefabs[0];
}
break;
case 0:
{
Debug.Log("未找到");
}
break;
}
var path = AssetDatabase.GUIDToAssetPath(errorGuid);
var metaPath = path + ".meta";
metaPath = Path.Combine(Environment.CurrentDirectory, metaPath);
if (File.Exists(metaPath) is false)
{
Debug.Log($"Meta路径未找到:{{metaPath}}");
return false;
}
var str = File.ReadAllText(metaPath);
str = str.Replace(searchPrefabs[0], guid);
File.WriteAllText(metaPath, str);
Debug.Log($"{name}已修复");
return true;
}
}