记录一下Addressables-Sample项目中的脚本和学习的笔记,主要是熟悉API及其使用方式.方便日后工作查询.
项目地址:
Unity官方教程
3.ComponentReference
此示例创建一个自己的泛型AssetReference,该AssetReference仅限于具有特定组件。
3.1 Scenes/SampleScene
Scripts/ComponentReference - ComponentReference
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class ComponentReference<TComponent> : AssetReference
{
public ComponentReference(string guid) : base(guid)
{
}
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);
}
public new AsyncOperationHandle<TComponent> InstantiateAsync(Transform parent = null, bool instantiateInWorldSpace = false)
{
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(parent, instantiateInWorldSpace), GameObjectReady);
}
public AsyncOperationHandle<TComponent> LoadAssetAsync()
{
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.LoadAssetAsync<GameObject>(), GameObjectReady);
}
AsyncOperationHandle<TComponent> GameObjectReady(AsyncOperationHandle<GameObject> arg)
{
var comp = arg.Result.GetComponent<TComponent>();
return Addressables.ResourceManager.CreateCompletedOperation<TComponent>(comp, string.Empty);
}
public override bool ValidateAsset(Object obj)
{
var go = obj as GameObject;
return go != null && go.GetComponent<TComponent>() != null;
}
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
}
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);
}
}
- 这是从AssetReference继承的类。它是通用的,没有指定它可能关心哪些组件。序列化工作需要此类的具体子类。
- 在编辑时,它会验证其上的资产集是否是具有所需组件的游戏对象。
- 在运行时,它可以加载/实例化游戏对象,然后返回所需的组件。API匹配基类(LoadAssetAsync和InstanceEasync)。
Scripts/ColorChanger - ColorChanger & ComponentReferenceColorChanger
using System;
using UnityEngine;
public class ColorChanger : MonoBehaviour
{
public void SetColor(Color col)
{
var rend = GetComponent<MeshRenderer>();
var material = rend.material;
material.color = col;
}
}
[Serializable]
public class ComponentReferenceColorChanger : ComponentReference<ColorChanger>
{
public ComponentReferenceColorChanger(string guid)
: base(guid) { }
}
- 我们选择关注的组件类型。
- 请注意,此文件包含ComponentReference的具体版本。这是必要的,因为如果您的游戏代码只是指定了一个ComponentReference,它就无法序列化或显示在检查器中。这个ComponentReferenceColorChanger使序列化和inspector UI工作。
- 应通过ComponentReference类中的ReleaseInstance()释放ComponentReference。要直接发布实例,请参阅ReleaseInstance实现以了解需求。
Scripts/Spawner
using System;
using UnityEngine;
using UnityEngine.ResourceManagement.AsyncOperations;
public class Spawner : MonoBehaviour
{
public ComponentReferenceColorChanger ColorShifterReference;
public ColorChanger ColorShifterDirect;
int m_Counter = 10000;
void FixedUpdate()
{
m_Counter++;
if (m_Counter == 15)
{
//note that this could work as an Instantiate or a Load.
//ColorShifterReference.LoadComponentAsync().Completed += LoadDone;
ColorShifterReference.InstantiateAsync().Completed += InstantiateDone;
}
else if (m_Counter > 30)
{
ColorChanger changer = Instantiate(ColorShifterDirect);
changer.SetColor(RandomColor());
m_Counter = 0;
}
}
//if using the LoadComponentAsync version above...
void LoadDone(AsyncOperationHandle<ColorChanger> obj)
{
if (obj.Result != null)
{
ColorChanger changer = Instantiate(obj.Result);
changer.SetColor(RandomColor());
}
}
//if using the InstantiateComponentAsync version above...
void InstantiateDone(AsyncOperationHandle<ColorChanger> obj)
{
if(obj.Result != null)
obj.Result.SetColor(RandomColor());
}
Color RandomColor()
{
return new Color(UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f));
}
}
- 对前面两个脚本的应用.