Last active
February 12, 2019 10:08
-
-
Save andrievsky/19186d13acefe0a2acad8b65d59d5061 to your computer and use it in GitHub Desktop.
Serialize asset string uri instead of Unity reference to decouple assets from each other and improve loading performance.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using Object = UnityEngine.Object; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
#endif | |
/** | |
* Usage | |
* | |
* // Bind in default way | |
* [AssetUri(typeof(Sprite))] public string SpriteUri; | |
* | |
* // Bind in custom way | |
* SpriteUri = (Sprite) AssetUriDrawer.Field("Select Sprite", SpriteUri, typeof(Sprite)); | |
* | |
* // Load resource at runtime | |
* void Start() { | |
* var sprite = AssetUriLoader.Load<Sprite>(SpriteUri); | |
* } | |
*/ | |
public class AssetUri : PropertyAttribute | |
{ | |
public readonly Type Type; | |
public AssetUri(Type type) | |
{ | |
Type = type ?? typeof(Object); | |
} | |
} | |
public static class AssetUriLoader | |
{ | |
public const string DefaultResourcesPath = "Assets/Resources/"; | |
public static T Load<T>(string uri) where T : Object | |
{ | |
return Resources.Load<T>(uri); | |
} | |
public static Object Load(string uri) | |
{ | |
return Resources.Load(uri); | |
} | |
} | |
#if UNITY_EDITOR | |
[CustomPropertyDrawer(typeof(AssetUri))] | |
public class AssetUriDrawer : PropertyDrawer | |
{ | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
if (property.propertyType != SerializedPropertyType.String) | |
{ | |
EditorGUI.LabelField(position, label.text, "Use AssetUri with string."); | |
return; | |
} | |
var attr = attribute as AssetUri; | |
var uri = property.stringValue; | |
Object value = null; | |
if (!string.IsNullOrEmpty(uri)) | |
{ | |
value = AssetUriLoader.Load(uri); | |
} | |
property.stringValue = Resolve(EditorGUI.ObjectField(position, value, attr.Type, false)); | |
} | |
public static string Field(string label, string uri, Type type) | |
{ | |
Object value = null; | |
if (!string.IsNullOrEmpty(uri)) | |
{ | |
value = AssetUriLoader.Load(uri); | |
} | |
return Resolve(EditorGUILayout.ObjectField(label, value, type, false)); | |
} | |
public static string Resolve(Object value) | |
{ | |
if (value == null) | |
{ | |
return null; | |
} | |
var assetPath = AssetDatabase.GetAssetPath(value); | |
if (string.IsNullOrEmpty(assetPath)) | |
{ | |
return null; | |
} | |
if (!assetPath.Contains(AssetUriLoader.DefaultResourcesPath)) | |
{ | |
throw new ArgumentException("Asset should be in " + AssetUriLoader.DefaultResourcesPath); | |
} | |
var startIndex = AssetUriLoader.DefaultResourcesPath.Length; | |
var endIndex = assetPath.LastIndexOf('.'); | |
if (endIndex == -1) | |
{ | |
throw new ArgumentException("Asset file name should ends with .*"); | |
} | |
return assetPath.Substring(startIndex, endIndex - startIndex); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment