Making an AssetBundle
An AssetBundle is a file Unity builds that holds a model with its materials and textures. A content item can wear a model from one ("model": { "bundle": "file", "asset": "Name" } in a content pack, or ModelBundlePath + ModelAsset in code; see Custom content).
This walks from a model in Blender to a bundle the game loads. You need Blender (any recent version) and Unity 2020.3.
Rules first
- Unity 2020.3, built-in render pipeline. The game is built with Unity 2020.3.44f1. Bundles from other major versions may fail to load; 2020.3 patch versions work (2020.3.34f1 was used to test). URP and HDRP materials show up pink.
- One mesh. The kit uses the first mesh in your model. Join the parts into one object before exporting; one mesh can still have several materials.
- No scripts. Only the model, its materials and textures. Scripts in a bundle can't run in the game.
- Only what you may share. Your own work, or models whose license allows it (keep their credit in your pack and on your mod page). Never models extracted from the game or other games.
1. Prepare the model in Blender
Size it in metres. Blender's units are metres, and so are the game's. Check the Dimensions in the N panel against your template's
sizein the content dump's items.json, or a similar item's: that's how big the game's own model is. Typical sizes, width x height x depth, measured from the game:Kind Examples Drinks, dishes Glass drink 0.10 x 0.15 x 0.09 m; plated dish about 0.26 x 0.06 x 0.23 m; coffee mug 0.16 x 0.10 x 0.12 m Desk and shelf items Mouse 0.10 x 0.15 x 0.11 m; headphones 0.18 x 0.22 x 0.11 m; table lamp 0.19 x 0.48 x 0.19 m; radio 0.29 x 0.50 x 0.16 m; small potted plant 0.21 x 0.34 x 0.20 m Seating Stool 0.41 x 0.47 x 0.45 m; bar chair 0.39 x 0.80 x 0.39 m; dining chair 0.49 x 1.07 x 0.64 m; two-seat sofa 1.73 x 0.86 x 0.78 m Tables Table 0.92 x 0.79 x 0.94 m; long table 1.96 x 0.77 x 0.99 m; high table 1.64 x 1.08 x 0.75 m Kitchen Base cabinet 0.60 or 0.90 x 0.99 x 0.66 m; wall cabinet 0.90 x 0.44 x 0.33 m; range 0.90 x 0.99 x 0.66 m; washing machine 0.73 x 1.04 x 0.75 m Bigger furniture Book shelf 0.69 x 1.60 x 0.35 m; floor lamp 0.39 x 1.40 x 0.39 m; single bed 1.00 x 0.57 x 2.13 m; vending machine about 1.3 x 2.1 x 0.6 m On the wall Painting about 0.92 x 0.92 m, 0.01 to 0.04 m deep; wall TV 1.02 x 0.62 x 0.08 m; small photo frame 0.46 x 0.36 x 0.07 m Floor Carpet 1.84 x 1.38 m up to 4.8 x 2.7 m, 0.01 to 0.04 m thick Thomas, as a shelf ornament, is 0.12 x 0.17 x 0.35 m: radio-sized. Matching the template's size also means the placement box (fitted to your model) sits where players expect.
Put the origin at the bottom centre. The game places an object by its origin, so an origin in the middle sinks half the model into the shelf. Snap the 3D cursor to the base (Shift+S), then Object > Set Origin > Origin to 3D Cursor.
Join the parts into one object: select them all, Ctrl+J.
Apply transforms: Ctrl+A > All Transforms. Rotation 0, scale 1, size as shown.
Facing: the kit keeps your model's rotation as built. If it faces backwards in the game, rotate it in Blender, apply, and export again.
Export: File > Export > FBX. Limit to Selected Objects, Object Types Mesh, Apply Transform on. For textures, set Path Mode to Copy and turn on Embed Textures (the button beside it), or copy the image files into Unity yourself.
2. Set up a Unity project
- Install Unity Hub, then Unity 2020.3 from the archive (Installs > Install Editor > Archive, or unity.com/releases/editor/archive). No extra modules are needed; if the Visual Studio download fails, untick it.
- New project with the 3D template (the built-in pipeline; not "3D (URP)").
- Make a folder
Assets/Editorand save this script in it asBuildBundles.cs:
using System.IO;
using UnityEditor;
using UnityEngine;
public static class BuildBundles
{
// Builds every asset marked with an AssetBundle name into Bundles/, for the Windows game.
[MenuItem("Assets/Build AssetBundles")]
public static void Build()
{
const string output = "Bundles";
Directory.CreateDirectory(output);
BuildPipeline.BuildAssetBundles(output, BuildAssetBundleOptions.ChunkBasedCompression,
BuildTarget.StandaloneWindows64);
EditorUtility.RevealInFinder(output);
}
// Marks the selected assets for a bundle named after the first one (lower case), for when the
// AssetBundle field at the bottom of the Inspector won't take typing.
[MenuItem("Assets/Put Selection In Bundle")]
public static void Mark()
{
if (Selection.objects.Length == 0) return;
string bundle = Selection.objects[0].name.ToLowerInvariant().Replace(' ', '-');
foreach (var o in Selection.objects)
AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(o)).assetBundleName = bundle;
Debug.Log($"Marked {Selection.objects.Length} asset(s) for bundle '{bundle}'");
}
}
3. Import and check the model
- Drag the FBX (and any textures) into the Project window.
- Select the FBX. In the Inspector:
- Model tab: Scale Factor 1, Convert Units on. Apply.
- Materials tab: Extract Materials... (and Extract Textures... if embedded) into a folder, so you can edit them. They should use the Standard shader.
- Drag the model into the scene beside a default cube (GameObject > 3D Object > Cube, which is 1 m) and check the size. Fix it in Blender, not with Unity's scale.
- Drag the model from the scene back into the Project window to make a prefab, and name it. This name is the
assetin your content pack ("asset": "Thomas"), and it must match exactly.
4. Build the bundle
- Select the prefab. At the bottom of the Inspector, set AssetBundle to a name (New..., e.g.
thomas). If the field won't take text, right-click the prefab > Put Selection In Bundle. - Assets > Build AssetBundles. The
Bundlesfolder opens. - Copy the file named after your bundle (
thomas, no extension) into your pack folder. The.manifestfiles and the file calledBundlesaren't needed.
5. Use it
BepInEx\plugins\ThomasPack\
thomas.content.json "model": { "bundle": "thomas", "asset": "Thomas" }
thomas
thomas-icon.png
Start the game and look for the model line in BepInEx\LogOutput.log:
Content: item 'thomas-figure': model 'Thomas' (0.12 x 0.17 x 0.35 m)
Then give item=Thomas the Tank Engine in the dev console, and place it.
An icon
Inventory icons are square PNGs; 256 px works well. One way in Blender: an orthographic camera looking down at a three-quarter angle, a Sun light, a transparent background (Render Properties > Film > Transparent), 256 x 256 output, then F12 and save as PNG. Point icon at it.
If it doesn't look right
| Symptom | Likely cause |
|---|---|
Log: no model 'X' in ...; keeping the template's look |
The bundle file isn't where bundle points, or asset doesn't match the prefab's name |
Log: 'X' has no mesh |
The prefab has no mesh renderer (an empty or a rig only) |
| Pink model | URP/HDRP project or shader; use the 3D (built-in) template and the Standard shader |
| Way too big or small | Size in Blender, apply scale, Scale Factor 1 in Unity |
| Floats or sinks | The origin isn't at the bottom centre |
| Only part of the model shows | It's several meshes; join them in Blender |
| Faces the wrong way | Rotate in Blender, apply, re-export |
| Bundle won't load at all | Built with a Unity version other than 2020.3, or not for Windows (StandaloneWindows64) |