diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs b/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs similarity index 61% rename from Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs rename to Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs index a7bd5581..8aaa3ef0 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs @@ -1,16 +1,22 @@ +using System; +using System.Collections; using UnityEngine; using UnityEditor; -[CustomPropertyDrawer(typeof(GameObjectReference))] -public class GameObjectReferenceDrawer : PropertyDrawer +[CustomPropertyDrawer(typeof(AssetReference), true)] +public class AssetReferenceDrawer : PropertyDrawer { private const float LineSpacing = 2f; + private Type _assetType; + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty packageNameProp = property.FindPropertyRelative("_packageName"); SerializedProperty assetGUIDProp = property.FindPropertyRelative("_assetGUID"); + Type assetType = GetAssetType(); + EditorGUI.BeginProperty(position, label, property); { float lineHeight = EditorGUIUtility.singleLineHeight; @@ -19,19 +25,19 @@ public class GameObjectReferenceDrawer : PropertyDrawer // 绘制 PackageName packageNameProp.stringValue = EditorGUI.TextField(line, "Package Name", packageNameProp.stringValue); - // 加载 GameObject + // 加载当前资源对象 string assetGUID = assetGUIDProp.stringValue; - GameObject current = null; + UnityEngine.Object current = null; if (string.IsNullOrEmpty(assetGUID) == false) { string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID); if (string.IsNullOrEmpty(assetPath) == false) - current = AssetDatabase.LoadAssetAtPath(assetPath); + current = AssetDatabase.LoadAssetAtPath(assetPath, assetType); } - // 绘制 GameObject + // 绘制资源对象字段 line.y += lineHeight + LineSpacing; - GameObject newAsset = (GameObject)EditorGUI.ObjectField(line, "Game Object", current, typeof(GameObject), false); + UnityEngine.Object newAsset = EditorGUI.ObjectField(line, assetType.Name, current, assetType, false); if (newAsset != current) { if (newAsset == null) @@ -46,7 +52,7 @@ public class GameObjectReferenceDrawer : PropertyDrawer } } - // 绘制 AssetGUID + // 绘制 AssetGUID(只读) line.y += lineHeight + LineSpacing; EditorGUI.BeginDisabledGroup(true); EditorGUI.TextField(line, "Asset GUID", assetGUIDProp.stringValue); @@ -54,8 +60,31 @@ public class GameObjectReferenceDrawer : PropertyDrawer } EditorGUI.EndProperty(); } + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return EditorGUIUtility.singleLineHeight * 3 + LineSpacing * 2; } + + /// + /// 通过反射获取字段对应子类的 AssetType + /// + private Type GetAssetType() + { + if (_assetType != null) + return _assetType; + + Type fieldType = fieldInfo.FieldType; + + // 兼容数组 + if (fieldType.IsArray) + fieldType = fieldType.GetElementType(); + // 兼容 List + else if (fieldType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(fieldType)) + fieldType = fieldType.GetGenericArguments()[0]; + + var instance = (AssetReference)Activator.CreateInstance(fieldType); + _assetType = instance.AssetType; + return _assetType; + } } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs.meta similarity index 83% rename from Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs.meta rename to Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs.meta index e47ae1b3..28cbca10 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/GameObjectReferenceDrawer.cs.meta +++ b/Assets/YooAsset/Samples~/Extension Sample/Editor/AssetReference/AssetReferenceDrawer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 53eb285fc3a7b614089a000f8c9c738c +guid: ee2a8d68b06fc434c8d70a9e1d94caf6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs similarity index 66% rename from Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs rename to Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs index 63243145..fd2902e3 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs @@ -3,19 +3,19 @@ using UnityEngine; using YooAsset; /// -/// 游戏对象弱引用,序列化时只保存资源 GUID +/// 资源弱引用基类 /// [Serializable] -public class GameObjectReference +public abstract class AssetReference { [SerializeField] - private string _packageName = "DefaultPackage"; + protected string _packageName = "DefaultPackage"; [SerializeField] - private string _assetGUID = ""; + protected string _assetGUID = ""; [NonSerialized] - private AssetHandle _handle; + protected AssetHandle _handle; /// /// 资源所属的包裹名称 @@ -27,6 +27,16 @@ public class GameObjectReference /// public string AssetGUID => _assetGUID; + /// + /// 当前加载句柄(未加载时为 null) + /// + public AssetHandle Handle => _handle; + + /// + /// 该引用负责加载的资源类型,由子类指定 + /// + public abstract Type AssetType { get; } + /// /// 检查运行时引用键是否有效 @@ -37,18 +47,18 @@ public class GameObjectReference return false; var package = YooAssets.GetPackage(_packageName); - var assetInfo = package.GetAssetInfoByGuid(_assetGUID, typeof(GameObject)); + var assetInfo = package.GetAssetInfoByGuid(_assetGUID, AssetType); return assetInfo.IsValid; } /// - /// 异步加载引用的游戏对象 + /// 异步加载引用的资源 /// /// 加载操作句柄 public AssetHandle LoadAssetAsync() { if (_handle != null) - throw new InvalidOperationException("GameObject reference has already been loaded. Release it first."); + throw new InvalidOperationException($"{GetType().Name} has already been loaded. Release it first."); if (string.IsNullOrEmpty(_packageName)) throw new ArgumentException("Package name is not set.", nameof(_packageName)); @@ -56,7 +66,7 @@ public class GameObjectReference throw new ArgumentException("Asset GUID is not set.", nameof(_assetGUID)); var package = YooAssets.GetPackage(_packageName); - var assetInfo = package.GetAssetInfoByGuid(_assetGUID, typeof(GameObject)); + var assetInfo = package.GetAssetInfoByGuid(_assetGUID, AssetType); _handle = package.LoadAssetAsync(assetInfo); return _handle; } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs.meta similarity index 83% rename from Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs.meta rename to Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs.meta index 43631680..371b4d3e 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/GameObjectReference.cs.meta +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReference.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 15552077c0d6ff441a4cd62af62b7d5a +guid: 7de4fe4f4d6834c47977a97c7ad20bd3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs new file mode 100644 index 00000000..0e5b96f3 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +/// +/// GameObject 资源弱引用 +/// +[Serializable] +public class AssetReferenceGameObject : AssetReference +{ + public override Type AssetType => typeof(GameObject); +} diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs.meta new file mode 100644 index 00000000..dcf75e13 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceGameObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 764d480d7edd8cd48b8105dc6b24bd2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceSample.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceSample.cs index f1a305d7..d53aa827 100644 --- a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceSample.cs +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceSample.cs @@ -3,36 +3,58 @@ using UnityEngine; using YooAsset; /// -/// 演示如何使用 GameObjectReference 弱引用加载并实例化游戏对象 +/// 演示如何使用 AssetReference 弱引用加载不同类型的资源 /// public class AssetReferenceSample : MonoBehaviour { [SerializeField] - private GameObjectReference _reference; + private AssetReferenceGameObject _prefabReference; + + [SerializeField] + private AssetReferenceTexture2D _textureReference; private IEnumerator Start() { - if (_reference.RuntimeKeyIsValid() == false) + // 加载并实例化预制体 + if (_prefabReference.RuntimeKeyIsValid()) { - yield break; + AssetHandle handle = _prefabReference.LoadAssetAsync(); + yield return handle; + + if (handle.Status == EOperationStatus.Succeeded) + { + GameObject instance = handle.InstantiateSync(new InstantiateOptions(true, transform, false)); + if (instance == null) + Debug.LogError($"Failed to instantiate GameObject reference '{_prefabReference.AssetGUID}'."); + } + else + { + Debug.LogError($"Failed to load GameObject reference '{_prefabReference.AssetGUID}': {handle.Error}."); + } } - AssetHandle handle = _reference.LoadAssetAsync(); - yield return handle; + // 加载纹理并赋值给渲染器材质 + if (_textureReference.RuntimeKeyIsValid()) + { + AssetHandle handle = _textureReference.LoadAssetAsync(); + yield return handle; - if (handle.Status == EOperationStatus.Succeeded) - { - GameObject instance = handle.InstantiateSync(new InstantiateOptions(true, transform, false)); - if (instance == null) - Debug.LogError($"Failed to instantiate GameObject reference '{_reference.AssetGUID}'."); - } - else - { - Debug.LogError($"Failed to load GameObject reference '{_reference.AssetGUID}': {handle.Error}."); + if (handle.Status == EOperationStatus.Succeeded) + { + var renderer = GetComponent(); + if (renderer != null) + renderer.material.mainTexture = handle.AssetObject as Texture2D; + } + else + { + Debug.LogError($"Failed to load Texture2D reference '{_textureReference.AssetGUID}': {handle.Error}."); + } } } + private void OnDestroy() { - _reference.ReleaseAsset(); + _prefabReference?.ReleaseAsset(); + _textureReference?.ReleaseAsset(); } } diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs new file mode 100644 index 00000000..18d4fcb2 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +/// +/// Texture2D 资源弱引用 +/// +[Serializable] +public class AssetReferenceTexture2D : AssetReference +{ + public override Type AssetType => typeof(Texture2D); +} diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs.meta new file mode 100644 index 00000000..7877c3b2 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c6c6d8423826d24083eb0608e0fd023 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs new file mode 100644 index 00000000..8b0c7b09 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +/// +/// Texture3D 资源弱引用 +/// +[Serializable] +public class AssetReferenceTexture3D : AssetReference +{ + public override Type AssetType => typeof(Texture3D); +} diff --git a/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs.meta b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs.meta new file mode 100644 index 00000000..4898e9a6 --- /dev/null +++ b/Assets/YooAsset/Samples~/Extension Sample/Runtime/AssetReference/AssetReferenceTexture3D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be5c51911e8f45a45b7ed11af7d0b50c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: