Modders currently have a template project they work from to create new systems and components. I am adding support for them to add new entities to the world. I am using the Content Management system to publish the subscene data, which contains their new entity prefabs, like this (which came from this thread: https://forum.unity.com/threads/how-to-actually-use-enable_content_delivery-in-build.1495526/):
[MenuItem("Modding/Content Update (fixed)")]
static void Execute()
{
string buildFolder = Path.Combine(Application.streamingAssetsPath, "ContentBuild");
if (!string.IsNullOrEmpty(buildFolder))
{
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
if (!Directory.Exists(Path.Combine(Path.GetDirectoryName(Application.dataPath),
$"Library/ContentUpdateBuildDir")))
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Application.dataPath),
$"Library/ContentUpdateBuildDir"));
if (!Directory.Exists(Path.Combine(Path.GetDirectoryName(Application.dataPath),
$"Library/ContentUpdateBuildDir/{PlayerSettings.productName}")))
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Application.dataPath),
$"Library/ContentUpdateBuildDir/{PlayerSettings.productName}"));
var tmpBuildFolder = Path.Combine(Path.GetDirectoryName(Application.dataPath),
$"Library/ContentUpdateBuildDir/{PlayerSettings.productName}");
var instance = DotsGlobalSettings.Instance;
var playerGuid = instance.GetPlayerType() == DotsGlobalSettings.PlayerType.Client
? instance.GetClientGUID()
: instance.GetServerGUID();
if (!playerGuid.IsValid)
throw new Exception("Invalid Player GUID");
var subSceneGuids = new HashSet<Unity.Entities.Hash128>();
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
{
var ssGuids = EditorEntityScenes.GetSubScenes(EditorBuildSettings.scenes[i].guid);
foreach (var ss in ssGuids)
{
if (!subSceneGuids.Contains(ss))
{
Debug.Log("GUID -> " + ss);
subSceneGuids.Add(ss);
}
}
}
if (subSceneGuids.Count == 0)
{
Debug.LogError("No SubScenes found");
return;
}
RemoteContentCatalogBuildUtility.BuildContent(subSceneGuids, playerGuid, buildTarget, tmpBuildFolder);
var publishFolder = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds",
$"{buildFolder}-RemoteContent");
RemoteContentCatalogBuildUtility.PublishContent(tmpBuildFolder, publishFolder, f => new string[] {"all"});
Debug.Log($"Publish Content Update complete to path {publishFolder}");
}
The resulting content is packaged up with the modder's other DLL's, and uploaded to the steam workshop. My game consumes that folder for subscribed mods, and then tries to load the subscene data like this:
RuntimeContentSystem.LoadContentCatalog(null, ModLoader.ModContentCache, "all");
ContentDeliveryGlobalState.Initialize(null, ModLoader.ModContentCache,
"all", s =>
{
if (s >= ContentDeliveryGlobalState.ContentUpdateState.ContentReady)
{
PerformWholeGameInitializationProcess();
}
});
I think I'm missing a step though because although it appears the Initialize was successful, the modded subscene does not actually get created and put into the game. The files in the ModContentCache path look correct, they are the result of the publish operation. I've attached an image.
Any ideas on what else needs to be done to actually load the subscene?