Using the Addressable Assets preview package in TL7!
LouisHong - https://forum.unity.com/threads/addressables-are-here.536304/

Using the Addressable Assets preview package in TL7!

TL;DR it was an awesome experience - diving into the package and understanding how to integrate it with my game’s current architecture was quite insightful!

Motivation

I recently learned about the Addressable Assets package (still in preview), which combines the best of both Resources and Asset Bundles, allowing one to locate assets irrespective of them being local or remote. Curious, I put my hand into the honeypot and began investigating.

Technique

I decided to replace the direct Weapon references using AssetReferences (the package adds on to the editor, allowing one to simply tick off the items one would want to use as Addressable Assets). The main difference from the technique in the lectures is that the assets must always be loaded asynchronously. So, I had to wrap the Equip call within a callback, which completed when the asset finished loading.

public void LoadEquipAsync(in AssetReference weaponAsset)
{
    currentWeaponAsset = weaponAsset;
    currentWeaponAsset.LoadAssetAsync<Weapon>().Completed +=
        (weaponHandle) => Equip(weaponHandle.Result);
}

The WeaponPickups would have to store AssetReferences instead of direct references to Weapons. I also decided that pickups for the same weapon should be noticed as well.

public class WeaponPickup : MonoBehaviour
{
    [SerializeField] AssetReference weaponAsset = null;

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            var fighter = other.GetComponent<Fighter>();
            if (!fighter.IsSameWeaponAsset(weaponAsset))
            {
                fighter.LoadEquipAsync(weaponAsset);
                Destroy(gameObject);
            }
        }
    }
}

Now, if you’re paying attention, you might have several questions in your mind:

  1. How am I going to serialize the AssetReferences? Last I checked these aren’t serializable (though the docs say they are - again - if you’ve been paying attention)!
  2. How on Earth do you know whether two assets are the same or not?

The answer came to me in a few precious hours after I found these two mysterious things in the AssetReferences docs.

  1. This.png
  2. AndThis.png

Bingo! All we need to do is serialize this GUID and reconstruct the AssetReference with it! Since it’s unique for every object, it’s easy to compare AssetReferences with!

After a miniature war with the machine, I figured out that the GUID was always wrapped [like this... yikes]. Thus, this code came into fruition:

public static class AssetReferenceExtensions
{
    public static string GetGuid(this AssetReference assetReference)
    {
        return (assetReference != null) ?
                assetReference.ToString().Trim(new char[] { '[', ']' }) : string.Empty;
    }
}

This code allowed me to write this.

public bool IsSameWeaponAsset(in AssetReference weaponAsset) =>
            currentWeaponAsset.GetGuid().Equals(weaponAsset.GetGuid());

With a bit of C# nuance and my own idiosyncrasies, the State would now end up looking like this.

object ISaveable.State
{
    get => (currentWeaponAsset ?? defaultWeaponAsset).GetGuid();
    set => LoadEquipAsync(new AssetReference((string)value));
}

I maintain two AssetReferences for easier management, but it can most definitely be one - with a bit of ingenuity - which I lack at the moment.

Summary

Suffice to say, the results are plausibly the same for both methods, but Addressable Assets aims to do much more. A quick online search reveals blog posts, documentation, best practices - you name it!

Here’s my complete code, if you have come this far, and want to look at how I attempt to use the latest C# for doing mumbo-jumbo. Disclaimer: I haven't updated its README yet. Apologies.

Thanks for reading!

要查看或添加评论,请登录

社区洞察