整合SLSUtilities
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "LunaWolfStudiosEditor.ScriptableSheets.Scanning",
|
||||
"rootNamespace": "LunaWolfStudiosEditor.ScriptableSheets.Scanning",
|
||||
"references": [
|
||||
"GUID:b37e9192bd2da3f4cbecf27120ea8f63",
|
||||
"GUID:da9a3cdcbea6eb84fa9a4e997b44b7b3"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0442c8337274c4247bf01f0da6282230
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/LunaWolfStudiosEditor.ScriptableSheets.Scanning.asmdef
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,215 @@
|
||||
using LunaWolfStudiosEditor.ScriptableSheets.Layout;
|
||||
using LunaWolfStudiosEditor.ScriptableSheets.Shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Scanning
|
||||
{
|
||||
public class ObjectScanner
|
||||
{
|
||||
private const string ProgressBarTitle = "Scriptable Sheets - Object Scanner";
|
||||
|
||||
private readonly Dictionary<Type, List<Object>> m_ObjectsByType = new Dictionary<Type, List<Object>>();
|
||||
public Dictionary<Type, List<Object>> ObjectsByType => m_ObjectsByType;
|
||||
|
||||
private Type[] m_ObjectTypes;
|
||||
public Type[] ObjectTypes => m_ObjectTypes;
|
||||
|
||||
private string[] m_ObjectTypeNames;
|
||||
public string[] ObjectTypeNames => m_ObjectTypeNames;
|
||||
|
||||
private string[] m_FriendlyObjectTypeNames;
|
||||
public string[] FriendlyObjectTypeNames => m_FriendlyObjectTypeNames;
|
||||
|
||||
private readonly Dictionary<Type, Dictionary<Object, List<Object>>> m_SubAssetsByTypeAndMainAsset = new Dictionary<Type, Dictionary<Object, List<Object>>>();
|
||||
public Dictionary<Type, Dictionary<Object, List<Object>>> SubAssetsByTypeAndMainAsset => m_SubAssetsByTypeAndMainAsset;
|
||||
|
||||
public void ScanObjects(ScanSettings settings, SheetAsset sheetAsset)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_ObjectsByType.Clear();
|
||||
m_SubAssetsByTypeAndMainAsset.Clear();
|
||||
|
||||
// Refresh incase new folders or assets were created.
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
// Unity does not consider the root Packages folder as a valid folder so we need to check it separately.
|
||||
if (settings.PathOption == ScanPathOption.Default && !AssetDatabase.IsValidFolder(settings.Path) && settings.Path != UnityConstants.Packages)
|
||||
{
|
||||
settings.Path = UnityConstants.DefaultAssetPath;
|
||||
}
|
||||
|
||||
var scanPaths = settings.GetScanPaths();
|
||||
var joinedPaths = settings.GetJoinedScanPaths(scanPaths);
|
||||
|
||||
if (settings.ShowProgressBar)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar(ProgressBarTitle, $"Scanning for assets of type {sheetAsset} at path(s) {joinedPaths}", 0.40f);
|
||||
}
|
||||
|
||||
var guids = AssetDatabase.FindAssets($"t:{sheetAsset}", scanPaths);
|
||||
|
||||
if (settings.ShowProgressBar)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar(ProgressBarTitle, $"Loading assets of type {sheetAsset} at path(s) {joinedPaths}", 0.80f);
|
||||
}
|
||||
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var assetType = asset.GetType();
|
||||
var nextAssetType = assetType;
|
||||
// Map the asset to its type and base types.
|
||||
while (nextAssetType.IsValidUnityObjectSubclass())
|
||||
{
|
||||
if (nextAssetType.IsValidConcreteType())
|
||||
{
|
||||
if (!m_ObjectsByType.TryGetValue(nextAssetType, out var objectsByType))
|
||||
{
|
||||
objectsByType = new List<Object>();
|
||||
m_ObjectsByType[nextAssetType] = objectsByType;
|
||||
}
|
||||
objectsByType.Add(asset);
|
||||
}
|
||||
nextAssetType = nextAssetType.BaseType;
|
||||
}
|
||||
|
||||
if (sheetAsset == SheetAsset.Scene)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var subAssets = AssetDatabase.LoadAllAssetsAtPath(path);
|
||||
if (subAssets.Length <= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var subAsset in subAssets)
|
||||
{
|
||||
if (subAsset == null || subAsset == asset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (sheetAsset == SheetAsset.Prefab)
|
||||
{
|
||||
if (subAsset is Component)
|
||||
{
|
||||
var subAssetGameObject = ((Component) subAsset).gameObject;
|
||||
var isRootPrefab = asset == subAssetGameObject;
|
||||
if (!settings.RootPrefabsOnly || isRootPrefab)
|
||||
{
|
||||
var subAssetType = subAsset.GetType();
|
||||
if (!m_ObjectsByType.TryGetValue(subAssetType, out var objectsByType))
|
||||
{
|
||||
objectsByType = new List<Object>();
|
||||
m_ObjectsByType[subAssetType] = objectsByType;
|
||||
}
|
||||
objectsByType.Add(subAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AssetDatabase.IsSubAsset(subAsset))
|
||||
{
|
||||
var subAssetType = subAsset.GetType();
|
||||
var nextSubAssetType = subAssetType;
|
||||
while (nextSubAssetType.IsValidUnityObjectSubclass())
|
||||
{
|
||||
// For binary types like Textures we want to add all the valid subclass types.
|
||||
// For ScriptableObjects it must be a scriptable object type.
|
||||
if (sheetAsset != SheetAsset.ScriptableObject || nextSubAssetType.IsSubclassOf(typeof(ScriptableObject)))
|
||||
{
|
||||
if (!m_ObjectsByType.TryGetValue(nextSubAssetType, out var objectsByType))
|
||||
{
|
||||
objectsByType = new List<Object>();
|
||||
m_ObjectsByType[nextSubAssetType] = objectsByType;
|
||||
}
|
||||
objectsByType.Add(subAsset);
|
||||
if (!m_SubAssetsByTypeAndMainAsset.TryGetValue(nextSubAssetType, out var subAssetByMainAsset))
|
||||
{
|
||||
subAssetByMainAsset = new Dictionary<Object, List<Object>>();
|
||||
m_SubAssetsByTypeAndMainAsset[nextSubAssetType] = subAssetByMainAsset;
|
||||
}
|
||||
if (!subAssetByMainAsset.TryGetValue(asset, out var subAssetList))
|
||||
{
|
||||
subAssetList = new List<Object>();
|
||||
subAssetByMainAsset[asset] = subAssetList;
|
||||
}
|
||||
subAssetList.Add(subAsset);
|
||||
}
|
||||
nextSubAssetType = nextSubAssetType.BaseType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.ShowProgressBar)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar(ProgressBarTitle, $"Resolving {sheetAsset} types using {nameof(ScanOption)} {settings.Option}", 0.90f);
|
||||
}
|
||||
|
||||
if (sheetAsset == SheetAsset.ScriptableObject && settings.Option == ScanOption.Assembly)
|
||||
{
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
var objectTypes = new List<Type>();
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
var types = assembly.GetTypes().Where
|
||||
(
|
||||
type => type.IsSubclassOf(typeof(ScriptableObject))
|
||||
&& type.IsSerializable
|
||||
&& type.IsValidConcreteType()
|
||||
&& !type.IsSubclassOf(typeof(Editor))
|
||||
&& !type.IsSubclassOf(typeof(EditorWindow))
|
||||
&& !type.IsScriptableSingleton()
|
||||
);
|
||||
objectTypes.AddRange(types);
|
||||
}
|
||||
m_ObjectTypes = objectTypes.Concat(m_ObjectsByType.Keys).Distinct().OrderBy(type => type.FullName).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ObjectTypes = m_ObjectsByType.Keys.OrderBy(type => type.FullName).ToArray();
|
||||
}
|
||||
|
||||
if (settings.ShowProgressBar)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar(ProgressBarTitle, $"Finalizing {sheetAsset} type names", 0.98f);
|
||||
}
|
||||
|
||||
m_ObjectTypeNames = m_ObjectTypes.Select(type => type.FullName).ToArray();
|
||||
// Submenu once we start having a lot of Objects.
|
||||
var separator = '.';
|
||||
if (m_ObjectTypeNames.Length > SheetLayout.SubMenuThreshold)
|
||||
{
|
||||
var newSeparator = '/';
|
||||
m_ObjectTypeNames = m_ObjectTypeNames.Select(s => s.Replace(separator, newSeparator)).ToArray();
|
||||
separator = newSeparator;
|
||||
}
|
||||
m_FriendlyObjectTypeNames = m_ObjectTypeNames.Select(s => s.Substring(s.LastIndexOf(separator) + 1)).ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"{nameof(ScanObjects)} for {nameof(SheetAsset)} {sheetAsset} failed with error: {ex}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4018a2d67bd0e64492cb3270615f6f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/ObjectScanner.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Scanning
|
||||
{
|
||||
public enum ScanOption
|
||||
{
|
||||
Default = 0,
|
||||
Assembly = 1,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d706a65632dd3041952bb5c61225d0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/ScanOption.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Scanning
|
||||
{
|
||||
public enum ScanPathOption
|
||||
{
|
||||
Default = 0,
|
||||
Assets = 1,
|
||||
Packages = 2,
|
||||
All = 3,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08d4b29bf4547d64cb4f0ffeaa043cff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/ScanPathOption.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,63 @@
|
||||
using LunaWolfStudiosEditor.ScriptableSheets.Shared;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Scanning
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ScanSettings
|
||||
{
|
||||
[SerializeField]
|
||||
private ScanOption m_Option = ScanOption.Default;
|
||||
public ScanOption Option { get => m_Option; set => m_Option = value; }
|
||||
|
||||
[SerializeField]
|
||||
private ScanPathOption m_PathOption = ScanPathOption.Default;
|
||||
public ScanPathOption PathOption { get => m_PathOption; set => m_PathOption = value; }
|
||||
|
||||
[SerializeField]
|
||||
private string m_Path = UnityConstants.DefaultAssetPath;
|
||||
public string Path { get => m_Path; set => m_Path = value; }
|
||||
|
||||
[SerializeField]
|
||||
private bool m_ShowProgressBar = true;
|
||||
public bool ShowProgressBar { get => m_ShowProgressBar; set => m_ShowProgressBar = value; }
|
||||
|
||||
[SerializeField]
|
||||
private bool m_RootPrefabsOnly = true;
|
||||
public bool RootPrefabsOnly { get => m_RootPrefabsOnly; set => m_RootPrefabsOnly = value; }
|
||||
|
||||
public string[] GetScanPaths()
|
||||
{
|
||||
switch (m_PathOption)
|
||||
{
|
||||
case ScanPathOption.Default:
|
||||
return new string[] { m_Path };
|
||||
case ScanPathOption.Assets:
|
||||
return new string[] { UnityConstants.DefaultAssetPath };
|
||||
case ScanPathOption.Packages:
|
||||
return new string[] { UnityConstants.Packages };
|
||||
case ScanPathOption.All:
|
||||
return new string[] { UnityConstants.DefaultAssetPath, UnityConstants.Packages };
|
||||
default:
|
||||
Debug.LogWarning($"Selected {nameof(ScanPathOption)} {m_PathOption} is not defined. Using default scan path {UnityConstants.DefaultAssetPath}.");
|
||||
return new string[] { UnityConstants.DefaultAssetPath };
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFirstScanPath()
|
||||
{
|
||||
return GetScanPaths()[0];
|
||||
}
|
||||
|
||||
public string GetJoinedScanPaths()
|
||||
{
|
||||
var scanPaths = GetScanPaths();
|
||||
return string.Join("\n", scanPaths);
|
||||
}
|
||||
|
||||
public string GetJoinedScanPaths(string[] scanPaths)
|
||||
{
|
||||
return string.Join("\n", scanPaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd3149c94f78c61419a2b93cbbe23f68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/ScanSettings.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Scanning
|
||||
{
|
||||
[System.Flags]
|
||||
public enum SheetAsset
|
||||
{
|
||||
Default = 0,
|
||||
ScriptableObject = 1 << 0,
|
||||
AnimationClip = 1 << 1,
|
||||
AnimatorController = 1 << 2,
|
||||
AudioClip = 1 << 3,
|
||||
AudioMixer = 1 << 4,
|
||||
AvatarMask = 1 << 5,
|
||||
Flare = 1 << 6,
|
||||
Font = 1 << 7,
|
||||
Material = 1 << 8,
|
||||
Mesh = 1 << 9,
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
PhysicsMaterial = 1 << 10,
|
||||
#else
|
||||
PhysicMaterial = 1 << 10,
|
||||
#endif
|
||||
PhysicsMaterial2D = 1 << 11,
|
||||
Prefab = 1 << 12,
|
||||
Scene = 1 << 13,
|
||||
Shader = 1 << 14,
|
||||
Sprite = 1 << 15,
|
||||
TerrainData = 1 << 16,
|
||||
TextAsset = 1 << 17,
|
||||
Texture = 1 << 18,
|
||||
VideoClip = 1 << 19,
|
||||
}
|
||||
|
||||
public static class SheetAssetExtensions
|
||||
{
|
||||
private static readonly Dictionary<SheetAsset, string> s_SheetAssetToType = new Dictionary<SheetAsset, string>()
|
||||
{
|
||||
{ SheetAsset.AnimationClip, "UnityEditor.AnimationClip" },
|
||||
{ SheetAsset.AnimatorController, "UnityEditor.Animations.AnimatorController" },
|
||||
{ SheetAsset.AudioClip, "UnityEditor.AudioClip" },
|
||||
{ SheetAsset.AudioMixer, "UnityEditor.Audio.AudioMixerController" },
|
||||
{ SheetAsset.AvatarMask, "UnityEngine.AvatarMask" },
|
||||
{ SheetAsset.Flare, "UnityEngine.Flare" },
|
||||
{ SheetAsset.Font, "UnityEngine.Font" },
|
||||
{ SheetAsset.Material, "UnityEngine.Material" },
|
||||
{ SheetAsset.Mesh, "UnityEngine.Mesh" },
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
{ SheetAsset.PhysicsMaterial, "UnityEngine.PhysicsMaterial" },
|
||||
#else
|
||||
{ SheetAsset.PhysicMaterial, "UnityEngine.PhysicMaterial" },
|
||||
#endif
|
||||
{ SheetAsset.PhysicsMaterial2D, "UnityEngine.PhysicsMaterial2D" },
|
||||
{ SheetAsset.Prefab, "UnityEngine.GameObject" },
|
||||
{ SheetAsset.Scene, "UnityEngine.SceneAsset" },
|
||||
{ SheetAsset.ScriptableObject, "UnityEngine.ScriptableObject" },
|
||||
{ SheetAsset.Shader, "UnityEngine.Shader" },
|
||||
{ SheetAsset.Sprite, "UnityEngine.Sprite" },
|
||||
{ SheetAsset.TerrainData, "UnityEngine.TerrainData" },
|
||||
{ SheetAsset.TextAsset, "UnityEngine.TextAsset" },
|
||||
{ SheetAsset.Texture, "UnityEngine.Texture2D" },
|
||||
{ SheetAsset.VideoClip, "UnityEngine.Video.VideoClip" }
|
||||
};
|
||||
|
||||
public static string GetDefaultType(this SheetAsset sheetAsset)
|
||||
{
|
||||
if (s_SheetAssetToType.TryGetValue(sheetAsset, out string type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{nameof(SheetAsset)} '{sheetAsset}' not found in dictionary {nameof(s_SheetAssetToType)}.");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e4399e7732bb7d48b5420fb7bd9beaa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Scanning/SheetAsset.cs
|
||||
uploadId: 823456
|
||||
Reference in New Issue
Block a user