87 lines
3.2 KiB
C#
87 lines
3.2 KiB
C#
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Creates an AssetReference that is restricted to having a specific Component.
|
|
/// * This is the class that inherits from AssetReference. It is generic and does not specify which Components it might care about. A concrete child of this class is required for serialization to work.
|
|
/// * At edit-time it validates that the asset set on it is a GameObject with the required Component.
|
|
/// * At runtime it can load/instantiate the GameObject, then return the desired component. API matches base class (LoadAssetAsync & InstantiateAsync).
|
|
/// </summary>
|
|
/// <typeparam name="TComponent">The component type.</typeparam>
|
|
public class ComponentReference<TComponent> : AssetReference
|
|
{
|
|
/// <inheritdoc />
|
|
public ComponentReference(string guid) : base(guid)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public new AsyncOperationHandle<TComponent> InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent = null)
|
|
{
|
|
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(position, Quaternion.identity, parent), GameObjectReady);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public new AsyncOperationHandle<TComponent> InstantiateAsync(Transform parent = null, bool instantiateInWorldSpace = false)
|
|
{
|
|
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(parent, instantiateInWorldSpace), GameObjectReady);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public AsyncOperationHandle<TComponent> LoadAssetAsync()
|
|
{
|
|
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.LoadAssetAsync<GameObject>(), GameObjectReady);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
AsyncOperationHandle<TComponent> GameObjectReady(AsyncOperationHandle<GameObject> arg)
|
|
{
|
|
var comp = arg.Result.GetComponent<TComponent>();
|
|
return Addressables.ResourceManager.CreateCompletedOperation<TComponent>(comp, string.Empty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates that the assigned asset has the component type
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
public override bool ValidateAsset(Object obj)
|
|
{
|
|
var go = obj as GameObject;
|
|
return go != null && go.GetComponent<TComponent>() != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates that the assigned asset has the component type, but only in the Editor
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public override bool ValidateAsset(string path)
|
|
{
|
|
#if UNITY_EDITOR
|
|
//this load can be expensive...
|
|
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
return go != null && go.GetComponent<TComponent>() != null;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void ReleaseInstance(AsyncOperationHandle<TComponent> op)
|
|
{
|
|
// Release the instance
|
|
var component = op.Result as Component;
|
|
if (component != null)
|
|
{
|
|
Addressables.ReleaseInstance(component.gameObject);
|
|
}
|
|
|
|
// Release the handle
|
|
Addressables.Release(op);
|
|
}
|
|
}
|