WiseTrains3: HL2 Synchronized Trains

From Valve Developer Community
Jump to: navigation, search

This tutorial was originally created by wisemx.

Ported from SDKnuts.net to VDC by: Pinsplash (talk) 01:27, 18 June 2018 (UTC)


In this one I’m only going to cover the aspects needed for synchronized trains in HL2 which were not mentioned in parts 1 or 2. I’ve also included a CS:S version in the download below. The CS:S version doesn’t include Alyx, naturally, or the moving ropes. The moving ropes are somewhat of a problem in CS:S, however there is a method you can use to overcome it. I haven’t created a tutorial for that but the CS:S drawbridge tutorial I created uses a method to overcome this problem. The other ropes in this project work in either HL2/HL2DM or CS:S. One more note about ropes in any Source game: A lot of people E-Mail me and ask why their ropes don’t hold anything. Ropes are illusionary, they are not solid and do not constrain anything, they are for appearance only.


The first consideration for HL2 trains that are synchronized, move together, is to space them properly, or as you learned in the previous 2 train tutorials we need to space the starting path_tracks properly, as the trains will spawn on the path_track they are assigned to.

Notice how the 4 trains in this tutorial are spaced, and the 4 path_tracks that are assigned to each of them. Even more important is the way these trains are controlled, start, change speed and stop, together.
The method I’ve used to lock the player in the first train is very important. As you can see in the 3D and 2D Top view ports, below, the player spawns in an invisible set of brushes. These are all func_brush textured entirely with tools/toolsnodraw. When the 4 trains first start the player spawns in these invisible brushes, which are parented to train 1. When the trains stop the player is released. This method won’t work very well in a multiplayer game, unless you use a series of triggers and get the timing right, so the player can be locked in the train. I’m still trying to come up with a better method of locking the player in trains like these. The only reason the player even needs to be locked in is the angle of climb and descent used in this tutorial, which will no doubt be the case if you create a roller coaster for HL2. (Porter's note: Personally I'd recommend point_viewcontrol. Also, each brush in the image is its own entity. They should have been tied as one, so that it's less work to change the settings on it/them, and to reduce the entity count.)

Here are the actions taken when the map spawns:

  1. Player spawns in train 1 and is enclosed in an invisible set of func_brush.
  2. logic_auto starts each of the 4 trains forward.
  3. As the trains get to certain parts of the track I’m using SetSpeedReal to gradually speed the trains up, as one, and then slow them back down before stopping.
  4. When the trains get to the incline I’m using a path_track to play clicking sounds, from an ambient_generic. (For the effect of a roller coaster climbing) The sound I used is ambient/machines/keyboard4_clicks.wav.
  5. When the trains complete their journey one of the last path_tracks will slow them down, stop them and release the player.
  6. All 4 trains share the same exact settings, except for their name and the name of their First Stop Target.

For our func_tracktrains:

  • Name: Train01, Train02, Train03 and Train04
  • Disable Receiving Shadows: Yes
  • Disable Shadows: Yes (To save on system resources)
  • First Stop Target: Track2, Track1, Track0 and Track17
  • Maximum Speed: 260
  • Initial Speed: 0
  • Change Velocity: Instantaneously
  • Change Angles: Near path_tracks
  • Distance Between the Wheels: 50
  • Height above Track: 20
  • Bank angle on turns: -10 (Roller Coaster effect)
  • Damage on Crush: 0
  • Move Sound: ambient/machines/train_wheels_loop1.wav (Train01 only)
  • Start Sound: plats/train_use1.wav (Train01 only)
  • Stop Sound: plats/ttrain_brake1.wav (Train01 only)
  • Flags: No User Control, HL1 Train, Is unblockable by Player

For out func_brushs:

  • Name: PlayerLock (6 func_brush all with the same name.)
  • Parent: Train01 (They will move with the train.)
  • Disable Receiving Shadows: Yes
  • Start Disabled: No
  • Disable Shadows: Yes
  • Solidity: Toggle
  • Solid BSP: No
  • Flags: Ignore Player USE

There’s a lot more you can do with this effect. I’ve included much more in the project file than is mentioned in this tutorial. I’m hoping I’ve included enough to get you up and running. Please forgive the track I made for this one, to create an actual coaster set of rails would have taken a lot of time, but I’m sure you’re going to create an awesome set of rails anyway.

See Also