添加UniTask插件和 Odin 插件

This commit is contained in:
SnowShow 2025-05-07 14:55:02 +08:00
parent eff54823a7
commit 0463711d88
149 changed files with 48926 additions and 9 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cfff520408b6f46439c7b0676925fb80
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,7 @@
using System;
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : class
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;

View File

@ -1,6 +1,18 @@
using System.Collections.Generic;
using UnityEngine;
public class ActorMgr : Singleton<ActorMgr>
{
private Dictionary<string,Container> _containers = new Dictionary<string,Container>();
protected override void OnLoad()
{
base.OnLoad();
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7db84c72b2408b24da5a225550b562ff
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 05b1eef81f23d6648992c93437892982
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa3dc305dd00dad49bbc1ff3996b055d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,79 @@
fileFormatVersion: 2
guid: 5651992cdad94894a3af7dc3f1da9170
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 0
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 0
Exclude PSM: 0
Exclude PSP2: 0
Exclude SamsungTV: 0
Exclude Tizen: 0
Exclude WebGL: 0
Exclude WiiU: 0
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
N3DS:
enabled: 1
settings: {}
PS4:
enabled: 1
settings: {}
PSM:
enabled: 1
settings: {}
PSP2:
enabled: 1
settings: {}
SamsungTV:
enabled: 1
settings: {}
Tizen:
enabled: 1
settings: {}
WebGL:
enabled: 1
settings: {}
WiiU:
enabled: 1
settings: {}
WindowsStoreApps:
enabled: 1
settings:
CPU: AnyCPU
XboxOne:
enabled: 1
settings: {}
iOS:
enabled: 1
settings: {}
tvOS:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,79 @@
fileFormatVersion: 2
guid: 5978f8f3dd274e848fbb7a123bde1fb9
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 0
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 0
Exclude PSM: 0
Exclude PSP2: 0
Exclude SamsungTV: 0
Exclude Tizen: 0
Exclude WebGL: 0
Exclude WiiU: 0
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
N3DS:
enabled: 1
settings: {}
PS4:
enabled: 1
settings: {}
PSM:
enabled: 1
settings: {}
PSP2:
enabled: 1
settings: {}
SamsungTV:
enabled: 1
settings: {}
Tizen:
enabled: 1
settings: {}
WebGL:
enabled: 1
settings: {}
WiiU:
enabled: 1
settings: {}
WindowsStoreApps:
enabled: 1
settings:
CPU: AnyCPU
XboxOne:
enabled: 1
settings: {}
iOS:
enabled: 1
settings: {}
tvOS:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a73a691127ad93941b89586292291dab
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,76 @@
fileFormatVersion: 2
guid: d2a8f0021d6b47c5923d8972dfb81ef1
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Android:
enabled: 1
settings: {}
Any:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 1
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude N3DS: 1
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 0
Exclude Win64: 0
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
Linux:
enabled: 1
settings: {}
Linux64:
enabled: 1
settings: {}
LinuxUniversal:
enabled: 1
settings: {}
OSXIntel:
enabled: 1
settings: {}
OSXIntel64:
enabled: 1
settings: {}
OSXUniversal:
enabled: 1
settings: {}
PSM:
enabled: 0
settings: {}
Win:
enabled: 1
settings: {}
Win64:
enabled: 1
settings: {}
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,76 @@
fileFormatVersion: 2
guid: 1e0a9643dc0d4b46bf2321f72c4e503e
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Android:
enabled: 1
settings: {}
Any:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 1
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude N3DS: 1
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 0
Exclude Win64: 0
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
Linux:
enabled: 1
settings: {}
Linux64:
enabled: 1
settings: {}
LinuxUniversal:
enabled: 1
settings: {}
OSXIntel:
enabled: 1
settings: {}
OSXIntel64:
enabled: 1
settings: {}
OSXUniversal:
enabled: 1
settings: {}
PSM:
enabled: 0
settings: {}
Win:
enabled: 1
settings: {}
Win64:
enabled: 1
settings: {}
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 47a84ebde4ec47fabb620b30cc7a3e5c
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 1
settings:
Exclude Android: 0
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude N3DS: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude PS4: 0
Exclude PSM: 0
Exclude PSP2: 0
Exclude SamsungTV: 0
Exclude Tizen: 0
Exclude WebGL: 0
Exclude WiiU: 0
Exclude Win: 0
Exclude Win64: 0
Exclude WindowsStoreApps: 0
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 47a84ebde4ec47fabb620b30cc7a096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: a4865f1ab4504ed8a368670db22f409c
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a4865f1ab4504ed8a368670db22f096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 61824742f78323c439d83403f8272d41
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 74721b9f0af448f5ae2e91102a1a5edd
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 1
settings:
Exclude Android: 0
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude N3DS: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude PS4: 0
Exclude PSM: 0
Exclude PSP2: 0
Exclude SamsungTV: 0
Exclude Tizen: 0
Exclude WebGL: 0
Exclude WiiU: 0
Exclude Win: 0
Exclude Win64: 0
Exclude WindowsStoreApps: 0
Exclude XboxOne: 0
Exclude iOS: 0
Exclude tvOS: 0
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,202 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Sirenix.Serialization.Config</name>
</assembly>
<members>
<member name="T:Sirenix.Serialization.CustomLogger">
<summary>
A helper class for quickly and easily defining custom loggers.
</summary>
<seealso cref="T:Sirenix.Serialization.ILogger" />
</member>
<member name="M:Sirenix.Serialization.CustomLogger.#ctor(System.Action{System.String},System.Action{System.String},System.Action{System.Exception})">
<summary>
Not yet documented.
</summary>
</member>
<member name="M:Sirenix.Serialization.CustomLogger.LogWarning(System.String)">
<summary>
Not yet documented.
</summary>
</member>
<member name="M:Sirenix.Serialization.CustomLogger.LogError(System.String)">
<summary>
Not yet documented.
</summary>
</member>
<member name="M:Sirenix.Serialization.CustomLogger.LogException(System.Exception)">
<summary>
Not yet documented.
</summary>
</member>
<member name="T:Sirenix.Serialization.DataFormat">
<summary>
Specifies a data format to read and write in.
</summary>
</member>
<member name="F:Sirenix.Serialization.DataFormat.Binary">
<summary>
A custom packed binary format. This format is most efficient and almost allocation-free,
but its serialized data is not human-readable.
</summary>
</member>
<member name="F:Sirenix.Serialization.DataFormat.JSON">
<summary>
A JSON format compliant with the json specification found at "http://www.json.org/".
<para />
This format has rather sluggish performance and allocates frightening amounts of string garbage.
</summary>
</member>
<member name="F:Sirenix.Serialization.DataFormat.Nodes">
<summary>
A format that does not serialize to a byte stream, but to a list of data nodes in memory
which can then be serialized by Unity.
<para />
This format is highly inefficient, and is primarily used for ensuring that Unity assets
are mergeable by individual values when saved in Unity's text format. This makes
serialized values more robust and data recovery easier in case of issues.
<para />
This format is *not* recommended for use in builds.
</summary>
</member>
<member name="T:Sirenix.Serialization.DefaultLoggers">
<summary>
Defines default loggers for serialization and deserialization. This class and all of its loggers are thread safe.
</summary>
</member>
<member name="P:Sirenix.Serialization.DefaultLoggers.DefaultLogger">
<summary>
Not yet documented.
</summary>
</member>
<member name="P:Sirenix.Serialization.DefaultLoggers.UnityLogger">
<summary>
Not yet documented.
</summary>
</member>
<member name="T:Sirenix.Serialization.ErrorHandlingPolicy">
<summary>
The policy for handling errors during serialization and deserialization.
</summary>
</member>
<member name="F:Sirenix.Serialization.ErrorHandlingPolicy.Resilient">
<summary>
Attempts will be made to recover from errors and continue serialization. Data may become invalid.
</summary>
</member>
<member name="F:Sirenix.Serialization.ErrorHandlingPolicy.ThrowOnErrors">
<summary>
Exceptions will be thrown when errors are logged.
</summary>
</member>
<member name="F:Sirenix.Serialization.ErrorHandlingPolicy.ThrowOnWarningsAndErrors">
<summary>
Exceptions will be thrown when warnings or errors are logged.
</summary>
</member>
<member name="T:Sirenix.Serialization.GlobalSerializationConfig">
<summary>
Not yet documented.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.ODIN_SERIALIZATION_CAUTIONARY_WARNING_TEXT">
<summary>
Text for the cautionary serialization warning shown in the inspector.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.ODIN_SERIALIZATION_CAUTIONARY_WARNING_BUTTON_TEXT">
<summary>
Text for the hide button for the cautionary serialization warning shown in the inspector.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.ODIN_PREFAB_CAUTIONARY_WARNING_BUTTON_TEXT">
<summary>
Text for the hide button for the cautionary prefab warning shown in the inspector.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.HideSerializationCautionaryMessage">
<summary>
Whether the user has chosen to hide the cautionary serialization warning.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.HideOdinSerializeAttributeWarningMessages">
<summary>
Whether the user has chosen to hide the warning messages related to the OdinSerialize attribute.
</summary>
</member>
<member name="F:Sirenix.Serialization.GlobalSerializationConfig.HideNonSerializedShowInInspectorWarningMessages">
<summary>
Whether the user has chosen to hide the warning messages related to the SerializeField and ShowInInspector attributes on non-serialized members.
</summary>
</member>
<member name="P:Sirenix.Serialization.GlobalSerializationConfig.Logger">
<summary>
Not yet documented.
</summary>
</member>
<member name="P:Sirenix.Serialization.GlobalSerializationConfig.EditorSerializationFormat">
<summary>
Not yet documented.
</summary>
</member>
<member name="P:Sirenix.Serialization.GlobalSerializationConfig.BuildSerializationFormat">
<summary>
Not yet documented.
</summary>
</member>
<member name="P:Sirenix.Serialization.GlobalSerializationConfig.LoggingPolicy">
<summary>
Not yet documented.
</summary>
</member>
<member name="P:Sirenix.Serialization.GlobalSerializationConfig.ErrorHandlingPolicy">
<summary>
Not yet documented.
</summary>
</member>
<member name="T:Sirenix.Serialization.ILogger">
<summary>
Implements methods for logging warnings, errors and exceptions during serialization and deserialization.
</summary>
</member>
<member name="M:Sirenix.Serialization.ILogger.LogWarning(System.String)">
<summary>
Logs a warning.
</summary>
<param name="warning">The warning to log.</param>
</member>
<member name="M:Sirenix.Serialization.ILogger.LogError(System.String)">
<summary>
Logs an error.
</summary>
<param name="error">The error to log.</param>
</member>
<member name="M:Sirenix.Serialization.ILogger.LogException(System.Exception)">
<summary>
Logs an exception.
</summary>
<param name="exception">The exception to log.</param>
</member>
<member name="T:Sirenix.Serialization.LoggingPolicy">
<summary>
The policy for which level of logging to do during serialization and deserialization.
</summary>
</member>
<member name="F:Sirenix.Serialization.LoggingPolicy.LogErrors">
<summary>
Not yet documented.
</summary>
</member>
<member name="F:Sirenix.Serialization.LoggingPolicy.LogWarningsAndErrors">
<summary>
Not yet documented.
</summary>
</member>
<member name="F:Sirenix.Serialization.LoggingPolicy.Silent">
<summary>
Not yet documented.
</summary>
</member>
</members>
</doc>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 74721b9f0af448f5ae2e91102a1a096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 5f3147f7af4c49739579b966c458f5e4
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f3147f7af4c49739579b966c458096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 5c65184932ff4fd48a343e2360256baf
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5c65184932ff4fd48a343e236025096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 4873f2a8bdae42baa0406e8a61366ca1
timeCreated: 1488828285
PluginImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude N3DS: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PSM: 1
Exclude PSP2: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude WiiU: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 1
Exclude XboxOne: 1
Exclude iOS: 1
Exclude tvOS: 1
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4873f2a8bdae42baa0406e8a6136096f
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,6 @@
<linker>
<assembly fullname="Sirenix.OdinInspector.Attributes" preserve="all"/>
<assembly fullname="Sirenix.Serialization.Config" preserve="all"/>
<assembly fullname="Sirenix.Serialization" preserve="all"/>
<assembly fullname="Sirenix.Utilities" preserve="all"/>
</linker>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1bec01331befdea4d9ed9033eabd68f8
timeCreated: 1613046886
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 39584688cfac6ff44bd94124e5bc1ca7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f597f19f656ba56eae4f6a3a7cc528f4
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 48e08dc33330d11e9d4a1b246c52e4f6
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ed09910c0094cb27be8f3ca264680da3
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cc355dd4cf1e6173beaeb22c2858cbe1
timeCreated: 1488828285
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe4970195facd664dbd38d1cbf2100c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 52c0fd243c6c01e4d9efa03616b655d5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85e532eecf67ab545b2a5a28f1a22894
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
Odin Inspector makes use of the Bootstrap icon library.
The library has been packed into the SdfIconAtlas.png
file as SDF data.
Bootstrap is released under the following license:
---
The MIT License (MIT)
Copyright (c) 2011-2018 Twitter, Inc.
Copyright (c) 2011-2018 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3fdc67fad3e362e47b5dd365a0bbdd7f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 90eaa0dc28c1934408dc1c02e13a507f
timeCreated: 1628274352
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e22dad2728c77344f8da0d2789866a0e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,51 @@
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Hidden/Sirenix/Editor/ExtractSprite"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Rect("Rect", Vector) = (0,0,0,0)
_TexelSize("TexelSize", Vector) = (0,0,0,0)
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _Rect;
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target {
float2 uv = i.uv;
uv *= _Rect.zw;
uv += _Rect.xy;
return tex2D(_MainTex, uv);
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0675e2791073a4147b190e55f1da7ac2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,98 @@
Shader "Hidden/Sirenix/OdinGUIShader"
{
SubShader
{
Lighting Off
Cull Off
ZWrite Off
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float _SirenixOdin_GreyScale;
float4 _SirenixOdin_GUIColor;
float4 _SirenixOdin_GUIUv;
float4 _SirenixOdin_HueColor;
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
float test1(float x, float y) {
if (x >= y) {
return 0;
} else {
return 1;
}
}
float test2(float x, float y) {
return step(x, y);
}
float3 rgb2hsv(float3 c) {
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float3 hsv2rgb(float3 c) {
c = float3(c.x, clamp(c.yz, 0.0, 1.0));
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
float4 frag(v2f i) : SV_Target {
float2 uv = i.uv;
uv.y = 1 - uv.y;
uv.x = _SirenixOdin_GUIUv.x + uv.x * _SirenixOdin_GUIUv.z;
uv.y = _SirenixOdin_GUIUv.y + uv.y * _SirenixOdin_GUIUv.w;
uv.y = 1 - uv.y;
// Greyscale
float4 col = tex2D(_MainTex, uv);
float3 greyScale = (0.3 * col.r) + (0.59 * col.g) + (0.11 * col.b);
col.rgb = lerp(col.rgb, greyScale, _SirenixOdin_GreyScale);
// Change hue
float3 h = col.rgb;
h = rgb2hsv(h);
float hue = rgb2hsv(_SirenixOdin_HueColor.rgb).x;
h.x = hue;
h = hsv2rgb(h);
col.rgb = lerp(col.rgb, h, _SirenixOdin_HueColor.a);
// Blend color
col *= _SirenixOdin_GUIColor;
return col;
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7619c1ca61a5ef94ca78ddfa69941dad
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Hidden/Sirenix/Editor/GUIIcon"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Blend SrcAlpha Zero
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _Color;
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target {
// drop shadow:
// float texelSize = 1.0 / 34.0;
// float2 shadowUv = clamp(i.uv + float2(-texelSize, texelSize * 2), float2(0, 0), float2(1, 1));
// fixed4 shadow = fixed4(0, 0, 0, tex2D(_MainTex, shadowUv).a);
fixed4 col = _Color;
col.a *= tex2D(_MainTex, i.uv).a;
// drop shadow:
// col = lerp(shadow, col, col.a);
return col;
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2ad0a53eacb91bd4fbe0dc668bf25e6f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,95 @@
Shader "Hidden/Sirenix/SdfIconShader"
{
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _SirenixOdin_SdfTex;
float _SirenixOdin_EdgeOffset;
float4 _SirenixOdin_Color;
float4 _SirenixOdin_BgColor;
float4 _SirenixOdin_Uv;
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
float samplePixel(float2 uv) {
return tex2D(_SirenixOdin_SdfTex, uv).a;
}
float linearstep(float lo, float hi, float input) {
float diff = hi - lo;
float offset = input - lo;
return min(1.0, max(0.0, offset / diff));
}
float sampleDist(float2 uv, float dx, float edge, float padding) {
float dist = samplePixel(uv);
float p = -abs((dx * 3072.0) / -padding);
float a = min(1, max(0, edge - p * 0.33333));
float b = max(0, min(1, edge + p * 0.33333));
return smoothstep(b, a, dist);
}
float4 frag(v2f i) : SV_Target {
float2 uv = i.uv;
uv.y = 1 - uv.y;
uv.x = _SirenixOdin_Uv.x + uv.x * _SirenixOdin_Uv.z;
uv.y = _SirenixOdin_Uv.y + uv.y * _SirenixOdin_Uv.w;
uv.y = 1 - uv.y;
float alpha = 0.0;
float edge = 0.5019608 + _SirenixOdin_EdgeOffset;
if (_SirenixOdin_BgColor.a > 0.01) {
float3 colorBg = _SirenixOdin_BgColor.rgb;
float3 colorFg = _SirenixOdin_Color.rgb;
float padding = 8;
float dx = ddx(uv.x);
float2 t = float2(dx * 0.333333, 0);
float3 subDist = float3(
sampleDist(uv.xy - t, dx, edge, padding),
sampleDist(uv.xy, dx, edge, padding),
sampleDist(uv.xy + t, dx, edge, padding));
float3 color = lerp(colorBg, colorFg, clamp(subDist, 0.0, 1.0));
float alpha = min(1, subDist.r + subDist.g + subDist.b);
float4 col = float4(color, alpha * _SirenixOdin_Color.a);
return col;
} else {
float padding = 8;
float dx = ddx(uv.x);
float alpha = sampleDist(uv, dx, edge, padding);
float4 col = _SirenixOdin_Color;
col.a *= alpha;
return col;
}
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 99e0f263ae4ed2d4d962a2e995dff6df
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -262940062, guid: a4865f1ab4504ed8a368670db22f409c, type: 3}
m_Name: OdinPathLookup
m_EditorClassIdentifier:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 08379ccefc05200459f90a1c0711a340
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -0,0 +1,128 @@
fileFormatVersion: 2
guid: 2a0112a98875dfd488b5d10bdb8a4903
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 10
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 16384
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 16384
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 16384
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b6e7b61d4e7a58e448dbc8b6516d311b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9562675c419aad46b2f50a7e8bea6c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -645759843, guid: a4865f1ab4504ed8a368670db22f409c, type: 3}
m_Name: GeneralDrawerConfig
m_EditorClassIdentifier:
enableUIToolkitSupport: 1
useOldUnityObjectField: 0
useOldUnityPreviewField: 0
useOldTypeSelector: 0
useNewObjectSelector: 1
showNoneItem: 1
showCategoriesByDefault: 0
preferNamespacesOverAssemblyCategories: 1
useOldPolymorphicField: 0
showBaseType: 1
nonDefaultConstructorPreference: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1e1694c3b4f084744a9daf4b83d2a5b1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1137305049, guid: a4865f1ab4504ed8a368670db22f409c, type: 3}
m_Name: InspectorConfig
m_EditorClassIdentifier:
enableOdinInInspector: 1
defaultEditorBehaviour: 11
processMouseMoveInInspector: 1
drawingConfig:
configs: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fdc5ae3cf8276b84fa88e5687552d8e9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -228747253, guid: a4865f1ab4504ed8a368670db22f409c, type: 3}
m_Name: OdinModuleConfig
m_EditorClassIdentifier:
configurations:
- ID: Unity.Addressables
ActivationSettings: 0
ModuleTogglingSettings: 1
ModuleUpdateSettings: 1

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a03275f16f29e3468c2a4e4a817fc90
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 356a67db9bc6244428bcd2aad1eefbda
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d92d0eb8b980c6d44b5f0e64a620355b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f123e8d393894d84f962d16a71d387f1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6384593779a7421881db64cdb25db4c5
timeCreated: 1718984862

View File

@ -0,0 +1,30 @@
//-----------------------------------------------------------------------
// <copyright file="OdinAddressableReflection.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
#if !SIRENIX_INTERNAL
#pragma warning disable
#endif
using System.Reflection;
using UnityEditor.AddressableAssets.Settings;
namespace Sirenix.OdinInspector.Modules.Addressables.Editor.Internal
{
internal static class OdinAddressableReflection
{
public static FieldInfo AddressableAssetEntry_mGUID_Field;
static OdinAddressableReflection()
{
AddressableAssetEntry_mGUID_Field = typeof(AddressableAssetEntry).GetField("m_GUID", BindingFlags.Instance | BindingFlags.NonPublic);
}
internal static void EnsureConstructed() { }
}
}
#endif

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c1a8e9ae60bf4edebd0ec6052eb9064e
timeCreated: 1718984883

View File

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------
// <copyright file="OdinAddressableReflectionValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
#if SIRENIX_INTERNAL
using System.Collections;
using System.Reflection;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.OdinInspector.Modules.Addressables.Editor.Internal;
[assembly: RegisterValidator(typeof(OdinAddressableReflectionValidator))]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor.Internal
{
public class OdinAddressableReflectionValidator : GlobalValidator
{
public override IEnumerable RunValidation(ValidationResult result)
{
OdinAddressableReflection.EnsureConstructed();
FieldInfo[] fields = typeof(OdinAddressableReflection).GetFields(BindingFlags.Static | BindingFlags.Public);
for (var i = 0; i < fields.Length; i++)
{
if (fields[i].IsLiteral)
{
continue;
}
if (fields[i].GetValue(null) != null)
{
continue;
}
result.AddError($"[Odin Addressable Module]: {fields[i].Name} was not found.");
}
return null;
}
}
}
#endif
#endif

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 97bf306f5a4249b192921db9152934f6
timeCreated: 1718984873

View File

@ -0,0 +1,29 @@
{
"name": "Sirenix.OdinInspector.Modules.Unity.Addressables",
"references": [
"Unity.Addressables",
"Unity.Addressables.Editor",
"Sirenix.Serialization",
"Sirenix.OdinInspector.Attributes",
"Sirenix.OdinInspector.Editor",
"Sirenix.Utilities.Editor",
"Sirenix.Utilities",
"Sirenix.OdinValidator.Editor"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [
"Sirenix.Serialization.dll",
"Sirenix.OdinInspector.Attributes.dll",
"Sirenix.OdinInspector.Editor.dll",
"Sirenix.Utilities.Editor.dll",
"Sirenix.Utilities.dll",
"Sirenix.OdinValidator.Editor.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3b4d8e09c665bfa47849130d8695171e
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b568c1d508ce0b74eb0025b8501d1c1e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,98 @@
//-----------------------------------------------------------------------
// <copyright file="AssetLabelReferenceValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
#if !SIRENIX_INTERNAL
#pragma warning disable
#endif
using UnityEngine;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using UnityEngine.AddressableAssets;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
#if ODIN_VALIDATOR_3_1
[assembly: RegisterValidationRule(typeof(AssetLabelReferenceValidator), Description =
"This validator ensures that AssetLabelReferences marked with the Required attribute display an error " +
"message if they are not set. It can also be configured to require that all AssetLabelReferences be set " +
"by default; the Optional attribute can then be used to exclude specific AssetLabelReferences from " +
"validation.")]
#else
[assembly: RegisterValidator(typeof(AssetLabelReferenceValidator))]
#endif
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
/// <summary>
/// Validator for AssetLabelReference values.
/// </summary>
public class AssetLabelReferenceValidator : ValueValidator<AssetLabelReference>
{
[Tooltip("If enabled, the validator will display an error message if the AssetLabelReference is not set. " +
"If disabled, the validator will only display an error message if the AssetLabelReference is set, but the " +
"assigned label does not exist.")]
[ToggleLeft]
public bool RequiredByDefault;
private bool required;
private bool optional;
private string requiredMessage;
protected override void Initialize()
{
var requiredAttr = this.Property.GetAttribute<RequiredAttribute>();
this.requiredMessage = requiredAttr?.ErrorMessage ?? $"<b>{this.Property.NiceName}</b> is required.";
if (this.RequiredByDefault)
{
required = true;
optional = Property.GetAttribute<OptionalAttribute>() != null;
}
else
{
required = requiredAttr != null;
optional = false;
}
}
protected override void Validate(ValidationResult result)
{
// If the Addressables settings have not been created, nothing else is really valid.
if (AddressableAssetSettingsDefaultObject.SettingsExists == false)
{
result.AddError("Addressables Settings have not been created.")
.WithButton("Open Settings Window", () => OdinAddressableUtility.OpenGroupsWindow());
return;
}
var value = Value?.labelString;
if (string.IsNullOrEmpty(value))
{
if (optional == false && required) // Optional == false & required? Nice.
{
result.AddError(requiredMessage).EnableRichText();
}
}
else
{
var labels = AddressableAssetSettingsDefaultObject.Settings.GetLabels();
if (labels.Contains(value) == false)
{
result.AddError($"Label <i>{value}</i> has not been created as a label.")
.WithButton("Open Label Settings", () => OdinAddressableUtility.OpenLabelsWindow());
}
}
}
}
}
#endif

View File

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

View File

@ -0,0 +1,284 @@
//-----------------------------------------------------------------------
// <copyright file="AssetReferenceValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
#if !SIRENIX_INTERNAL
#pragma warning disable
#endif
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine.AddressableAssets;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
#if ODIN_VALIDATOR_3_1
[assembly: RegisterValidationRule(typeof(AssetReferenceValidator), Description =
"This validator provides robust integrity checks for your asset references within Unity. " +
"It validates whether an asset reference has been assigned, and if it's missing, raises an error. " +
"It further checks the existence of the main asset at the assigned path, ensuring it hasn't been " +
"inadvertently deleted or moved. The validator also verifies if the assigned asset is addressable " +
"and, if not, offers a fix to make it addressable. Moreover, it ensures the asset adheres to " +
"specific label restrictions set through the AssetReferenceUILabelRestriction attribute. " +
"Lastly, it performs checks on any sub-object linked to the asset, making sure it hasn't gone missing. " +
"This comprehensive validation system prevents hard-to-spot bugs and errors, " +
"fostering a more robust and efficient development workflow.")]
#else
[assembly: RegisterValidator(typeof(AssetReferenceValidator))]
#endif
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class AssetReferenceValidator : ValueValidator<AssetReference>
{
[Tooltip("If true and the AssetReference is not marked with the Optional attribute, " +
"the validator will display an error message if the AssetReference is not set. " +
"If false, the validator will only display an error message if the AssetReference is set, " +
"but the assigned asset does not exist.")]
[ToggleLeft]
public bool RequiredByDefault;
private bool required;
private bool optional;
private string requiredMessage;
private List<AssetReferenceUIRestriction> restrictions;
protected override void Initialize()
{
var requiredAttr = this.Property.GetAttribute<RequiredAttribute>();
this.requiredMessage = requiredAttr?.ErrorMessage ?? $"<b>{this.Property.NiceName}</b> is required.";
if (this.RequiredByDefault)
{
this.required = true;
this.optional = this.Property.GetAttribute<OptionalAttribute>() != null;
}
else
{
this.required = requiredAttr != null;
this.optional = false;
}
this.restrictions = new List<AssetReferenceUIRestriction>();
foreach (var attr in this.Property.Attributes)
{
if (attr is AssetReferenceUIRestriction r)
{
this.restrictions.Add(r);
}
}
}
protected override void Validate(ValidationResult result)
{
// If the Addressables settings have not been created, nothing else is really valid.
if (AddressableAssetSettingsDefaultObject.SettingsExists == false)
{
result.AddError("Addressables Settings have not been created.")
.WithButton("Open Settings Window", () => OdinAddressableUtility.OpenGroupsWindow());
return;
}
var assetReference = this.Value;
var assetReferenceHasBeenAssigned = !string.IsNullOrEmpty(assetReference?.AssetGUID);
// No item has been assigned.
if (!assetReferenceHasBeenAssigned)
{
if (optional == false && required) // Optional == false & required? Nice.
{
result.AddError(this.requiredMessage).EnableRichText();
}
return;
}
var assetPath = AssetDatabase.GUIDToAssetPath(assetReference.AssetGUID);
var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath);
// The item has been assigned, but is now missing.
if (mainAsset == null)
{
result.AddError($"The previously assigned main asset with path <b>'{assetPath}'</b> is missing. GUID <b>'{assetReference.AssetGUID}'</b>");
return;
}
var addressableAssetEntry = AddressableAssetSettingsDefaultObject.Settings.FindAssetEntry(assetReference.AssetGUID, true);
var isAddressable = addressableAssetEntry != null;
// Somehow an item sneaked through all of unity's validation measures and ended up not being addressable
// while still ending up in the asset reference object field.
if (!isAddressable)
{
result.AddError("Assigned item is not addressable.")
.WithFix<MakeAddressableFixArgs>("Make Addressable", args => OdinAddressableUtility.MakeAddressable(mainAsset, args.Group));
}
// Check the assigned item against any and all label restrictions.
else
{
if (OdinAddressableUtility.ValidateAssetReferenceRestrictions(restrictions, mainAsset, out var failedRestriction) == false)
{
if (failedRestriction is AssetReferenceUILabelRestriction labelRestriction)
{
result.AddError($"Asset reference is restricted to items with these specific labels <b>'{string.Join(", ", labelRestriction.m_AllowedLabels)}'</b>. The currently assigned item has none of them.")
.WithFix<AddLabelsFixArgs>("Add Labels", args => SetLabels(mainAsset, args.AssetLabels));
}
else
{
result.AddError("Restriction failed: " + failedRestriction.ToString());
}
}
}
// The assigned item had a sub object, but it's missing.
if (!string.IsNullOrEmpty(assetReference.SubObjectName))
{
var subObjects = OdinAddressableUtility.EnumerateAllActualAndVirtualSubAssets(mainAsset, assetPath);
var hasMissingSubObject = true;
foreach (var subObject in subObjects)
{
if (subObject.name == assetReference.SubObjectName)
{
hasMissingSubObject = false;
break;
}
}
if (hasMissingSubObject)
{
result.AddError($"The previously assigned sub asset with name <b>'{assetReference.SubObjectName}'</b> is missing.").EnableRichText();
}
}
if (assetReference.ValidateAsset(mainAsset) || assetReference.ValidateAsset(assetPath))
return;
if (assetReference is AssetReferenceSprite && assetReference.editorAsset is Sprite)
return;
result.AddError($"{assetReference.GetType().GetNiceFullName()}.ValidateAsset failed to validate assigned asset.");
}
private static void SetLabels(UnityEngine.Object obj, List<AssetLabel> assetLabels)
{
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return;
var settings = AddressableAssetSettingsDefaultObject.Settings;
var guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(obj));
var entry = settings.FindAssetEntry(guid, false);
foreach (var assetLabel in assetLabels.Where(a => a.Toggled))
{
entry.SetLabel(assetLabel.Label, true, false, false);
}
settings.SetDirty(AddressableAssetSettings.ModificationEvent.LabelAdded, entry, false, true);
}
private class MakeAddressableFixArgs
{
[ValueDropdown(nameof(GetGroups))]
[OnInspectorInit(nameof(SelectDefault))]
public AddressableAssetGroup Group;
private void SelectDefault()
{
this.Group = AddressableAssetSettingsDefaultObject.SettingsExists
? AddressableAssetSettingsDefaultObject.Settings.DefaultGroup
: null;
}
private static IEnumerable<ValueDropdownItem> GetGroups()
{
return !AddressableAssetSettingsDefaultObject.SettingsExists
? Enumerable.Empty<ValueDropdownItem>()
: AddressableAssetSettingsDefaultObject.Settings.groups
.Where(group => !group.ReadOnly)
.Select(group => new ValueDropdownItem(group.Name, group));
}
[Button(SdfIconType.ListNested), PropertySpace(8f)]
private void OpenAddressablesGroups() => OdinAddressableUtility.OpenGroupsWindow();
}
private class AddLabelsFixArgs
{
[HideIf("@true")]
public List<AssetLabel> AssetLabels
{
get
{
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return this.assetLabels;
var settings = AddressableAssetSettingsDefaultObject.Settings;
var labels = settings
.GetLabels()
.Select(l => new AssetLabel { Label = l, Toggled = false })
.ToList();
foreach (var assetLabel in this.assetLabels)
{
var label = labels.FirstOrDefault(l => l.Label == assetLabel.Label);
if (label != null)
{
label.Toggled = assetLabel.Toggled;
}
}
this.assetLabels = labels;
return this.assetLabels;
}
}
private List<AssetLabel> assetLabels = new List<AssetLabel>();
[OnInspectorGUI]
private void Draw()
{
var togglesRect = EditorGUILayout.GetControlRect(false, Mathf.CeilToInt(this.AssetLabels.Count / 2f) * 20f);
for (var i = 0; i < this.AssetLabels.Count; i++)
{
var assetLabel = this.AssetLabels[i];
var toggleRect = togglesRect.SplitGrid(togglesRect.width / 2f, 20, i);
assetLabel.Toggled = GUI.Toggle(toggleRect, assetLabel.Toggled, assetLabel.Label);
}
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return;
GUILayout.Space(8f);
var buttonsRect = EditorGUILayout.GetControlRect(false, 20f);
if (SirenixEditorGUI.SDFIconButton(buttonsRect, "Open Addressables Labels", SdfIconType.TagsFill))
{
OdinAddressableUtility.OpenLabelsWindow();
}
}
}
private class AssetLabel
{
public bool Toggled;
public string Label;
}
}
}
#endif

View File

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

View File

@ -0,0 +1,205 @@
//-----------------------------------------------------------------------
// <copyright file="CheckDuplicateBundleDependenciesValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR && ODIN_VALIDATOR_3_1
#if !SIRENIX_INTERNAL
#pragma warning disable
#endif
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor.AddressableAssets.Settings;
using System.Collections;
using System;
using Sirenix.OdinValidator.Editor;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
[assembly: RegisterValidationRule(typeof(CheckDuplicateBundleDependenciesValidator),
Description = "This validator detects potential duplicate asset dependencies in an addressable group, without the need for a build. " +
"For instance, imagine two prefabs in separate groups, both referencing the same material. Each group would then include the material " +
"and all its associated dependencies. " +
"To address this, the material should be marked as Addressable, either with one of the prefabs or in a distinct group.\n\n" +
"<b>Fixes: </b>Executing the fix will make the dependency addressable and move it to the specified group.\n\n" +
"<b>Exceptions: </b>It's important to note that duplicate assets aren't inherently problematic. For example, if certain assets are " +
"never accessed by the same user group, such as region-specific assets, these duplications might be desired or at least inconsequential. " +
"As every project is unique, decisions concerning duplicate asset dependencies should be considered on a case-by-case basis.")]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class CheckDuplicateBundleDependenciesValidator : GlobalValidator
{
private static Dictionary<GUID, List<string>> dependencyGroupMap = new Dictionary<GUID, List<string>>();
[Tooltip("The severity of the validation result.")]
public ValidatorSeverity ValidatorSeverity = ValidatorSeverity.Warning;
[Tooltip("Assets to ignore when validating.")]
[LabelText("Ignored GUIDs"), CustomValueDrawer(nameof(DrawGUIDEntry))]
public List<string> IgnoredGUIDs = new List<string>();
public override IEnumerable RunValidation(ValidationResult result)
{
dependencyGroupMap.Clear();
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
if (addressableAssetSettings == null) yield break;
foreach (var addressableAssetGroup in addressableAssetSettings.groups)
{
if (addressableAssetGroup == null) continue;
foreach (var addressableAssetEntry in addressableAssetGroup.entries)
{
var dependencyAssetPaths = AssetDatabase.GetDependencies(addressableAssetEntry.AssetPath)
.Where(assetPath => !assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) &&
!assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));
foreach (var dependencyAssetPath in dependencyAssetPaths)
{
var dependencyGUID = new GUID(AssetDatabase.AssetPathToGUID(dependencyAssetPath));
if (this.IgnoredGUIDs.Contains(dependencyGUID.ToString())) continue;
var dependencyAddressableAssetEntry = addressableAssetSettings.FindAssetEntry(dependencyGUID.ToString());
var isAddressable = dependencyAddressableAssetEntry != null;
if (isAddressable) continue;
if (!dependencyGroupMap.ContainsKey(dependencyGUID))
{
dependencyGroupMap.Add(dependencyGUID, new List<string>());
}
if (!dependencyGroupMap[dependencyGUID].Contains(addressableAssetGroup.Name))
{
dependencyGroupMap[dependencyGUID].Add(addressableAssetGroup.Name);
}
}
}
}
foreach (var kvp in dependencyGroupMap)
{
var dependencyGUID = kvp.Key;
var groups = kvp.Value;
if (groups.Count > 1)
{
var assetPath = AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString());
var message = $"{assetPath} is duplicated in these groups: {string.Join(", ", groups)}";
result.Add(this.ValidatorSeverity, message).WithFix<FixArgs>(args =>
{
if (args.FixChoice == FixChoice.Ignore)
{
var sourceType = args.IgnoreForEveryone ? ConfigSourceType.Project : ConfigSourceType.Local;
var data = RuleConfig.Instance.GetRuleData<CheckDuplicateBundleDependenciesValidator>(sourceType);
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
RuleConfig.Instance.SetAndSaveRuleData(data, sourceType);
return;
}
var obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object));
AddressableAssetGroup group;
if (args.Group == "Create New Group")
{
if (args.GroupName.IsNullOrWhitespace()) return;
group = addressableAssetSettings.FindGroup(args.GroupName);
if (group == null)
{
group = addressableAssetSettings.CreateGroup(args.GroupName, false, false, false, null);
}
}
else
{
group = addressableAssetSettings.FindGroup(args.Group);
if (group == null)
{
group = addressableAssetSettings.CreateGroup(args.Group, false, false, false, null);
}
}
OdinAddressableUtility.MakeAddressable(obj, group);
}, false).WithModifyRuleDataContextClick<CheckDuplicateBundleDependenciesValidator>("Ignore", data =>
{
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
}).SetSelectionObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString())));
}
}
}
private string DrawGUIDEntry(string guid)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
EditorGUILayout.TextArea(assetPath, SirenixGUIStyles.MultiLineLabel);
EditorGUILayout.TextField(guid);
return guid;
}
private enum FixChoice
{
AddToGroup,
Ignore,
}
private class FixArgs
{
[EnumToggleButtons, HideLabel]
public FixChoice FixChoice;
[PropertySpace(10)]
[ValueDropdown("Groups")]
//[Title("Group To Add To", TitleAlignment = TitleAlignments.Centered)]
[ShowIf(nameof(FixChoice), FixChoice.AddToGroup, Animate = false)]
public string Group = "Duplicate Asset Isolation";
[ValidateInput(nameof(ValidateGroupName), "The group name cannot be empty")]
[ShowIf(nameof(ShowNewGroupName), Animate = false)]
public string GroupName;
[LabelWidth(120f)]
[PropertySpace(10)]
[ShowIf("FixChoice", FixChoice.Ignore, Animate = false)]
public bool IgnoreForEveryone = true;
[OnInspectorGUI]
[PropertySpace(10)]
[DetailedInfoBox("Note that duplicate assets may not always be an issue", "Note that duplicate assets may not always be an issue. If assets will never be requested by the same set of users (for example, region-specific assets), then duplicate dependencies may be desired, or at least inconsequential. Each Project is unique, so fixing duplicate asset dependencies should be evaluated on a case by case basis")]
private void Dummy() { }
private bool ShowNewGroupName => this.FixChoice != FixChoice.Ignore && this.Group == "Create New Group";
private bool ValidateGroupName() => !this.GroupName.IsNullOrWhitespace();
private IEnumerable<string> Groups()
{
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
return addressableAssetSettings == null
? Enumerable.Empty<string>()
: addressableAssetSettings.groups
.Where(group => group != null && group.Name != "Built In Data")
.Select(group => group.Name)
.Append("Duplicate Asset Isolation")
.Prepend("Create New Group");
}
}
}
}
#endif

View File

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

View File

@ -0,0 +1,175 @@
//-----------------------------------------------------------------------
// <copyright file="CheckResourcesToAddressableDuplicateDependenciesValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR && ODIN_VALIDATOR_3_1
#if !SIRENIX_INTERNAL
#pragma warning disable
#endif
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities.Editor;
using System.Collections;
using System;
using System.IO;
using Sirenix.OdinValidator.Editor;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
[assembly: RegisterValidationRule(typeof(CheckResourcesToAddressableDuplicateDependenciesValidator),
Description = "This validator identifies dependencies that are duplicated in both addressable groups and the \"Resources\" folder.\n\n" +
"These duplications mean that data will be included in both the application build and the addressables build.\n\n" +
"You can decide to simply ignore these duplicated dependencies if this behavior is desired, or use the provided fix " +
"to move the asset outside of the \"Resources\" folder.")]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class CheckResourcesToAddressableDuplicateDependenciesValidator : GlobalValidator
{
[Tooltip("The severity of the validation result.")]
public ValidatorSeverity ValidatorSeverity = ValidatorSeverity.Warning;
[Tooltip("Assets to ignore when validating.")]
[LabelText("Ignored GUIDs"), CustomValueDrawer(nameof(DrawGUIDEntry))]
public List<string> IgnoredGUIDs = new List<string>();
public override IEnumerable RunValidation(ValidationResult result)
{
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
if (addressableAssetSettings == null) yield break;
foreach (var addressableAssetGroup in addressableAssetSettings.groups)
{
if (addressableAssetGroup == null) continue;
foreach (var addressableAssetEntry in addressableAssetGroup.entries)
{
var dependencyAssetPaths = AssetDatabase.GetDependencies(addressableAssetEntry.AssetPath)
.Where(assetPath => !assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) &&
!assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));
foreach (var dependencyAssetPath in dependencyAssetPaths)
{
var dependencyGUID = new GUID(AssetDatabase.AssetPathToGUID(dependencyAssetPath));
if (this.IgnoredGUIDs.Contains(dependencyGUID.ToString())) continue;
var dependencyAddressableAssetEntry = addressableAssetSettings.FindAssetEntry(dependencyGUID.ToString());
var isAddressable = dependencyAddressableAssetEntry != null;
if (isAddressable) continue;
if (!IsInsideResourcesFolder(dependencyAssetPath)) continue;
result.Add(this.ValidatorSeverity, $"{dependencyAssetPath} is duplicated in addressable data and resource folders.")
.WithFix<FixArgs>(args =>
{
if (args.FixChoice == FixChoice.Ignore)
{
var sourceType = args.IgnoreForEveryone ? ConfigSourceType.Project : ConfigSourceType.Local;
var data = RuleConfig.Instance.GetRuleData<CheckResourcesToAddressableDuplicateDependenciesValidator>(sourceType);
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
RuleConfig.Instance.SetAndSaveRuleData(data, sourceType);
return;
}
if (!ValidNewFolder(args.NewFolder, out _)) return;
if (!AssetDatabase.IsValidFolder(args.NewFolder))
{
Directory.CreateDirectory(new DirectoryInfo(args.NewFolder).FullName);
AssetDatabase.Refresh();
}
var newPath = $"{args.NewFolder}/{Path.GetFileName(dependencyAssetPath)}";
AssetDatabase.MoveAsset(dependencyAssetPath, newPath);
}, false).WithModifyRuleDataContextClick<CheckResourcesToAddressableDuplicateDependenciesValidator>("Ignore", data =>
{
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
}).SetSelectionObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString())));
yield break;
}
}
}
}
private string DrawGUIDEntry(string guid)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
EditorGUILayout.TextArea(assetPath, SirenixGUIStyles.MultiLineLabel);
EditorGUILayout.TextField(guid);
return guid;
}
private static bool IsInsideResourcesFolder(string path)
{
var pathElements = path.Split('/');
foreach (var pathElement in pathElements)
{
if (pathElement.Equals("Resources", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static bool ValidNewFolder(string path, out string message)
{
if (IsInsideResourcesFolder(path))
{
message = "The asset cannot be moved into a 'Resources' folder";
return false;
}
if (!path.StartsWith("Assets/"))
{
message = "The asset must be inside the 'Assets' folder";
return false;
}
message = "The folder is valid";
return true;
}
private enum FixChoice
{
MoveAsset,
Ignore,
}
private class FixArgs
{
[HideLabel]
[EnumToggleButtons]
public FixChoice FixChoice;
[FolderPath]
[PropertySpace(10)]
[ValidateInput(nameof(ValidateFolderPath))]
[ShowIf("FixChoice", FixChoice.MoveAsset, Animate = false)]
public string NewFolder = "Assets/Resources_moved";
[LabelWidth(120f)]
[PropertySpace(10)]
[ShowIf("FixChoice", FixChoice.Ignore, Animate = false)]
public bool IgnoreForEveryone = true;
private bool ValidateFolderPath(string path, ref string message)
{
return ValidNewFolder(path, out message);
}
}
}
}
#endif

View File

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

Some files were not shown because too many files have changed in this diff Show More