添加缺失插件

This commit is contained in:
YXY
2026-03-03 18:24:17 +08:00
parent d43882c5cf
commit c979cd2a92
90 changed files with 5269 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
using System;
using System.Linq;
using UnityEngine;
namespace AssetUsageFinder {
[Serializable]
public class AssetDependencies {
public string[] DependencyGuids;
public string HashString;
[NonSerialized] Hash128 _hashCache;
public Hash128 DependencyHash {
get { return _hashCache.Equals(default(Hash128)) ? Hash128.Parse(HashString) : _hashCache; }
set {
_hashCache = value;
HashString = value.ToString();
}
}
public bool Contains(string guid) {
return DependencyGuids.Any(d => StringComparer.InvariantCultureIgnoreCase.Equals(guid, d));
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b4b690bbffa63544f9cc84b6b0bcbf18
timeCreated: 1486474181
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace AssetUsageFinder {
public class CacheManager {
Dictionary<string, AssetDependencies> _dict;
HashSet<string> _used;
// [MenuItem("Tools/LogPath")]
static void Log() {
Debug.Log(Application.temporaryCachePath);
}
public CacheManager() {
_dict = new Dictionary<string, AssetDependencies>(StringComparer.InvariantCultureIgnoreCase);
_used = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
}
public void Init() {
var serializable = Deserialize();
_dict = serializable.OnDeserialize();
}
static SerializableData Deserialize() {
SerializableData data;
string json;
if (!File.Exists(Path)) {
// not exists - write new
data = SerializableData.Empty();
json = JsonUtility.ToJson(data);
File.WriteAllText(Path, json);
}
else {
// exists
json = File.ReadAllText(Path);
if (string.IsNullOrEmpty(json)) {
// but corrupted - overwrite with new
data = SerializableData.Empty();
json = JsonUtility.ToJson(data);
File.WriteAllText(Path, json);
}
data = JsonUtility.FromJson<SerializableData>(json);
if (!SerializableData.Valid(data)) {
// but corrupted - overwrite with new
data = SerializableData.Empty();
json = JsonUtility.ToJson(data);
File.WriteAllText(Path, json);
}
// todo assert valid
}
return data;
}
static string Path => $"{Application.temporaryCachePath}/AssetUsageFinder4.json";
public void Serialize() {
var data = SerializableData.OnSerialize(_dict);
var json = JsonUtility.ToJson(data);
File.WriteAllText(Path, json);
}
internal AssetDependencies Get(string path, string guid) {
_used.Add(guid);
if (_dict.TryGetValue(guid, out var res)) {
var assetDependencyHash = AssetDatabase.GetAssetDependencyHash(path);
if (assetDependencyHash.isValid && res.DependencyHash == assetDependencyHash) {
return res;
}
res = HashByPath();
_dict[guid] = res;
return res;
}
res = HashByPath();
_dict.Add(guid, res);
return res;
AssetDependencies HashByPath() {
var dependencyPaths = AssetDatabase.GetDependencies(path, recursive: false);
var guids = dependencyPaths.Select(AssetDatabase.AssetPathToGUID).ToArray();
return new AssetDependencies {
DependencyGuids = guids,
DependencyHash = AssetDatabase.GetAssetDependencyHash(path),
};
}
}
[Serializable]
public class SerializableData {
public const int CurrentVersion = 7; // for cache invalidation
public int Version;
public string[] Keys;
public AssetDependencies[] Values;
public static SerializableData Empty() => new SerializableData() {
Keys = new string[0],
Values = new AssetDependencies[0],
Version = CurrentVersion,
};
public static SerializableData OnSerialize(Dictionary<string, AssetDependencies> dict) {
return new SerializableData() {
Keys = dict.Keys.ToArray(),
Values = dict.Values.ToArray(),
Version = CurrentVersion,
};
}
public Dictionary<string, AssetDependencies> OnDeserialize() {
var res = new Dictionary<string, AssetDependencies>(StringComparer.InvariantCultureIgnoreCase);
var keysLength = Keys.Length;
for (var i = 0; i < keysLength; i++) res.Add(Keys[i], Values[i]);
return res;
}
public static bool Valid(SerializableData that) =>
that != null && CurrentVersion == that.Version && that.Keys != null && that.Values != null && that.Keys.Length == that.Values.Length;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e70f0d094b7379b45a36f7fc76809b0a
timeCreated: 1486465336
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
[Serializable]
abstract class DependencyAbstractFinder {
public SearchTarget Target;
public ResultRow[] Dependencies;
public GUIContent TabContent;
public DependencyAbstractFinder Parent;
public string Title = "";
public List<DependencyAbstractFinder> Parents() {
var res = new List<DependencyAbstractFinder>();
for (var cur = this; cur != null; cur = cur.Parent)
res.Add(cur);
return res;
}
public IEnumerable<ResultRow> Group(IEnumerable<ResultRow> inScenePro) {
ResultRow cur = null;
var res = new List<ResultRow>();
var list = inScenePro.OrderBy(t => t.Main.GetInstanceID());
var modificationsString = "Object.Modification.Modifications";
var correpsondingString = "CorrespondingSourceObject";
var gameObjectString = "GameObject";
foreach (var source in list.ToList()) {
if (cur == null || cur.Main != source.Main) {
cur = source;
var buf = source.Properties.Where(p =>
!p.Content.text.Contains(gameObjectString) &&
!p.Content.text.Contains(modificationsString) &&
!p.Content.text.Contains(correpsondingString)).ToList();
cur.Properties = buf;
res.Add(cur);
}
else {
foreach (var item in source.Properties) {
if (
!item.Content.text.Contains(gameObjectString) &&
!item.Content.text.Contains(modificationsString) &&
!item.Content.text.Contains(correpsondingString) &&
!cur.Properties.Any(p =>
p.Content.text == item.Content.text &&
p.Content.tooltip == p.Content.tooltip)) {
cur.Properties.Add(item);
}
}
}
}
return res;
}
public abstract void FindDependencies();
public abstract DependencyAbstractFinder Nest(Object o);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 25951e74c3fd1cd40863089a51c157ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,381 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
static class DependencyFinderEngine {
#region Private
const string AssetsRootPath = "Assets/";
static double _cachedTime;
static bool NeedsUpdate {
get {
var t = _cachedTime;
_cachedTime = EditorApplication.timeSinceStartup;
var result = _cachedTime - t > 0.03;
return result;
}
}
static Option<ResultRow> GenerateResultRowByObject(SearchTarget target, Object c, bool isScene = true) {
var so = new SerializedObject(c);
var sp = so.GetIterator();
ResultRow row = null;
while (sp.Next(enterChildren: true)) {
string transformPath = string.Empty;
if (sp.propertyType != SerializedPropertyType.ObjectReference) continue;
if (!target.Check(sp.objectReferenceValue)) continue;
if (row == null) {
row = new ResultRow {
Root = c,
Target = c,
SerializedObject = so
};
if (isScene) {
var component = c as Component;
if (component) {
row.Main = component.gameObject;
}
else {
var o = c as GameObject;
if (o != null) {
row.Main = o;
}
}
var go = row.Main as GameObject;
// Assert.NotNull(go);
row.LabelContent.text = AnimationUtility.CalculateTransformPath(go.transform, null);
row.LabelContent.image = AssetPreview.GetMiniThumbnail(go);
}
else {
var path = AssetDatabase.GetAssetPath(c);
row.Main = AssetDatabase.LoadMainAssetAtPath(path);
var mainType = PrefabUtility.GetPrefabAssetType(row.Main);
if (mainType != PrefabAssetType.NotAPrefab) {
var comp = row.Target as Component;
if (comp) {
try {
transformPath = string.Format("{0}/", AnimationUtility.CalculateTransformPath(comp.transform, null)).Replace("/", "/\n");
}
catch {
// ignored
}
}
}
row.LabelContent.text = path.Replace(AssetsRootPath, string.Empty);
row.LabelContent.image = AssetDatabase.GetCachedIcon(path);
}
}
Texture2D miniTypeThumbnail = row.Main == c ? null : AssetPreview.GetMiniThumbnail(c);
row.Properties.Add(new ResultRow.PropertyData {
Property = sp.Copy(),
Content = new GUIContent {
image = miniTypeThumbnail,
text = Nicify(sp, sp.serializedObject.targetObject, row.Main, target),
tooltip = string.Format("{2}{0}.{1}", sp.serializedObject.targetObject.GetType().Name, sp.propertyPath, transformPath)
}
});
}
if (row == null)
so.Dispose();
return row;
}
public static IEnumerable<(int state, string crumbs)> Traverse(AnimatorController controller) {
for (var index = 0; index < controller.layers.Length; index++) {
var controllerLayer = controller.layers[index];
foreach (var i in Inner(controllerLayer.stateMachine, $"{controllerLayer.name}({index})"))
yield return i;
}
}
static IEnumerable<(int state, string crumbs)> Inner(AnimatorStateMachine f, string crumbs) {
foreach (var state in f.states)
yield return (state.state.GetInstanceID(), crumbs);
foreach (var child in f.stateMachines) {
foreach (var tuple in Inner(child.stateMachine, $"{crumbs}/{child.stateMachine.name}"))
yield return tuple;
}
}
// todo use GetInstanceID instead of unityobj refs
static Dictionary<int, Dictionary<int, string>> _animCache = new Dictionary<int, Dictionary<int, string>>();
static string GetBread(AnimatorController c, AnimatorState state) {
if (!_animCache.TryGetValue(c.GetInstanceID(), out var res)) {
res = new Dictionary<int, string>();
_animCache.Add(c.GetInstanceID(), res);
foreach (var (stateId, crumbs) in Traverse(c))
res.Add(stateId, crumbs);
}
if (res.TryGetValue(state.GetInstanceID(), out var crumb))
return $"{crumb}/";
return string.Empty;
}
static string Nicify(SerializedProperty sp, Object o, Object main, SearchTarget target) {
// return sp.propertyPath;
string nice = string.Empty;
switch (o) {
case AnimatorController _: {
return Nice(sp.propertyPath);
}
case BlendTree blendTree: {
return $"{blendTree.name}({o.GetType().Name})";
}
case AnimatorState animatorState: {
if (main is AnimatorController animatorController) {
var bread = GetBread(animatorController, animatorState);
return $"{bread}{animatorState.name}";
}
break;
}
case StateMachineBehaviour smb: {
var ctx = AnimatorController.FindStateMachineBehaviourContext(smb);
if (ctx.Length == 0)
break;
var first = ctx[0];
var bread = string.Empty;
switch (first.animatorObject) {
case AnimatorStateMachine _:
// nothing
break;
case AnimatorState ast: {
bread = GetBread(first.animatorController, ast);
break;
}
}
return $"{bread}{first.animatorObject.name}";
}
case Material _:
nice = sp.displayName;
break;
default: {
nice = Nice(sp.propertyPath);
break;
}
}
nice = string.Format("{0}.{1}", o.GetType().Name, nice);
return nice;
}
static string Nice(string path) {
var nice = path.Replace(".Array.data", string.Empty);
if (nice.IndexOf(".m_PersistentCalls.m_Calls", StringComparison.Ordinal) > 0) {
nice = nice.Replace(".m_PersistentCalls.m_Calls", string.Empty)
.Replace(".m_Target", string.Empty);
}
if (nice.StartsWith("m_", StringComparison.Ordinal))
nice = nice.Replace("m_", string.Empty);
nice = nice.Split('.').Select(t => ObjectNames.NicifyVariableName(t).Replace(" ", string.Empty)).Aggregate((a, b) => a + "." + b);
return nice;
}
public static IEnumerable<T> AsEnumerable<T>(T o) {
yield return o;
}
#endregion
#region Project
static HashSet<string> GetDependencies(Object activeObject) {
var targetPath = AssetDatabase.GetAssetPath(activeObject);
var targetGuid = AssetDatabase.AssetPathToGUID(targetPath);
var objectGuids = AssetDatabase.FindAssets("t:Object");
var results = new HashSet<string>(StringComparer.Ordinal);
var total = objectGuids.LongLength;
var cache = Globals<CacheManager>.Get();
try {
for (int i = 0; i < total; i++) {
var path = AssetDatabase.GUIDToAssetPath(objectGuids[i]);
var res = cache.Get(path, objectGuids[i]);
if (path.Contains(".unity"))
continue;
if (res.Contains(targetGuid))
results.Add(path);
if (!NeedsUpdate) continue;
if (EditorUtility.DisplayCancelableProgressBar("Generating cache", "Searching for file usages", (float) i / total))
break;
}
}
finally {
cache.Serialize();
EditorUtility.ClearProgressBar();
}
results.Remove(targetPath);
return results;
}
public static IEnumerable<ResultRow> GetFilesThatReference(SearchTarget target) {
return GetDependencies(target.Target)
.SelectMany(p => AssetDatabase.LoadAllAssetsAtPath(p))
.Where(t => t && !(t is DefaultAsset) && !(t is Transform))
.Select(asset => GenerateResultRowByObject(target, asset, false))
.Where(row => row.HasValue)
.Select(r => r.GetOrFail());
}
public static HashSet<string> GetScenesThatContain(Object activeObject) {
var targetPath = AssetDatabase.GetAssetPath(activeObject);
var targetGuid = AssetDatabase.AssetPathToGUID(targetPath);
var results = new HashSet<string>(StringComparer.Ordinal);
var sceneGuids = AssetDatabase.FindAssets("t:Scene");
var total = sceneGuids.LongLength;
var cache = Globals<CacheManager>.Get();
try {
for (int i = 0; i < total; i++) {
var path = AssetDatabase.GUIDToAssetPath(sceneGuids[i]);
var res = cache.Get(path, sceneGuids[i]);
if (res.Contains(targetGuid))
results.Add(path);
if (!NeedsUpdate) continue;
if (EditorUtility.DisplayCancelableProgressBar("Searching for file usages in scenes..", path, (float) i / total))
break;
}
}
finally {
cache.Serialize();
EditorUtility.ClearProgressBar();
}
EditorUtility.ClearProgressBar();
results.Remove(targetPath);
return results;
}
#endregion Project
public static IEnumerable<ResultRow> GetDependenciesInScene(SearchTarget target) {
var referencedBy = new List<ResultRow>();
for (int ii = 0; ii < SceneManager.sceneCount; ii++) {
var currentScene = SceneManager.GetSceneAt(ii);
if (!currentScene.IsValid() || !currentScene.isLoaded)
continue;
var allObjects = currentScene
.GetRootGameObjects()
.SelectMany(g => {
if (g != target.Target)
return g.GetComponentsInChildren<Component>(true)
.Where(FilterComponents).Union(AsEnumerable(g as Object));
return g.GetComponentsInChildren<Component>(true).Where(FilterComponents);
})
.Where(t => t)
.ToArray();
var total = allObjects.Length;
var step = total / 5;
try {
if (target.Nested.TryGet(out var nested))
foreach (var n in nested) {
var searchTarget = SearchTarget.CreateSceneNested(n);
for (var i = 0; i < total; i++) {
var comp = allObjects[i];
if (!GenerateResultRowByObject(target, comp).TryGet(out var res))
continue;
if (res != null && target.Target != res.Main)
referencedBy.Add(res);
if (!GenerateResultRowByObject(searchTarget, comp).TryGet(out var resultNested))
continue;
if (resultNested != null && searchTarget.Target != resultNested.Main)
referencedBy.Add(resultNested);
if (step == 0) continue;
if (i % step != 0) continue;
if (EditorUtility.DisplayCancelableProgressBar("Searching for file usages in current scene..", target.Target.name, (float) i / total))
break;
}
}
}
finally {
EditorUtility.ClearProgressBar();
}
}
return referencedBy.Distinct().ToList();
}
static bool FilterComponents(Component c) {
switch (c) {
case Transform _:
return false;
default:
return true;
}
}
public static IEnumerable<ResultRow> GetDependenciesInStage(SearchTarget target, UnityEditor.SceneManagement.PrefabStage stage) {
var referencedBy = new List<ResultRow>();
var allObjects = stage.scene
.GetRootGameObjects()
.SelectMany(g => {
if (g != target.Target)
return g.GetComponentsInChildren<Component>(true).Where(FilterComponents).Union(AsEnumerable(g as Object));
return g.GetComponentsInChildren<Component>(true).Where(FilterComponents);
}).ToArray();
var total = allObjects.Length;
for (int i = 0; i < total; i++) {
var comp = allObjects[i];
if (!GenerateResultRowByObject(target, comp).TryGet(out var res))
continue;
referencedBy.Add(res);
if (EditorUtility.DisplayCancelableProgressBar("Searching for file usages in current scene..", target.Target.name, (float) i / total))
break;
}
EditorUtility.ClearProgressBar();
return referencedBy;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8a6622c947e860548bd95915e407658e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using System;
using System.Diagnostics;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
using UnityEngine.Assertions;
namespace AssetUsageFinder {
[Serializable]
sealed class FileDependencyFinder : DependencyAbstractFinder {
public class Pair {
public string NicifiedPath;
public string Path;
}
public Pair[] ScenePaths;
public FileDependencyFinder(Object target) {
Asr.IsTrue(target, "Asset you're trying to search is corrupted");
Target = SearchTarget.CreateFile(target);
FindDependencies();
var path = AssetDatabase.GetAssetPath(Target.Target);
Title = path;
TabContent = new GUIContent {
text = target.name,
image = AssetDatabase.GetCachedIcon(path)
};
}
public override void FindDependencies() {
var files = DependencyFinderEngine.GetFilesThatReference(Target);
Dependencies = Group(files.Where(f => !(f.Target is SceneAsset)))
.OrderBy(t => t.LabelContent.text, StringComparer.Ordinal)
.ToArray();
}
public override DependencyAbstractFinder Nest(Object o) {
return new FileDependencyFinder(o) {Parent = this};
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c4b883461f4461438dae02eba435811
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using System;
namespace AssetUsageFinder {
static class Globals<T> where T : class {
static T _instance;
public static void TryInit(Func<T> ctor) {
if (_instance != null) return;
_instance = ctor.Invoke();
}
public static T Get() => _instance;
public static T GetOrCreate(Func<T> ctor) {
TryInit(ctor);
return _instance;
}
public static void Set(T value) => _instance = value;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2dee75149ff4451a979163c53566150c
timeCreated: 1587621466

View File

@@ -0,0 +1,37 @@
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
[Serializable]
sealed class InSceneDependencyFinder : DependencyAbstractFinder {
[SerializeField] string _scenePath;
public InSceneDependencyFinder(Object target, string scenePath) {
Target = SearchTarget.CreateScene(target, scenePath);
_scenePath = scenePath;
Title = scenePath;
var name = target is Component ? target.GetType().Name : target.name;
TabContent = new GUIContent {
text = name,
image = AssetPreview.GetMiniTypeThumbnail(Target.Target.GetType()) ?? AssetPreview.GetMiniThumbnail(Target.Target)
};
FindDependencies();
}
public override void FindDependencies() {
var dependenciesInScene = DependencyFinderEngine.GetDependenciesInScene(Target);
Dependencies = Group(dependenciesInScene).ToArray();
}
public override DependencyAbstractFinder Nest(Object o) {
return new InSceneDependencyFinder(o, _scenePath) {Parent = this};
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 925da3bd0dee034418ecb5cf800a3526
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
[Serializable]
sealed class InStageDependencyFinder : DependencyAbstractFinder {
[SerializeField] string _stagePath;
[SerializeField] UnityEditor.SceneManagement.PrefabStage _stage;
public InStageDependencyFinder(Object target, string stagePath) {
Target = SearchTarget.CreateStage(target, stagePath);
_stagePath = stagePath;
_stage = Target.Stage;
Title = stagePath;
var name = target is Component ? target.GetType().Name : target.name;
TabContent = new GUIContent {
text = name,
image = AssetPreview.GetMiniTypeThumbnail(Target.Target.GetType()) ?? AssetPreview.GetMiniThumbnail(Target.Target)
};
FindDependencies();
}
public override void FindDependencies() {
Dependencies = Group(DependencyFinderEngine.GetDependenciesInStage(Target, _stage)).ToArray();
}
public override DependencyAbstractFinder Nest(Object o) {
return new InStageDependencyFinder(o, _stagePath) {Parent = this};
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 584109c30c0a0d849bbc12ec89d8c597
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
[Serializable]
class ResultRow {
[Serializable]
public class PropertyData {
public SerializedProperty Property;
public GUIContent Content;
}
public Object Target;
public SerializedObject SerializedObject;
public List<PropertyData> Properties = new List<PropertyData>();
public Object Root;
public GUIContent LabelContent = new GUIContent();
public GUIContent PropertyFieldContent = new GUIContent();
public Object Main;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 40006b038ab829f4698bcebf3c1508f1
timeCreated: 1467625979
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,119 @@
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
using static AssetUsageFinder.PrefabUtilities;
using Object = UnityEngine.Object;
namespace AssetUsageFinder {
[Serializable]
class SearchTarget {
public static SearchTarget CreateStage(Object target, string sceneOrStagePath = null) {
return new SearchTarget(target, FindModeEnum.Stage, sceneOrStagePath);
}
public static SearchTarget CreateFile(Object target, string sceneOrStagePath = null) {
return new SearchTarget(target, FindModeEnum.File, sceneOrStagePath);
}
public static SearchTarget CreateScene(Object target, string sceneOrStagePath = null) {
return new SearchTarget(target, FindModeEnum.Scene, sceneOrStagePath);
}
public static SearchTarget CreateSceneNested(Object target) {
return new SearchTarget(target, FindModeEnum.Scene) {IsNested = true};
}
public Object Target;
public Option<Object[]> Nested;
public Object Root;
public Scene Scene;
public UnityEditor.SceneManagement.PrefabStage Stage;
public bool IsNested;
SearchTarget(Object target, FindModeEnum findMode, string sceneOrStagePath = null) {
Asr.IsNotNull(target, "Asset you're trying to search is corrupted");
Target = target;
var path = sceneOrStagePath ?? AssetDatabase.GetAssetPath(Target);
switch (findMode) {
case FindModeEnum.File: {
Asr.IsTrue(string.IsNullOrEmpty(sceneOrStagePath));
Root = AssetDatabase.LoadMainAssetAtPath(path);
if (!IsNested)
Nested = AufUtils.LoadAllAssetsAtPath(path);
if (AssetDatabase.GetMainAssetTypeAtPath(path).IsAssignableFrom(typeof(SceneAsset)))
Scene = SceneManager.GetSceneByPath(path);
}
break;
case FindModeEnum.Scene:
case FindModeEnum.Stage: {
Root = Target;
var asset = AssetDatabase.GetAssetPath(target);
if (Target is GameObject go) {
switch (PrefabUtility.GetPrefabAssetType(go)) {
case PrefabAssetType.Regular:
case PrefabAssetType.Variant: {
if (!IsNested)
Nested = string.IsNullOrEmpty(asset) ? go.GetComponents<Component>() : AssetDatabase.LoadAllAssetsAtPath(asset);
break;
}
case PrefabAssetType.Model: {
if (!IsNested)
Nested = AssetDatabase.LoadAllAssetsAtPath(asset);
break;
}
case PrefabAssetType.MissingAsset:
case PrefabAssetType.NotAPrefab:
if (!IsNested)
Nested = go.GetComponents<Component>().Union(Enumerable.Repeat(Target, 1)).ToArray();
break;
}
Stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
if (findMode == FindModeEnum.Scene) {
if (string.IsNullOrEmpty(sceneOrStagePath))
sceneOrStagePath = go.scene.path;
Scene = SceneManager.GetSceneByPath(sceneOrStagePath);
}
}
else if (Target is Component c) {
// prefab instance
Nested = default;
if (findMode == FindModeEnum.Scene) {
if (string.IsNullOrEmpty(sceneOrStagePath))
sceneOrStagePath = c.gameObject.scene.path;
Scene = SceneManager.GetSceneByPath(sceneOrStagePath);
}
}
else {
if (!IsNested)
Nested = AssetDatabase.LoadAllAssetsAtPath(asset);
if (AssetDatabase.GetMainAssetTypeAtPath(path).IsAssignableFrom(typeof(SceneAsset)))
Scene = SceneManager.GetSceneByPath(path);
}
}
break;
}
Asr.IsTrue(!IsNested || !Nested.HasValue);
}
public bool Check(Object arg) {
if (arg == null || Target == null) return false;
if (arg == Target) return true;
if (!Nested.TryGet(out var n)) return false;
var length = n.Length;
for (var i = 0; i < length; i++)
if (n[i] == arg)
return true;
return false;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f500aea056165bb4294b484f1c9623d3
timeCreated: 1467656394
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: