Skip to content
You're reading the docs for Railroader 0.6 (the MoW Update), currently available on the Experimental branch.

Blender Workflow

Railroader loads models as Unity prefabs, so anything Unity can import will work. Blender is what we use, and this page covers the two parts of that trip that most often go wrong: export settings, and getting doors, hatches, and brake rigging out of one model as separate animation clips.

If you are new to building a model for the game, start with Creating a Freight Car (Basics) and come back here when you need animation.

  • One Blender unit is one meter, so model at real-world size.
  • Put the origin where the game expects it. For a car, the origin belongs at the center of the car at rail head height, with the car’s length running along Unity’s Z axis — which, with the export settings below, is Blender’s Y axis. The game lays track with the top of the rail at zero and positions cars from that plane, so an origin at the car’s floor or at ground level puts the car in the wrong place on the track.
  • Apply transforms. Object > Apply > All Transforms on your finished meshes, so the exported objects start clean.
  • Name your objects deliberately. Object names become GameObject names in Unity, and definitions address them by path: a TransformReference is a list of those names. Name the doors Left Doors, not Cube.003.

Use File > Export > FBX (.fbx). The sections below follow the export panel top to bottom; anything not listed is at its default.

Path Mode stays at Auto, with the Embed Textures button beside it off — textures belong in the pack as their own files.

Once you’ve made the export settings adjustments below, save a preset with the + button under Operator Presets at the top of the dialog. Then you can call it back up next time using the preset.

SettingValue
Limit to Selected ObjectsOn, once the file holds more than the model
Object TypesEmpty, Armature, Mesh
SettingValue
Forward / UpY Forward / Z Up — not Blender’s defaults, which import facing backwards
Apply ScalingsFBX Units Scale — writes the file in meters, so the model lands at scale (1, 1, 1). Blender’s default All Local gives (100, 100, 100) against a 0.01 Scale Factor, which is equivalent but noisier
Apply TransformOff — Blender flags it experimental, and next to the two settings above it has nothing left to bake

Those values match Blender’s own axes, so the exporter rotates nothing on the way out. It tags the file as Z-up instead, and Unity converts on import, mapping Blender +Y to Unity +Z and +Z to +Y. Leave Unity’s Bake Axis Conversion import option off, or the model is corrected twice.

SettingValue
SmoothingNormals Only — ships the normals your Blender shading produces
Apply ModifiersOn
Triangulate FacesOn
Tangent SpaceOff
SettingValue
Add Leaf BonesOff, to avoid extra bones in Unity

The panel is collapsed and disabled by default; the checkbox in its own header turns it on.

SettingValue
Animation (panel header)On
Key All BonesOn — keys every bone on every sampled frame
NLA StripsOn — each NLA strip becomes its own clip
All ActionsOff — defaults to on, which imports into Unity as a lot of animation clips you don’t want
Simplify0.1 — trims redundant keys without visibly rounding motion. The default of 1.0 drops enough that it shows on linear travel like a sliding door; drop to 0 if a mechanical movement still wobbles off its path

Blender’s unit of animation is the action; Unity’s is the AnimationClip. Definitions name whole clips, so independent animations (two doors that open, say) need two clips.

How many clips you get is determined in Blender, before export. Unity imports whatever the file holds. To control what clips get imported, you will create NLA strips in Blender using the NLA editor (Non-Linear Animation):

  1. Animate one movement (a single door) and in the Action Editor give the action a real name (Door Front Left).
  2. Click Push Down in the Action Editor header. The action moves into an NLA track as a strip.
  3. Repeat for each movement, and make sure no strip or track is left muted, since muted ones are skipped on export.
  4. Check each strip’s name in the NLA editor sidebar (N > Strip tab). The strip name is what the clip arrives under in Unity, so make it readable.

Each strip’s frame range becomes that clip’s length. Strips may overlap or sit anywhere on the timeline; the game plays each clip on its own, so their arrangement doesn’t carry over.

The export side of this is the Animation panel — the panel itself on, NLA Strips on, All Actions off.

Select the imported FBX and open the Inspector.

Animation Type should be Generic, Unity’s default for non-humanoid models. Railroader plays clips through an Animator, which cannot use Legacy clips.

Each strip appears as a clip. Rename them here: the names that come across from Blender are rarely what you want (Door LFAction), and renaming is safe — the clip stays bound to the animation underneath.

Set Loop Time for anything that runs continuously, and leave it off for a door, which is driven to a position rather than played through.

Definitions never name a clip asset directly. They name an entry in the model prefab’s AnimationMap, which resolves the name to a clip at load.

Add the AnimationMap to the model root inside your prefab, the object Unity created from the FBX. It has to share a GameObject with the Animator, since that is where Railroader looks for one, and clip curves are addressed relative to it. Then add one entry per clip: a name of your choosing, plus the clip.

{
"kind": "ToggleAnimation",
"animation": { "clipName": "Door Front Left" },
"targetColliderObject": { "path": ["boxcar01", "Left Doors"] },
"key": "door.l",
"title": "Door"
}

The model is on its side, or facing backwards

Section titled “The model is on its side, or facing backwards”

Lying on its back means Unity did not convert a Z-up file, usually because Bake Axis Conversion is on. Facing backwards, or arriving with a -89.98 rotation, means the export used Blender’s default -Z Forward / Y Up. Fix either by re-exporting, not by adding a compensating rotation in the prefab — that just moves the problem into every clip and collider downstream.

NLA Strips was off, or the actions were never pushed down into tracks. With no strips to export, everything animating lands in one clip covering the scene frame range.

Names like Cube|CubeAction.001 mean All Actions is on. Turn it off.

Couldn't find animation named Door Front Left in my-boxcar

The AnimationMap has no entry by that name, or its clip slot is empty. Renaming an action or strip in Blender is the usual cause: the clip comes back in under a new name, the map entry loses its reference and empties, and the definition keeps asking for the old name.

Either the AnimationMap (and so the Animator) is on the wrong GameObject, or the curves are addressing a hierarchy that no longer matches. Renaming or reparenting objects in Unity after import breaks those paths; rename in Blender and re-export instead.