2024-09-30 19:40:50 +08:00
|
|
|
|
#if UNITY_EDITOR
|
2024-09-29 23:31:12 +08:00
|
|
|
|
using System.Collections.Generic;
|
2024-09-29 15:59:14 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using UnityEditor.SceneManagement;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
using UnityObject = UnityEngine.Object;
|
|
|
|
|
|
2024-09-29 23:31:12 +08:00
|
|
|
|
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
internal static class UnityObjectExtensions
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
|
|
|
|
public static int GetLocalIdentifierInFile(this UnityObject unityObject)
|
|
|
|
|
{
|
|
|
|
|
PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
|
SerializedObject serializedObject = new SerializedObject(unityObject);
|
|
|
|
|
inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null);
|
|
|
|
|
SerializedProperty localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile");
|
|
|
|
|
return localIdProp.intValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
internal class ContainerMissingTypes
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
public readonly GUID AssetGUID;
|
|
|
|
|
public readonly List<ContainerMissingRefs> Recirds = new List<ContainerMissingRefs>();
|
|
|
|
|
public ContainerMissingTypes(GUID assetGUID)
|
|
|
|
|
{
|
|
|
|
|
AssetGUID = assetGUID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class MissingRefCollectUtility
|
|
|
|
|
{
|
|
|
|
|
//private readonly Dictionary<TypeData, ContainerMissingRefs> _manualRepairedMissingRefs = new Dictionary<TypeData, ContainerMissingRefs>();
|
|
|
|
|
//private readonly List<ContainerMissingTypes> _autoRepariedMissingTypes = new List<ContainerMissingTypes>();
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
private readonly List<Record> _collectedMissingTypes = new List<Record>();
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
|
|
|
|
#region Collect
|
2024-09-30 19:40:50 +08:00
|
|
|
|
public List<Record> Collect()
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
//_manualRepairedMissingRefs.Clear();
|
|
|
|
|
|
|
|
|
|
_collectedMissingTypes.Clear();
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
CollectByPrefabs(_collectedMissingTypes);
|
|
|
|
|
CollectByScriptableObjects(_collectedMissingTypes);
|
|
|
|
|
CollectByScenes(_collectedMissingTypes);
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
//ContainerMissingRefs[] result = _manualRepairedMissingRefs.Values.ToArray();
|
|
|
|
|
//_manualRepairedMissingRefs.Clear();
|
|
|
|
|
|
|
|
|
|
return _collectedMissingTypes;
|
2024-09-29 15:59:14 +08:00
|
|
|
|
}
|
2024-09-30 19:40:50 +08:00
|
|
|
|
public readonly struct Record
|
|
|
|
|
{
|
|
|
|
|
public readonly UnityObjectDataBase UnityObject;
|
|
|
|
|
public readonly ManagedReferenceMissingType[] missingTypes;
|
|
|
|
|
public Record(UnityObjectDataBase unityObject, ManagedReferenceMissingType[] missingTypes)
|
|
|
|
|
{
|
|
|
|
|
UnityObject = unityObject;
|
|
|
|
|
this.missingTypes = missingTypes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void CollectByPrefabs(List<Record> list)
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
|
|
|
|
Scene previewScene = EditorSceneManager.NewPreviewScene();
|
|
|
|
|
foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".prefab")))
|
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
var prefabAsset = AssetDatabase.LoadAssetAtPath<GameObject>(pathToPrefab);
|
|
|
|
|
var unityObjectData = new UnityObjectData(prefabAsset, pathToPrefab);
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
PrefabUtility.LoadPrefabContentsIntoPreviewScene(pathToPrefab, previewScene);
|
|
|
|
|
var prefabLoaded = previewScene.GetRootGameObjects()[0];
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
foreach (var component in prefabLoaded.GetComponentsInChildren<MonoBehaviour>())
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
if (SerializationUtility.HasManagedReferencesWithMissingTypes(component) == false) { continue; }
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(component);
|
|
|
|
|
list.Add(new Record(unityObjectData, missings));
|
2024-09-29 15:59:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
UnityObject.DestroyImmediate(prefabLoaded);
|
2024-09-29 15:59:14 +08:00
|
|
|
|
}
|
|
|
|
|
EditorSceneManager.ClosePreviewScene(previewScene);
|
|
|
|
|
}
|
2024-09-30 19:40:50 +08:00
|
|
|
|
private void CollectByScriptableObjects(List<Record> list)
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
|
|
|
|
foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".asset")))
|
|
|
|
|
{
|
|
|
|
|
var scriptableObject = AssetDatabase.LoadAssetAtPath<ScriptableObject>(pathToPrefab);
|
2024-09-30 19:40:50 +08:00
|
|
|
|
var unityObjectData = new UnityObjectData(scriptableObject, pathToPrefab);
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
if (SerializationUtility.HasManagedReferencesWithMissingTypes(scriptableObject) == false) { continue; }
|
2024-09-29 15:59:14 +08:00
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(scriptableObject);
|
|
|
|
|
list.Add(new Record(unityObjectData, missings));
|
2024-09-29 15:59:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-30 19:40:50 +08:00
|
|
|
|
private void CollectByScenes(List<Record> list)
|
2024-09-29 15:59:14 +08:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
foreach (var scene in GetAllScenesInAssets())
|
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
var unityObjectData = new SceneObjectData(scene);
|
|
|
|
|
|
2024-09-29 15:59:14 +08:00
|
|
|
|
var gameObjects = scene.GetRootGameObjects();
|
|
|
|
|
|
|
|
|
|
foreach (var objectOnScene in gameObjects)
|
|
|
|
|
{
|
|
|
|
|
foreach (var monoBehaviour in objectOnScene.GetComponentsInChildren<MonoBehaviour>())
|
|
|
|
|
{
|
2024-09-30 19:40:50 +08:00
|
|
|
|
if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false) { continue; }
|
|
|
|
|
|
|
|
|
|
var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour);
|
|
|
|
|
list.Add(new Record(unityObjectData, missings));
|
2024-09-29 15:59:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Utils
|
|
|
|
|
private static IEnumerable<Scene> GetAllScenesInAssets()
|
|
|
|
|
{
|
|
|
|
|
var oldScenesSetup = EditorSceneManager.GetSceneManagerSetup();
|
|
|
|
|
|
|
|
|
|
(bool isHasSelected, string scenePath, int identifierInFile) oldSelectedObject = default;
|
|
|
|
|
GameObject activeGameObject = Selection.activeGameObject;
|
|
|
|
|
if (activeGameObject != null)
|
|
|
|
|
{
|
|
|
|
|
oldSelectedObject.isHasSelected = true;
|
|
|
|
|
oldSelectedObject.scenePath = activeGameObject.scene.path;
|
|
|
|
|
oldSelectedObject.identifierInFile = activeGameObject.GetLocalIdentifierInFile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var pathToScene in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".unity")))
|
|
|
|
|
{
|
|
|
|
|
Scene scene = EditorSceneManager.OpenScene(pathToScene, OpenSceneMode.Single);
|
|
|
|
|
yield return scene;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorSceneManager.RestoreSceneManagerSetup(oldScenesSetup);
|
|
|
|
|
|
|
|
|
|
if (oldSelectedObject.isHasSelected)
|
|
|
|
|
{
|
|
|
|
|
Selection.activeGameObject = SceneManager.GetSceneByPath(oldSelectedObject.scenePath)
|
|
|
|
|
.GetRootGameObjects()
|
|
|
|
|
.FirstOrDefault(gameObject => gameObject.GetLocalIdentifierInFile() == oldSelectedObject.identifierInFile);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Selection.activeGameObject = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-30 19:40:50 +08:00
|
|
|
|
//private void AddMissingType(ManagedReferenceMissingType missingType, UnityObjectDataBase unityObject)
|
|
|
|
|
//{
|
|
|
|
|
// var typeData = new TypeData(missingType);
|
|
|
|
|
// var missingTypeData = new MissingTypeData(missingType, unityObject);
|
|
|
|
|
// if (_manualRepairedMissingRefs.TryGetValue(typeData, out var containerMissingTypes) == false)
|
|
|
|
|
// {
|
|
|
|
|
// containerMissingTypes = new ContainerMissingRefs(typeData);
|
|
|
|
|
// _manualRepairedMissingRefs.Add(typeData, containerMissingTypes);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// containerMissingTypes.ManagedReferencesMissingTypeDatas.Add(missingTypeData);
|
|
|
|
|
//}
|
2024-09-29 15:59:14 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
2024-09-30 19:40:50 +08:00
|
|
|
|
}
|
|
|
|
|
#endif
|