Asset mods

The Unity 2017.1.1 project and the AssetBundle pipeline.

Developers
How-to
3 min read

If your mod adds 3D content (a map, props, retextures), you need a second project: a Unity project that builds AssetBundles, alongside your C# plugin project.

4.1 Use Unity 2017.1.1 exactly

Build your AssetBundles in Unity 2017.1.1 — the version Jet Island shipped with. Other versions may not work and are untested. AssetBundles are sensitive to serialization changes between Unity versions, so matching the game's version avoids load failures.

4.2 The ExportAssetBundle.cs build script

Add an Editor script to your Unity project that creates an Assets/Build AssetBundle menu item and writes the bundle out. A minimal version:

// Place in an "Editor" folder: Assets/Editor/ExportAssetBundle.cs
using System.IO;
using UnityEditor;

public class ExportAssetBundle
{
    [MenuItem("Assets/Build AssetBundle")]
    static void BuildAllAssetBundles()
    {
        // Output into the project's StreamingAssets so it's easy to find.
        string outputPath = "Assets/StreamingAssets/AssetBundles";
        if (!Directory.Exists(outputPath))
            Directory.CreateDirectory(outputPath);

        BuildPipeline.BuildAssetBundles(
            outputPath,
            BuildAssetBundleOptions.None,
            BuildTarget.StandaloneWindows64   // Jet Island is a 64-bit Windows VR game
        );

        AssetDatabase.Refresh();
    }
}

Tag the prefabs/assets you want to ship with an AssetBundle name (the dropdown at the bottom of the Inspector). Then run Assets > Build AssetBundle. Your .unity3d bundle appears in Assets/StreamingAssets/AssetBundles/. Ship that file with your mod.

4.3 Load the bundle at runtime from your plugin

Because AssetBundles can't contain code, your plugin loads the bundle, pulls out a prefab, instantiates it, and attaches any custom behavior via AddComponent<>():

using System.IO;
using UnityEngine;

public static class MapLoader
{
    public static void SpawnFromBundle()
    {
        // The game-side StreamingAssets path; the .unity3d file ships next to the game.
        string path = Path.Combine(
            Application.streamingAssetsPath, "mymap.unity3d");

        AssetBundle bundle = AssetBundle.LoadFromFile(path);
        if (bundle == null)
        {
            Debug.LogError("[MyMod] Failed to load AssetBundle at " + path);
            return;
        }

        GameObject prefab = bundle.LoadAsset<GameObject>("MyMapRoot");
        GameObject instance = Object.Instantiate(prefab);

        // AssetBundles hold no code — add behavior here:
        instance.AddComponent<MyMapBehaviour>();

        // Keep the bundle reference if you'll load more assets; otherwise
        // bundle.Unload(false) frees the bundle but keeps loaded objects.
    }
}

AssetBundle.LoadFromFile is the fastest load path. Call it from a sensible point in your plugin (e.g. after the relevant level loads in OnLevelWasLoaded) and cache the bundle reference if you'll pull more than one asset from it.

Where do the .unity3d files go on the player's machine? Tell your users in the README. The natural location is the game's JetIsland_Data\StreamingAssets\ folder (which is what Application.streamingAssetsPath resolves to at runtime). Since asset placement isn't centrally standardized, always document the exact path your mod expects.



An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.