manual:subwaysim:map_construction:importing_switches
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| manual:subwaysim:map_construction:importing_switches [2026/01/21 11:32] – dcs | manual:subwaysim:map_construction:importing_switches [2026/01/21 12:17] (current) – dcs | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Importing Switches ====== | ====== Importing Switches ====== | ||
| - | In this section, we explain how to **place and use imported | + | Imported |
| - | Imported | + | Most standard |
| - | Typical examples include: | + | However, more complex constructions (for example |
| - | | + | |
| - | | + | |
| - | | + | |
| - | Because these layouts can be very complex and highly individual, they are created **manually | + | In those cases, the switch is built in a 3D program (usually |
| + | |||
| + | This page covers: | ||
| + | * When imported switches are needed | ||
| + | * Using already included imported switches from the SDK | ||
| + | * The full pipeline for creating your own imported switch: | ||
| + | modelling → paths → export → import → animations → Blueprint → Railtool connection | ||
| ---- | ---- | ||
| - | ===== When Are Imported Switches | + | ===== 1) When Do You Need Imported Switches? ===== |
| - | The Railtool supports: | + | Use imported switches when: |
| - | * standard | + | * the Railtool does not support the geometry (e.g. **DKW**, **EKW**, **DW**, special crossings, double crossovers) |
| - | * simple crossovers | + | * your switch has a non-standard |
| - | * regular procedural track geometry | + | * you need an exact real-world design |
| + | * you need special frog/guard layouts or custom sleeper/ | ||
| - | However, some switch types are: | + | You do NOT need imported switches for: |
| - | * too complex | + | * normal crossings (they have no moving parts) |
| - | * too custom | + | * standard left/right turnouts supported by Railtool |
| - | * or too irregular | + | |
| - | to be generated procedurally. | + | Crossings (no moving parts) |
| - | + | ||
| - | In these cases, **imported switches** | + | |
| ---- | ---- | ||
| - | ===== Built-in Imported Switches ===== | + | ===== 2) Using Built-in Imported Switches |
| - | SubwaySim 2 already includes | + | The Modding SDK ships with a variety |
| - | They can be found inside the **SubwaySim2_Modding** plugin under: | + | You can find them here: |
| SubwaySim2_Modding / RailwaySystem / ImportedSwitches | SubwaySim2_Modding / RailwaySystem / ImportedSwitches | ||
| - | This folder | + | Inside this folder, you will see many switch assets. |
| Important: | Important: | ||
| - | * Always | + | * Only use the **BP_...** |
| - | * Only these Blueprint actors | + | * The Blueprints |
| + | * StaticMeshes / SkeletalMeshes alone are NOT enough. | ||
| {{: | {{: | ||
| Line 49: | Line 51: | ||
| ---- | ---- | ||
| - | ===== Placing an Imported Switch | + | ==== 2.1 Placing an Imported Switch |
| - | To place an imported switch | + | 1. Make sure you are in **Selection Mode** in the Unreal Editor |
| + | | ||
| - | | + | 2. Drag the desired |
| - | (not Railtool mode) | + | |
| - | * Navigate to: | + | 3. You can freely |
| - | SubwaySim2_Modding / RailwaySystem / ImportedSwitches | + | |
| - | + | ||
| - | * Drag the desired **BP_ImportedSwitch** Blueprint into the level | + | |
| - | + | ||
| - | After placing the switch: | + | |
| - | * it can be freely | + | |
| - | * it can be rotated as needed | + | |
| - | * positioning is done manually | + | |
| - | Take your time to align the switch correctly with your intended | + | 4. Align it to your intended layout. |
| + | (This is manual placement, so take your time.) | ||
| {{: | {{: | ||
| Line 72: | Line 67: | ||
| ---- | ---- | ||
| - | ===== Connecting | + | ==== 2.2 Connecting |
| - | Once the switch is placed: | + | Once the switch is placed, it needs to be connected to the Railtool track network: |
| - | * switch | + | * Switch |
| → [[manual: | → [[manual: | ||
| - | * use the **Control Points** of the imported switch | + | * Use the **Control Points** of the imported switch |
| - | * connect | + | * Connect your Railtool track splines to those Control Points (same idea as normal |
| After this step: | After this step: | ||
| - | * the imported switch behaves like any other Railtool-connected | + | * the imported switch behaves like a normal |
| - | * AI routing, signaling, and dispatching | + | * AI routing |
| {{: | {{: | ||
| Line 90: | Line 85: | ||
| ---- | ---- | ||
| - | ====== Creating Your Own Imported Switches | + | ===== 3) Creating Your Own Imported Switches ===== |
| If none of the provided switches fit your needs, you can create your own imported switch. | If none of the provided switches fit your needs, you can create your own imported switch. | ||
| Line 98: | Line 93: | ||
| * special crossover layouts | * special crossover layouts | ||
| * prototype or fictional designs | * prototype or fictional designs | ||
| + | * real-world designs that differ from the base assets | ||
| - | Creating a custom imported switch involves: | + | The full workflow looks like this: |
| - | * modeling the switch in a 3D tool (e.g. Blender) | + | |
| - | * preparing meshes and pivots correctly | + | |
| - | * importing the assets into the SDK | + | |
| - | * creating the required Blueprint setup | + | |
| - | This process will be explained in the next section. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ====== Importing Switches ====== | ||
| - | |||
| - | Imported switches are used when the Railtool cannot generate a special switch type reliably. | ||
| - | |||
| - | Most standard switches can be created directly with the Railtool. | ||
| - | However, more complex constructions (for example **double crossovers / DKW**, **EKW**, **DW**, or special custom geometry) vary a lot between networks and often require manual modelling. | ||
| - | |||
| - | In those cases, the switch is built in a 3D program (usually **Blender**), | ||
| - | |||
| - | This page covers: | ||
| - | * when imported switches are needed | ||
| - | * using already included imported switches from the SDK | ||
| - | * the full pipeline for creating your own imported switch: | ||
| - | modelling → paths → export → import → animations → Blueprint → Railtool connection | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== 1) When Do You Need Imported Switches? ===== | ||
| - | |||
| - | Use imported switches when: | ||
| - | * the Railtool does not support the geometry (e.g. DKW, EKW, DW, special crossovers) | ||
| - | * your switch has a non-standard shape/ | ||
| - | * you need an exact real-world design | ||
| - | * you need special frog/guard layouts or unique sleeper/ | ||
| - | |||
| - | You do NOT need imported switches for: | ||
| - | * normal crossings (they have no moving parts) | ||
| - | * standard left/right switches supported by Railtool | ||
| - | |||
| - | Crossings (no moving parts) are generated by Railtool and do not need custom building. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== 2) Using SDK Imported Switches ===== | ||
| - | |||
| - | The Modding SDK already ships with a variety of imported switches used by the base game. | ||
| - | |||
| - | You can find them here: | ||
| - | |||
| - | SubwaySim2_Modding / RailwaySystem / ImportedSwitches | ||
| - | |||
| - | Inside this folder, you will see many switch assets. | ||
| - | |||
| - | Important: | ||
| - | * Only use the **BP_...** Blueprints for placement in levels. | ||
| - | * The Blueprints contain the configuration needed for Railtool and animations. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== 2.1 Placing an Imported Switch in a Level ==== | ||
| - | |||
| - | 1. Make sure you are in **Selection Mode** in the Unreal Editor | ||
| - | | ||
| - | |||
| - | 2. Drag a **BP_...** imported switch into your level. | ||
| - | |||
| - | 3. You can freely move and rotate it like any normal actor. | ||
| - | |||
| - | 4. Once positioned: | ||
| - | go to the Railtool track workflow: | ||
| - | | ||
| - | |||
| - | 5. Connect the switch using ControlPoints exactly like a normal Railtool switch. | ||
| - | |||
| - | The imported switch behaves like a normal switch after it is connected. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ===== 3) Building Your Own Imported Switch ===== | ||
| - | |||
| - | This section explains the full workflow for building your own switch. | ||
| - | |||
| - | Overview: | ||
| 1) Planning & naming | 1) Planning & naming | ||
| 2) Modelling rails + frogs + guards | 2) Modelling rails + frogs + guards | ||
| - | 3) Creating drivable paths (very important) | + | 3) Creating drivable paths (critical!) |
| 4) Sleepers, clamps, gravel | 4) Sleepers, clamps, gravel | ||
| 5) UVs & materials | 5) UVs & materials | ||
| Line 195: | Line 110: | ||
| 12) Test in level + connect with Railtool | 12) Test in level + connect with Railtool | ||
| - | We follow | + | This is the same concept |
| ---- | ---- | ||
| Line 201: | Line 116: | ||
| ===== 4) Terminology (German + English) ===== | ===== 4) Terminology (German + English) ===== | ||
| - | This is a quick translation list used in references and modelling: | + | Quick translation list used in references and modelling: |
| ^ English ^ German ^ | ^ English ^ German ^ | ||
| Line 222: | Line 137: | ||
| We generally build everything in the **60E1 rail profile**. | We generally build everything in the **60E1 rail profile**. | ||
| - | (That means your rail meshes, trims, and dimensions | + | |
| + | That means: | ||
| + | * your rail meshes match the prepared | ||
| + | * your dimensions, trims, and clearances align with existing track content | ||
| ---- | ---- | ||
| Line 239: | Line 157: | ||
| * visually (looks correct) | * visually (looks correct) | ||
| * physically (wheels can pass) | * physically (wheels can pass) | ||
| - | * for flangeway clearance at the frog and guards | + | * for flangeway clearance at frog and guards |
| ---- | ---- | ||
| Line 250: | Line 168: | ||
| * rail geometry intersects | * rail geometry intersects | ||
| * flangeway must remain correct | * flangeway must remain correct | ||
| - | * wings and guard guidance must prevent derailment | + | * wings and guard guidance must prevent derailment |
| * some switch types have double or triple frog variants | * some switch types have double or triple frog variants | ||
| Line 264: | Line 182: | ||
| * Some switches can also use manual levers instead of motors | * Some switches can also use manual levers instead of motors | ||
| - | If you simulate the blade movement: | + | If you animate |
| - | * include this offset in the animation | + | * include this offset in timing/curves |
| * make sure throw bar geometry doesn’t clip | * make sure throw bar geometry doesn’t clip | ||
| Line 278: | Line 196: | ||
| When a guard rail does not fit cleanly: | When a guard rail does not fit cleanly: | ||
| - | * add a small guide rail piece (look at existing | + | * add a small guide rail piece |
| + | * look at previously made switches for style reference | ||
| ---- | ---- | ||
| Line 295: | Line 214: | ||
| ---- | ---- | ||
| - | ===== 6) Switch Types (Crossing, | + | ===== 6) Switch Types (Crossing, Switch, DW, EKW, DKW) ===== |
| ==== 6.1 Rail Crossing ==== | ==== 6.1 Rail Crossing ==== | ||
| Line 344: | Line 263: | ||
| Inside blades: | Inside blades: | ||
| - | * easier | + | * simpler |
| * often tighter constraints | * often tighter constraints | ||
| Line 360: | Line 279: | ||
| DW-60E1-100-6: | DW-60E1-100-6: | ||
| - | If your toolchain doesn’t like “:”: | + | Some softwares don’t like “: |
| DW-60E1-100-1_6LR | DW-60E1-100-1_6LR | ||
| Line 373: | Line 292: | ||
| ===== 8) Modelling in Blender ===== | ===== 8) Modelling in Blender ===== | ||
| - | This section describes the modelling workflow used for complex switches. | + | We assume you are working inside a prepared file like: |
| - | We assume you are working inside a prepared file like: | ||
| 60E1-Rail.blend | 60E1-Rail.blend | ||
| - | which already contains prepared meshes. | ||
| - | Follow | + | This file already contains prepared meshes and references. |
| + | Follow | ||
| * create a new Collection for your switch | * create a new Collection for your switch | ||
| * keep rails, sleepers, clamps, paths separated | * keep rails, sleepers, clamps, paths separated | ||
| Line 385: | Line 303: | ||
| ---- | ---- | ||
| - | ==== 8.1 Curves and Paths (The Foundation) ==== | + | ==== 8.1 Curves and Paths (Foundation) ==== |
| - | We start by defining the geometry using curves. | + | First we set up our angle, example **1:6**: |
| - | Example: angle 1:6 | + | |
| + | 2) Extrude it 6 m along X-Axis | ||
| + | 3) Extrude it 1 m along Y-Axis | ||
| + | 4) Fill the 2 lonely verts → you now have a triangle | ||
| - | 1) Place a vertex at world origin. | + | The edge that is ~6.08 m long will be called **“c”**. |
| - | 2) Extrude | + | |
| - | 3) Extrude 1 m on Y | + | |
| - | 4) Fill the triangle | + | |
| - | The triangle | + | Next we make a 100° circle and align it so that the bottom vertex sits in the origin. |
| + | Recommended: | ||
| + | * a vertex count divisible by 4 | ||
| + | * individual | ||
| + | Example: 1024 verts. | ||
| - | Next: | + | Delete unnecessary verts (keep only the range you need). |
| - | * Create a 100° circle | + | |
| - | * Align the bottom vertex of the circle to the world origin | + | |
| - | * Use a high vertex count divisible by 4 | + | |
| - | (example: 1024 verts) with ~0.6 m edge length | + | |
| - | Then: | + | Now: |
| - | * delete unnecessary verts | + | |
| * extrude the triangle edge “c” | * extrude the triangle edge “c” | ||
| - | * move the circle along X until it is tangent to “c” | + | * move the circle along X until the circle |
| - | How to align precisely: | + | How to align precisely |
| - | * use snapping (active element) | + | * enable |
| - | * pick a vert, select all, edge snap to “c” | + | * select |
| - | * if still crossing, | + | * edge snap it to “c” |
| + | * if still crossing | ||
| + | This is faster and more precise than eyeballing. | ||
| - | Now you have the left curve. | + | Now you have the left curve more or less done. |
| - | For the right curve: | + | You still need a right curve: |
| - | * duplicate the first | + | * duplicate the first curve |
| - | * move so its start sits at the origin | + | * move it so that the very start sits in world origin |
| - | * rotate 180° or mirror along X | + | * rotate |
| - | Add a straight | + | Now add a straight |
| - | + | At this point your switch | |
| - | You now have the main curve layout. | + | |
| ---- | ---- | ||
| - | ==== 8.2 Creating Drivable Paths (Export-Ready) ==== | + | ==== 8.2 Creating Drivable Paths (Export-Ready |
| Paths define where trains can drive. | Paths define where trains can drive. | ||
| - | They must match exactly wherever paths intersect. | + | They MUST be correct, otherwise routing will fail. |
| Workflow: | Workflow: | ||
| - | * duplicate | + | * duplicate |
| * convert to meshes | * convert to meshes | ||
| - | * shorten ends slightly | + | * cut them short a bit |
| - | * ensure | + | * make sure they all start at the same point (if your layout requires it) |
| - | * extrude edges 0.1 m upwards for better visibility | + | * extrude |
| + | |||
| + | Important rule: | ||
| + | * Wherever paths intersect, they must share IDENTICAL vertex positions. | ||
| + | * The paths need the exact same verts wherever they intersect. | ||
| Naming recommendation: | Naming recommendation: | ||
| Line 443: | Line 365: | ||
| * PathRight | * PathRight | ||
| * PathStraight | * PathStraight | ||
| - | * (and any additional | + | (and more if needed) |
| - | Critical rule: | + | These paths will later be referenced inside the Switch Blueprint |
| - | * Wherever | + | |
| - | * If the vertices don’t match, routing can break or trains can “jump”. | + | |
| - | + | ||
| - | These path meshes are exported and later referenced inside the Switch Blueprint | + | |
| ---- | ---- | ||
| Line 456: | Line 374: | ||
| Rails: | Rails: | ||
| - | * Take 60E1Double mesh | + | * take the 60E1Double mesh |
| * duplicate it | * duplicate it | ||
| - | * add Array modifier (enable Merge) | + | * add an Array modifier (enable |
| - | * add Curve modifier | + | * add a Curve modifier |
| - | * repeat for all rail segments | + | * repeat for all required |
| - | Flangeway: | + | Flangeway |
| - | * do the same with the “Abstand” mesh (wheel | + | * do the same with the “Abstand” mesh (shows the wheel clearance / flangeway) |
| - | Now you should | + | After that you should |
| ---- | ---- | ||
| Line 471: | Line 389: | ||
| ==== 8.4 Sleepers (Array on Curves) ==== | ==== 8.4 Sleepers (Array on Curves) ==== | ||
| - | Take an existing sleeper mesh: | + | Next, sleepers: |
| - | * usually WoodenSleeper2.6 | + | * take an existing sleeper mesh (often WoodenSleeper2.6) |
| + | * add a constant offset array of 0.6 m (if not already existing) | ||
| + | * add a curve modifier and put it onto the curves | ||
| - | Add: | + | After lengthening |
| - | * constant offset array: 0.6 m (distance) | + | |
| - | * curve modifier on each curve | + | |
| - | + | ||
| - | After merging / lengthening | + | |
| ---- | ---- | ||
| - | ==== 8.5 Frogs: Cut, Stitch, Model ===== | + | ==== 8.5 Frogs: Cut-Out + Stitching the Heart ==== |
| - | At first it will look wrong because rails overlap. | + | At first the frog area will look wrong because rails intersect. |
| - | Step 1: Cut out the intersection areas | + | Step 1: Cut out the parts where the flangeway and rail intersect. |
| - | * remove mesh parts where flangeway and rail intersect | + | |
| - | Step 2: Model the frog geometry | + | Step 2: Model the frog: |
| - | * extend | + | * lengthen |
| - | * use references | + | * use references |
| - | * add wings | + | * don’t forget the wings |
| - | * ensure | + | * keep flangeway |
| - | Frogs can look weird in Blender: | + | Frogs will always |
| - | * that’s normal | + | Focus on clearance |
| - | * focus on real clearances | + | |
| ---- | ---- | ||
| - | ==== 8.6 Blades + Stock Rails ===== | + | ==== 8.6 Blades + Stock Rails ==== |
| Blades: | Blades: | ||
| - | * start from BladeRailDouble mesh | + | * take BladeRailDouble mesh |
| - | * curve it along blade curves | + | * put it on the curves |
| - | * rotate if needed | + | * rotate if needed |
| - | * duplicate | + | * duplicate |
| - | * move segments | + | * move the thin end to where the blade ends |
| - | * delete the “wrong” blade side faces | + | * delete |
| - | Then: | + | Now: |
| - | * bridge edges between segments | + | * select each segment and bridge edges (linear) |
| - | * add enough | + | * add as many cuts as needed |
| - | * sharpen thin end edges | + | * delete unneeded faces |
| - | * apply curve modifier | + | * sharpen |
| + | * apply the curve modifier | ||
| - | Stock rails: | + | Stock rail: |
| * duplicate StockRailDouble | * duplicate StockRailDouble | ||
| - | * curve it along the corresponding rail | + | * add curve modifier |
| - | * repeat same for every blade area | + | * align it to the corresponding rail |
| + | Repeat | ||
| Goal: | Goal: | ||
| - | * the blade sits correctly against stock rail | + | * blade sits correctly against stock rail |
| - | * no gauge errors | + | * gauge stays correct |
| - | * no wheel clearance issues | + | * no clearance issues |
| ---- | ---- | ||
| - | ==== 8.7 Guards and Guides | + | ==== 8.7 Guards and Guides ==== |
| Guard rail: | Guard rail: | ||
| - | * duplicate GuardRailDouble | + | * duplicate GuardRailDouble |
| - | * curve it along needed areas | + | * put it on the required curve segments |
| - | * trim if needed | + | * trim it if needed |
| - | If guard does not fit: | + | If a guard does not fit: |
| - | * add a guide rail piece (small metal guide) | + | * add a small metal piece called |
| - | * use existing | + | * look at previously made switches |
| ---- | ---- | ||
| - | ==== 8.8 Hollow Sleepers + Throw Bar ===== | + | ==== 8.8 Hollow Sleepers + Throw Bar ==== |
| - | Hollow | + | Hollow |
| - | * use existing | + | * take HollowSleeper mesh |
| - | * place at blade ends between two sleepers | + | * move it to the end of your blades in between two sleepers |
| - | * ensure | + | * make sure the steel part doesn’t intersect |
| Throw bar: | Throw bar: | ||
| - | * place ThrowBar | + | * take ThrowBar |
| - | * align to blade ends | + | * move them to the same point and align them with the blade ends |
| Make sure: | Make sure: | ||
| - | * throw bar doesn’t clip | + | |
| - | * blades have enough clearance for motion | + | |
| ---- | ---- | ||
| - | ==== 8.9 Clamps (Tedious but Required) | + | ==== 8.9 Clamps (Tedious but Required) ==== |
| - | Clamps are placed individually because: | + | Clamps are the most tedious part. |
| - | * arrays do not allow unique pivots for rotation | + | |
| - | * clamps must match rail curvature and sleeper placement | + | |
| - | Workflow: | + | Helper setup: |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | Placement workflow: |
| - | | + | |
| - | | + | |
| - | | + | |
| - | 8) special cases: if clamps | + | |
| + | | ||
| + | 6) rotate | ||
| + | |||
| + | Why not instances/ | ||
| + | * you may need to adjust | ||
| + | * pivots must rotate properly per clamp | ||
| Blade clamps: | Blade clamps: | ||
| - | * use ClampK_BladeBUILD on stock rail near blades | + | * use ClampK_BladeBUILD on the corresponding |
| Guard clamps: | Guard clamps: | ||
| - | * use ClampK_GuardBUILD on guard rails | + | * use ClampK_GuardBUILD on the corresponding |
| - | Performance note: | + | Special clamps: |
| - | * clamps | + | * when clamps |
| - | * see Optimization section | + | |
| ---- | ---- | ||
| - | ==== 8.10 Optimization Choices | + | ==== 8.10 Clamp Optimization Choices ==== |
| + | |||
| + | Clamps are a lot of geometry. You have two approaches: | ||
| - | Correct way (more work, best performance): | + | Correct way (best performance, more work): |
| - | * separate clamps | + | * separate |
| - | * add sockets | + | * add sockets |
| - | * record | + | * write down single/ |
| - | * place clamps | + | * place clamps |
| - | * most efficient | + | This is easier |
| - | Lazy way (often | + | Lazy way (often |
| * export clamps as a separate StaticMesh | * export clamps as a separate StaticMesh | ||
| - | * add aggressive | + | * apply strong |
| - | For most mod projects: | + | Recommendation: |
| * start with the lazy way | * start with the lazy way | ||
| - | * optimize later if needed | + | * optimize later if performance becomes a problem |
| ---- | ---- | ||
| - | ==== 8.11 Gravel | + | ==== 8.11 Gravel ==== |
| - | Pick gravel mesh: | + | Take a gravel mesh (GravelOEBB or GravelSubway depending on usage) |
| - | * GravelOEBB or GravelSubway depending on context | + | and apply curve modifiers (often multiple curve passes). |
| Then: | Then: | ||
| - | * curve modifier on gravel (often multiple passes) | ||
| * apply modifiers | * apply modifiers | ||
| - | * merge parts to avoid overlaps / Z-fighting | + | * merge parts together (avoid overlaps / Z-fighting) |
| - | * ensure | + | * make sure ends connect |
| - | UV note: | + | UV important: |
| - | * gravel must match texel density of base gravel mesh | + | * gravel must match texel density of normal |
| - | * project from view (top-down) and apply same tx density | + | * project from view (top-down) and apply same texel density |
| ---- | ---- | ||
| Line 625: | Line 545: | ||
| ===== 9) UVs and Textures ===== | ===== 9) UVs and Textures ===== | ||
| - | We use a tileable trimsheet | + | UVs are quite simple because we use a tileable trimsheet: **RailTileSet**. |
| Workflow: | Workflow: | ||
| - | * select shiny metal parts → cube project → tx density 5.12 px/cm at 1k | + | * select shiny metal parts → cube project → texel density 5.12 px/cm on a 1k texture |
| - | * move those UVs to shiny section (upper part) | + | * move those UVs into the shiny section |
| * rust parts → second section | * rust parts → second section | ||
| - | * repeat for wood/ | + | * repeat for wood/ |
| - | Tip: | + | Consistency matters: |
| - | * keeping consistent | + | * same texel density |
| ---- | ---- | ||
| - | ===== 10) Rigging and Animating | + | ===== 10) Rigging and Animating ===== |
| - | Imported switches need blade animations. | + | Imported switches need blade movement. |
| We use an Armature. | We use an Armature. | ||
| Line 646: | Line 566: | ||
| ---- | ---- | ||
| - | ==== 10.1 Rigging | + | ==== 10.1 Rigging ==== |
| - | 1) Create root bone: | + | 1) Create |
| - | Name: Rail | + | |
| - | 2) Assign | + | 2) Assign |
| - | (rails, frogs, guards, sleepers, gravel, clamps | + | * rails (excluding blades) |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| - | Quick workflow: | + | Fast workflow: |
| - | * merge those meshes temporarily | + | * merge the static |
| * select all faces | * select all faces | ||
| - | * CTRL+G → assign to group "Rail" | + | * CTRL+G → assign to vertex |
| 3) For each blade: | 3) For each blade: | ||
| - | * create a bone at the thick end | + | * place your first bone at the start of the blade (thick end) |
| - | * move end to thin end | + | * move its end to the thin end |
| - | * subdivide twice → 4 bones per blade | + | * subdivide |
| - | * align bones to curved blade centerline | + | * align the bones to the curved blade centerline |
| + | * bones should sit in the middle of the blade | ||
| Naming convention: | Naming convention: | ||
| - | Blade(FromTo)_(L/R)(Index) | + | Blade(direction from → direction to)_(left/right blade)(bone index starting at thick end) |
| Examples: | Examples: | ||
| Line 674: | Line 600: | ||
| Throw bars: | Throw bars: | ||
| - | * vertex | + | * vertex |
| + | * include the final number | ||
| Skinning: | Skinning: | ||
| - | * parent blades to armature with automatic weights | + | * parent blades to the armature with Automatic Weights |
| - | * verify in pose mode that skinning is correct | + | * then verify |
| ---- | ---- | ||
| - | ==== 10.2 Animating | + | ==== 10.2 Animating ==== |
| - | A DW example | + | Example: |
| + | * BladeSwitch1 (SW1) | ||
| + | * BladeSwitch2 (SW2) | ||
| - | | + | Typical timing example: |
| - | * BladeSwitch2 | + | |
| + | * frame 20: opposite blade starts moving | ||
| + | * frame 80: one side returns to neutral | ||
| + | * frame 100: the other side reaches the final switched position | ||
| - | Workflow (example timing): | + | Example rotation |
| - | * frame 1: one blade side closed | + | |
| - | * frame 20: other side begins | + | |
| - | * frame 80: return to neutral for one side | + | |
| - | * frame 100: other side reaches switched end | + | |
| - | + | ||
| - | Example rotation: | + | |
| * R1: 1° | * R1: 1° | ||
| * R2: 0.5° | * R2: 0.5° | ||
| - | * (values depend on geometry, adjust for clearance) | ||
| Important: | Important: | ||
| - | * ensure flangeways pass without clipping | + | |
| - | * throw bar doesn’t | + | |
| - | * set graph curves to linear | + | * ensure |
| - | * export animations as NLA strips | + | |
| - | Make sure: | + | Graph Editor: |
| - | * both animations | + | * set curves to linear |
| - | * naming | + | |
| + | Output requirement: | ||
| + | * both animations | ||
| + | * naming | ||
| ---- | ---- | ||
| - | ===== 11) Exporting | + | ===== 11) Exporting |
| - | Export settings: | + | Export groups |
| - | * Use the same settings as vehicle exports for meshes | + | * SkeletalMesh FBX (armature + blades |
| - | * Use animation export settings for animations | + | * Animations FBX (or included |
| - | + | * StaticMeshes FBX (sleepers, gravel, clamps | |
| - | Export groups: | + | * Paths FBX (all paths can be in one FBX) |
| - | * SkeletalMesh FBX (with armature + blades) | + | |
| - | * Animations FBX (or together | + | |
| - | * StaticMeshes FBX (sleepers/clamps/gravel if separate) | + | |
| - | * Paths FBX (all path meshes | + | |
| - | + | ||
| - | For paths: | + | |
| - | * Turn off Combine Meshes on import later | + | |
| - | * Ensure path names are clean and unique | + | |
| Folder structure: | Folder structure: | ||
| - | * follow the SDK naming/ | + | * follow the SDK conventions |
| + | |||
| + | Paths requirement: | ||
| + | * names must be clean and unique (PathLeft, PathRight, etc.) | ||
| + | * paths must share vertices at intersections | ||
| ---- | ---- | ||
| - | ===== 12) Importing | + | ===== 12) Importing |
| Import categories: | Import categories: | ||
| - | ==== 12.1 SkeletalMesh | + | ---- |
| + | |||
| + | ==== 12.1 SkeletalMesh | ||
| - | Import the SkeletalMesh like a vehicle | + | Import the SkeletalMesh like a vehicle: |
| - | * place it into your ImportedSwitch | + | * place it into your plugin |
| - | * then import animations into an Animations subfolder | + | * import animations into an Animations subfolder |
| Verify: | Verify: | ||
| * skeleton is correct | * skeleton is correct | ||
| - | * animations play in animation | + | * animations play correctly on preview |
| ---- | ---- | ||
| - | ==== 12.2 StaticMeshes and Paths ===== | + | ==== 12.2 StaticMeshes and Paths ==== |
| StaticMeshes: | StaticMeshes: | ||
| Line 756: | Line 681: | ||
| Paths: | Paths: | ||
| * can be imported from one FBX | * can be imported from one FBX | ||
| - | * IMPORTANT: disable Combine Meshes | + | * IMPORTANT: disable |
| - | * verify | + | * each path must become |
| - | | + | * verify |
| ---- | ---- | ||
| Line 767: | Line 692: | ||
| Rules: | Rules: | ||
| - | * place it near other imported switch ABPs | + | * place it with other imported switch ABPs (same structure) |
| + | * Parent Class must be: **Lua Anim Instance** | ||
| * follow naming conventions | * follow naming conventions | ||
| - | * Parent Class must be: Lua Anim Instance | ||
| - | Workflow: | + | Workflow |
| - | * copy an existing imported switch ABP | + | * copy/ |
| - | * create variables for SW1 / SW2 (or your needed | + | * make SW1 / SW2 (or your blade groups) |
| * assign your Anim Sequences to those variables | * assign your Anim Sequences to those variables | ||
| - | * update Layered Blend per Bone with your bone names | + | * update |
| - | (triple-check typos and correct order) | + | (triple check for typos and correct order) |
| If blades don’t move: | If blades don’t move: | ||
| - | * bone names wrong | + | * wrong bone names |
| * wrong skeleton | * wrong skeleton | ||
| * animations not assigned | * animations not assigned | ||
| - | * not exported | + | * NLA strips |
| ---- | ---- | ||
| Line 788: | Line 713: | ||
| ===== 14) Switch Blueprint Setup (RTImportedSwitchActor) ===== | ===== 14) Switch Blueprint Setup (RTImportedSwitchActor) ===== | ||
| - | In this step we create the Blueprint | + | This Blueprint |
| - | The Blueprint | + | It combines: |
| * SkeletalMesh component | * SkeletalMesh component | ||
| - | * StaticMeshes | + | * StaticMesh components |
| * Animation Blueprint | * Animation Blueprint | ||
| * RailTool2 SwitchConfigurations (critical) | * RailTool2 SwitchConfigurations (critical) | ||
| Line 798: | Line 723: | ||
| ---- | ---- | ||
| - | ==== 14.1 Create the Blueprint | + | ==== 14.1 Create the Blueprint ==== |
| 1) Create Blueprint Class | 1) Create Blueprint Class | ||
| - | 2) Parent Class: | + | 2) Parent Class: |
| - | RTImportedSwitchActor | + | 3) Name it coherently, e.g.: |
| - | 3) Name it coherently: | + | |
| | | ||
| ---- | ---- | ||
| - | ==== 14.2 Assign Meshes and ABP ===== | + | ==== 14.2 Assign Meshes and ABP ==== |
| - | SkeletalMesh component: | + | In the Blueprint: |
| * assign your SkeletalMesh | * assign your SkeletalMesh | ||
| - | * assign | + | * set Animation Mode to use your Animation Blueprint |
| + | * assign your ABP | ||
| Optional: | Optional: | ||
| - | * add StaticMesh components for clamps/ | + | * add StaticMesh components for clamps/ |
| ---- | ---- | ||
| - | ==== 14.3 RailTool2 SwitchConfigurations ===== | + | ==== 14.3 RailTool2 SwitchConfigurations ==== |
| + | |||
| + | Open the Blueprint Details and locate: | ||
| - | Open Details: | ||
| RailTool2 → SwitchConfigurations | RailTool2 → SwitchConfigurations | ||
| - | Add entries for each valid route through the switch. | + | Each SwitchConfiguration defines one valid route through the switch. |
| Each configuration links: | Each configuration links: | ||
| - | * a Path mesh | + | * a Path mesh (PathLeft / PathRight / PathStraight / ...) |
| - | * blade state values | + | * animation |
| - | State values are usually discrete (0 / 1 / 2) depending on ABP logic. | + | Example |
| - | + | * Route “Left”: | |
| - | Example | + | |
| - | * Left route: | + | |
| Path = PathLeft | Path = PathLeft | ||
| - | SW1 = 1 | + | SW1 = 1 (end) |
| SW2 = 0 | SW2 = 0 | ||
| - | * Right route: | + | * Route “Right”: |
| Path = PathRight | Path = PathRight | ||
| SW1 = 0 | SW1 = 0 | ||
| SW2 = 2 | SW2 = 2 | ||
| - | Use configuration index cycling for debugging: | + | Notes: |
| - | * 0 first config, 1 second, etc. | + | * You can cycle through SwitchConfigurations (index |
| - | + | | |
| - | If you see no changes: | + | |
| - | * ABP variables wrong | + | |
| - | * animations not assigned | + | |
| - | * bone names mismatch | + | |
| ---- | ---- | ||
| - | ==== 14.4 Optional Construction Script Toggles | + | ==== 14.4 Optional Construction Script Toggles ==== |
| - | Common | + | Some imported switches need optional |
| - | * Gravel visibility | + | * hide gravel |
| - | * sleeper variant selection | + | * swap sleepers |
| - | Implement by: | + | Typical setup: |
| * exposed variables | * exposed variables | ||
| - | * Set Visibility in Construction Script | + | * Set Visibility |
| ---- | ---- | ||
| - | ==== 14.5 Switch Motors | + | ==== 14.5 Switch Motors ==== |
| - | Add switch motor meshes | + | If your switch |
| - | + | * determine motor placement | |
| - | Workflow: | + | * copy relative location/ |
| - | * determine motor transform | + | * optionally use an enum for motor positions |
| - | * copy relative location/ | + | |
| - | * optionally use an enum (MotorPosition) | + | |
| ---- | ---- | ||
| - | ===== 15) Testing the Switch in a Level ===== | + | ===== 15) Testing the Switch in the Level ===== |
| - | 1) Ensure | + | 1) Make sure you are in **Selection Mode** |
| - | 2) Drag the BP_... imported switch into the level | + | 2) Drag your BP_... imported switch into the level |
| 3) Move/rotate it into position | 3) Move/rotate it into position | ||
| - | 4) Connect with Railtool ControlPoints: | + | 4) Connect |
| - | | + | → [[manual: |
| - | Important: | + | Validate: |
| - | * after connection, validate routes by driving AI/player across | + | * drive each route (player and/or AI) over all paths |
| * check for clipping at frogs and blade ends | * check for clipping at frogs and blade ends | ||
| * verify blade animations match selected route | * verify blade animations match selected route | ||
| + | * verify signals / route setting behave as expected on connected tracks | ||
| ---- | ---- | ||
| Line 892: | Line 811: | ||
| ===== 16) Extra Info: Calculating the Angle ===== | ===== 16) Extra Info: Calculating the Angle ===== | ||
| - | Example 1:6 | + | Example 1:6: |
| 1/6 = 0.1666... | 1/6 = 0.1666... | ||
| Line 900: | Line 819: | ||
| 9.4623° | 9.4623° | ||
| - | You can keep a list of known angles to avoid repeating the math. | + | It can be useful to maintain |
| ---- | ---- | ||
| Line 907: | Line 826: | ||
| * Paths do not share identical vertices at intersections | * Paths do not share identical vertices at intersections | ||
| - | * Wrong pivot/ | + | * Wrong pivot/ |
| * ABP bone names mismatch → blades never move | * ABP bone names mismatch → blades never move | ||
| * SwitchConfigurations missing/ | * SwitchConfigurations missing/ | ||
| - | * Frog flangeway clearance wrong → derail-looking behavior | + | * Frog flangeway clearance wrong → clipping / derail-looking behavior |
| - | * Clamp geo too heavy → performance issues (use LODs or instancing | + | * Clamp geometry |
| - | * Gravel overlaps | + | * Gravel overlaps |
| ---- | ---- | ||
| Line 918: | Line 837: | ||
| ===== Next Step ===== | ===== Next Step ===== | ||
| - | After your imported switch | + | Once your imported switch |
| - | * place more of them as needed | + | |
| - | * connect them with Railtool | + | |
| - | * continue | + | |
| - | Back to: | ||
| * [[manual: | * [[manual: | ||
| {{page> | {{page> | ||
manual/subwaysim/map_construction/importing_switches.txt · Last modified: by dcs
