I’m looking for advice on the best way to manage my assets/resources.
It looks like there are a few ways to handle assets.
-Scenes (when a scene in included in a build so are the assets in the scene)
-Resources folder (EVERYTHING in the resources folder is included in the build)
-Asset bundles
-Addressable Asset System
-Editor (I load many assets in editor to automate… but these are not used in the build at runtime)
And within each of these options there are many ways to build and load/unload assets. Interdependent references & shared assets. It’s kind of overwhelming.
Currently I use the Resources folder. But this has 2 problems
1: It has a 4GB limit ( Bug: 4GB limit to Textures in standalone build )
2: It is inefficient (everything is the folder is built… even file’s I don’t use)
So I’m moving away from the resources folder to a new system. But I’m not sure what that system should be.
Is it safe to use Asset Bundles or will they be depreciated soon with the introduction of the Addressable Asset System? Or is the Addressable Asset System just another interface layer on top of Asset Bundles meaning Asset Bundles are here to stay?
Here’s a video of editor prefab generation.
For runtime I load levels that contain prefabs. But almost everything else is generated by script (GUI, monsters, equipment, etc.). I have a reference to every asset in a script (here’s an example).
public static readonly BatEnumAudioClip KeyCaveWormAttack = new BatEnumAudioClip(3003, "KeyCaveWormAttack", "Audio/Effects/FreeSoundDotOrg/CaveWormAttack/172004__skinnysoundguy__creature-beast-retch");
public static readonly BatEnumAudioClip KeyCaveWormDie = new BatEnumAudioClip(3004, "KeyCaveWormDie", "Audio/Effects/FreeSoundDotOrg/CaveWormDie/177453__andromadax24__s-pain-slith-16");
public static readonly BatEnumAudioClip KeyCaveWormUnburrow = new BatEnumAudioClip(3005, "KeyCaveWormUnburrow", "Audio/Effects/FreeSoundDotOrg/CaveWormUnburrow/169557__jorickhoofd__gravel-impact-3");
public static readonly BatEnumAudioClip KeyCaveWormUnburrow2 = new BatEnumAudioClip(3006, "KeyCaveWormUnburrow2", "Audio/Effects/FreeSoundDotOrg/CaveWormUnburrow2/121893__stephensaldanha__creature-small-high-pitch-roar", volumeMultIn: 2.5f);
public static readonly BatEnumAudioClip KeyCaveWormDigLoop = new BatEnumAudioClip(3007, "KeyCaveWormDigLoop", "Audio/Effects/FreeSoundDotOrg/CaveWormDigLoop/82722__prozaciswack__digging", volumeMultIn: 0.5f, r1In: 1f, r2In: 6f);
public static readonly BatEnumAudioClip KeyPortalLoop = new BatEnumAudioClip(3008, "KeyPortalLoop", "Prefabs/Scene/Portals/PortalScene/Stuff/L_Bughole_circle", r1In: 2f, r2In: 6f);
public static readonly BatEnumAudioClip KeyExplosion = new BatEnumAudioClip(3009, "KeyExplosion", "Audio/Effects/FreeSoundDotOrg/110115__ryansnook__small-explosion", volumeMultIn: 0.4f);
public static readonly BatEnumAudioClip KeyFrostCastBegin = new BatEnumAudioClip(3010, "KeyFrostCastBegin", "Audio/Effects/FreeSoundDotOrg/Ice00/138484__randomationpictures__chill-hit");
public static readonly BatEnumAudioClip KeyRepel = new BatEnumAudioClip(3011, "KeyRepel", "Audio/Effects/FreeSoundDotOrg/Repel/139476__odeean__sound-jump");
public static readonly BatEnumAudioClip KeyBlock = new BatEnumAudioClip(3012, "KeyBlock", "Audio/Effects/FreeSoundDotOrg/218460__thomasjaunism__wood-block-hit_CC0");
public static readonly BatEnumAudioClip KeyBeep = new BatEnumAudioClip(3013, "KeyBeep", "Audio/Effects/Custom/Effect_Pyter_Laser Beam");
public static readonly BatEnumAudioClip KeyMiss = new BatEnumAudioClip(3014, "KeyMiss", "Audio/Effects/FreeSoundDotOrg/Miss/9509__petenice__whooshCC");
Then to use an asset I will basically call PlayAudioClipNetworked(KeyBeep) and it will play on all clients.
The reason I need a reference to every asset is for networking. If an audio clip is played what I do is send the auto clips integer ID across the network and tell all clients to play it. Then when the client receives the message they look up the asset from the ID and plays it locally.
I think these are the are the 2 things I want to include in my build.
1: Anything that’s in one of my scenes
2: Anything that’s referenced in one of my scripts!!! (Unsure the best way to do this)
… and dependencies.
Regarding what assets are loaded at runtime: Since my assets are not part of the scene I currently load them manually at application startup. It takes a few seconds and doesn’t take up that much memory. I don’t have that many assets and loading almost everything at startup is doesn’t seem too bad at the moment. The alternative is to load assets the 1st time they are used… but this can create glitchy gameplay. (i.e. the 1st time an explosion occurs it will have to load the explosion prefab, audio sources, etc. and causes a gltich)
Currently what I’m leaning towards is using my scripts that reference assets to also build Asset Bundles. That way anything that is not included in a script is not included in the build (unless it’s used in a scene).
From what I’ve read using Asset Bundles I will iterate through each asset and set it’s AssetImporter.assetBundleName to an asset bundle, or null if not used.
Then call BuildPipeline.BuildAssetBundles(…) to build all asset bundles.
Then at runtime load the assets from the bundle.
Does this seem like the proper approach?
Thanks in advance.