You can use Loadable on classes derived from MonoBehaviour or ScriptableObject to establish on-demand references from one object to another.
So my expectation is that calling LoadableTest.loadableGameObject.Load() gives me prefab A.
When running in the Editor this works, but in a standalone player I get an error that the content could not be loaded. The Content Directory seems to be properly registered though.
Have you built the data for the content directory yet?
If you haven’t already, please follow the instructions here.
using UnityEditor;
using UnityEditor.Build.Reporting;
public static class BuildContentPackRootAsset
{
[MenuItem("Build/Content Directories/Content Pack")]
public static void Build()
{
var parameters = new BuildContentDirectoryParameters
{
// Folder for the built content directory (created if it does not exist).
// Typically should be outside the Assets folder.
outputPath = "Builds/ContentPack",
// Project paths to ScriptableObject root assets for this pack.
// Unity includes each root and every asset they reference (direct, Loadable, scenes).
rootAssetPaths = new[]
{
"Assets/ContentPacks/ContentPackRootAsset.asset"
},
// Optional build flags (for example BuildContentOptions.CleanBuildCache).
// See BuildContentOptions in the Scripting Reference.
options = BuildContentOptions.None,
};
// Uses the active build target from Build Profiles.
BuildReport report = BuildPipeline.BuildContentDirectory(parameters);
if (report.summary.result == BuildResult.Succeeded)
UnityEngine.Debug.Log($"Content directory built to: {parameters.outputPath}");
}
}
The player build and content directory build systems are (currently) isolated, with equally isolated loading systems.
That Loadable in LoadableTest is pointing at player content, and loading via the player builds loading system.
The way you’d do it is include the scene as a LoadableScene in the content directory build, and load that LoadableScene rather than one in the scene list.
We’re working on reconciling player content and content directories, but we’re not there yet.
It should have errored out for you at player build time to flag the above, let me work out with my team why it didn’t, but hopefully that’s enough to get you rolling.
I see, so player content can’t have Loadable references to content that’s being shipped as part of content directories currently?
Instead I guess if you want to load something from a content directory you always have to use ContentLoadManager.GetRootAssets to get an instance of your ScriptableObject and use the Loadables on that to get to the content?
That wasn’t really clear to me from the documentation.
This sounds like it should still load the content then, just from the player content instead of the content directory content? But it’s throwing an error instead.
100% fair point re-documentation, I’ll pick that up.
That’s correct re-the ScriptableObject.
The content directory loading system is specifically designed to support loadables, so they may only be loaded within the content directory context. You can consider those concepts coupled for now.
We’re working hard on making sure all the different facets of Unity use the new backend (inc. the player) but 6.6 is really just our first step.
Here’s what I understand so far (please correct me if I am wrong):
Any Loadable (Loadable<T> / LoadableSceneId / LoadableObjectId) should live in a content directory. They can’t live in Player Build.
The player build can’t directly refer any kind of loadable (via inspector). Only through ContentLoadManager.RegisterContentDirectory. As the content directory’s path needs to be resolved during runtime.
A loadable can refer another loadable, example a MonoBehaviour in a LoadableSceneId scene referring a prefab using Loadable<T> (if they are part of different content directories, they will be duplicated as required).
A Loadable<T>'s result can be instantiated and then the loadable be released immediately. The instances will still stay. At least that’s how it works for prefab as per my experiments so far. I haven’t tested but probably you can even release the ContentDirectoryHandle.
LoadableSceneId seem to behave quite differently, and I am still trying to figure them out properly. It seems they can’t be released? My understanding is they get released automatically when we unload the scene, or that they are not loaded in the same way, rather always instantiated. However, releasing it’s ContentDirectoryHandle crashes Editor and breaks the Player Build. So I am not really sure how they work.
Unfortunately the documentation around content directories is quite lacking and confusing, and there’s a lack of proper warnings/error in the editor too. Those could be really helpful.
Also, in fact there are some difference in how the loadables behave in editor and a build. You can use direct references to loadables (eg Loadable<T> in inspector) in the editor even from player build assets/scene, without any problems, but they break in a build, adding to the confusion.