Unity 重置專案資源的guid
阿新 • • 發佈:2019-01-09
有時需要將多個專案的資源合併到一個專案中,但有可能有些資源是共用的,它的guid是一樣的,這樣合併到一個專案時,可能會超成衝突。
如果要讓每個資源的guid都不相同,就需要重新生成guid,並且更新引用。下面是步驟
1. UNITY選單-> Editor > Project Setting - > Editor
設定 Version Controller 為Visible Meta Files
2. Asset Serialization 設定為 Force Text
3. 下面是程式碼
using System; using System.Collections.Generic; using System.IO; using UnityEditor; namespace UnityGuidRegenerator { public class UnityGuidRegeneratorMenu { [MenuItem("Tools/Regenerate asset GUIDs")] public static void RegenerateGuids() { if (EditorUtility.DisplayDialog("GUIDs regeneration", "You are going to start the process of GUID regeneration. This may have unexpected results. \n\n MAKE A PROJECT BACKUP BEFORE PROCEEDING!", "Regenerate GUIDs", "Cancel")) { try { AssetDatabase.StartAssetEditing(); string path = Path.GetFullPath(".") + Path.DirectorySeparatorChar + "Assets/_Game";//要更新guid的資料夾 UnityGuidRegenerator regenerator = new UnityGuidRegenerator(path); regenerator.RegenerateGuids(); } finally { AssetDatabase.StopAssetEditing(); EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); } } } } internal class UnityGuidRegenerator { private static readonly string[] kDefaultFileExtensions = { // "*.meta", // "*.mat", // "*.anim", // "*.prefab", // "*.unity", // "*.asset" "*.*" }; private readonly string _assetsPath; public UnityGuidRegenerator(string assetsPath) { _assetsPath = assetsPath; } public void RegenerateGuids(string[] regeneratedExtensions = null) { if (regeneratedExtensions == null) { regeneratedExtensions = kDefaultFileExtensions; } // Get list of working files List<string> filesPaths = new List<string>(); foreach (string extension in regeneratedExtensions) { filesPaths.AddRange( Directory.GetFiles(_assetsPath, extension, SearchOption.AllDirectories) ); } // Create dictionary to hold old-to-new GUID map Dictionary<string, string> guidOldToNewMap = new Dictionary<string, string>(); Dictionary<string, List<string>> guidsInFileMap = new Dictionary<string, List<string>>(); // We must only replace GUIDs for Resources present in Assets. // Otherwise built-in resources (shader, meshes etc) get overwritten. HashSet<string> ownGuids = new HashSet<string>(); // Traverse all files, remember which GUIDs are in which files and generate new GUIDs int counter = 0; foreach (string filePath in filesPaths) { EditorUtility.DisplayProgressBar("Scanning Assets folder", MakeRelativePath(_assetsPath, filePath), counter / (float) filesPaths.Count); string contents = File.ReadAllText(filePath); IEnumerable<string> guids = GetGuids(contents); bool isFirstGuid = true; foreach (string oldGuid in guids) { // First GUID in .meta file is always the GUID of the asset itself if (isFirstGuid && Path.GetExtension(filePath) == ".meta") { ownGuids.Add(oldGuid); isFirstGuid = false; } // Generate and save new GUID if we haven't added it before if (!guidOldToNewMap.ContainsKey(oldGuid)) { string newGuid = Guid.NewGuid().ToString("N"); guidOldToNewMap.Add(oldGuid, newGuid); } if (!guidsInFileMap.ContainsKey(filePath)) guidsInFileMap[filePath] = new List<string>(); if (!guidsInFileMap[filePath].Contains(oldGuid)) { guidsInFileMap[filePath].Add(oldGuid); } } counter++; } // Traverse the files again and replace the old GUIDs counter = -1; int guidsInFileMapKeysCount = guidsInFileMap.Keys.Count; foreach (string filePath in guidsInFileMap.Keys) { EditorUtility.DisplayProgressBar("Regenerating GUIDs", MakeRelativePath(_assetsPath, filePath), counter / (float) guidsInFileMapKeysCount); counter++; string contents = File.ReadAllText(filePath); foreach (string oldGuid in guidsInFileMap[filePath]) { if (!ownGuids.Contains(oldGuid)) continue; string newGuid = guidOldToNewMap[oldGuid]; if (string.IsNullOrEmpty(newGuid)) throw new NullReferenceException("newGuid == null"); contents = contents.Replace("guid: " + oldGuid, "guid: " + newGuid); } File.WriteAllText(filePath, contents); } EditorUtility.ClearProgressBar(); } private static IEnumerable<string> GetGuids(string text) { const string guidStart = "guid: "; const int guidLength = 32; int textLength = text.Length; int guidStartLength = guidStart.Length; List<string> guids = new List<string>(); int index = 0; while (index + guidStartLength + guidLength < textLength) { index = text.IndexOf(guidStart, index, StringComparison.Ordinal); if (index == -1) break; index += guidStartLength; string guid = text.Substring(index, guidLength); index += guidLength; if (IsGuid(guid)) { guids.Add(guid); } } return guids; } private static bool IsGuid(string text) { for (int i = 0; i < text.Length; i++) { char c = text[i]; if ( !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')) ) return false; } return true; } private static string MakeRelativePath(string fromPath, string toPath) { Uri fromUri = new Uri(fromPath); Uri toUri = new Uri(toPath); Uri relativeUri = fromUri.MakeRelativeUri(toUri); string relativePath = Uri.UnescapeDataString(relativeUri.ToString()); return relativePath; } } }