Skip to content

Using asynchronous methods for loading game prefabs

zorgesho edited this page Apr 26, 2021 · 3 revisions

Currently Subnautica on the experimental branch supports only asynchronous loading for prefabs from resources. Mods that add new tech types based on game prefabs and use GetGameObject for preparing their prefabs will not work on the exp branch. Also, they'll not work on the stable branch after that update hit it (no one knows when/if it'll happen).

In order to work, mods should be updated with adding GetGameObjectAsync method to their prefabs. Both GetGameObject and GetGameObjectAsync methods are needed in the ModPrefab for now (so they'll work on both branches).

Following example shows how your code can be changed from synchronous to asynchronous (example is put together from CustomFabricator.cs in SMLHelper).

Sync->async using TechType

A sync way for creating prefab using TechType:

public override GameObject GetGameObject()
{
    GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.Fabricator);
    GameObject resultPrefab = Object.Instantiate(originalPrefab);
	
    // ... some prefab processing
	
    return resultPrefab;
}

Same prefab in an async way:

public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
{
    CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.Fabricator);
    yield return task;
    GameObject originalPrefab = task.GetResult();
    GameObject resultPrefab = Object.Instantiate(originalPrefab);

    // ... some prefab processing

    gameObject.Set(resultPrefab);
}

Sync->async using resource path

A sync way for creating prefab using resource path:

public override GameObject GetGameObject()
{
    GameObject originalPrefab = Resources.Load<GameObject>("Submarine/Build/CyclopsFabricator");
    // or you can use
    // GameObject originalPrefab = UWE.PrefabDatabase.GetPrefabForFilename("Submarine/Build/CyclopsFabricator");

    GameObject resultPrefab = Object.Instantiate(originalPrefab);

    // ... some prefab processing

    return resultPrefab;
}

Same prefab in an async way (make sure to add ".prefab" extension):

public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
{
    IPrefabRequest request = UWE.PrefabDatabase.GetPrefabForFilenameAsync("Submarine/Build/CyclopsFabricator.prefab");
    yield return request;
    request.TryGetPrefab(out GameObject originalPrefab);

    GameObject resultPrefab = Object.Instantiate(originalPrefab);

    // ... some prefab processing

    gameObject.Set(resultPrefab);
}

Keep in mind that you need both GetGameObject and GetGameObjectAsync methods. Once you get prefab from the game, you can work with it in the same way regardless of the method, so you can move prefab processing code to some common method.

GetGameObjectAsync can be added before the async game update, that way your mod will work on both branches before and after the async update (at least crafting part will work, mods still can be broken for other reasons).

To make sure that upcoming game update will not break your mod, test it on the experimental branch from time to time.

Please note that some pages are under construction and the links to them will be enabled as they are completed

Home
Quick Start Guide

[Adding]

[Editing]

[General Utilities]

[Language]

Clone this wiki locally