WiseElevators: HL2 Elevators
This tutorial was originally created by wisemx. It was originally posted on SDKnuts.net.
Introduction
Illustrated in this project:
- A simple 4 floor Elevator.
- More advanced version of the same. Both vmf files are included below.
- Advanced effect uses env_sprite,func_brush, func_button, func_tracktrain, logic_relay, path_track, prop_dynamic and trigger_multiple entities.
- Demo of func_movelinear used for a similar effect.
- Elevator has a button for each floor.
- Each floor has a functional door and buttons.
developer 2
.Creation
func_movelinear
The reason I included a demo of func_movelinear, with a box moving up and down, is to show how a simple elevator or lift can be created. The method I used for the box going up and down took all of 2 minutes to create. (Visible below, next to the player start, in the images of the elevator interior.) These are brush-based entities you texture as needed. The one in this project uses two outputs back to itself.
My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
---|---|---|---|---|---|---|
OnFullyOpen | crate_lift | Close | 3.00 | No | ||
OnFullyClosed | crate_lift | Open | 3.00 | No |
And a logic_auto
to open it when the map starts.
My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
---|---|---|---|---|---|---|
OnMapSpawn | crate_lift | Open | 0.00 | No |
After its initial opening the func_movelinear
will trigger itself. You can easily control func_movelinear
with buttons and triggers.
I believe the best way to make elevators in HL2 is with func_tracktrain
. You will see a lot of comments about how difficult it is to get things working properly but I can assure you it’s not at all difficult. Once you know a few tricks, these can be created in a matter of minutes. One such trick is the use of a one-time-only path_track
to spawn the elevator. It is never used again after that. In the case of this 4 floor elevator, another path_track
is in the same general area as the first and it will be used instead each time the elevator returns to floor 1.
There are three adjustments you will need to make once your elevator is working.
- The position of the first
path_track
. - The position of the substitute
path_track
that will replace it. - The
func_tracktrain
’s Height above track property.
By tweaking these three objects you can get the elevator to start and stop exactly where you want. Keep in mind func_tracktrain
entities must be created facing East, or to the right in the top (x/y) 2D viewport. How can you tell which way is East? Once you create the first block for your func_tracktrain
think of the right side as the front. During the rest of your design time build your func_tracktrain
accordingly.
You should also know that the func_tracktrain
doesn’t have to be built in place. It will spawn in position at the First Stop Target you specify. In this project the func_tracktrain
has as its First Stop Target path_track_01
and I’ve checked the flags Fire once and Teleport to THIS path track for that path_track
. It will only be used once, after that path_track_01a
will be the first path_track
.
path_track_01
, the first path_track
, is shown in red. Its substitute is 5 units lower. This really is a fast and easy way to force your elevator to spawn, start and stop in the exact positions you want it to.
Your first path_track
is created once you have created the func_tracktrain
for your elevator. The remaining path_track
s are all clones of the first created by selecting a path_track
and then holding ⇧ Shift while you drag a clone with the mouse. The very same method you may be using for ropes. Once you create the first path_track
give it a name right away. As you create the clones Hammer will name the others for you and set the Next Stop Target property as well. You can create all of your path_track
s in a matter of seconds.
Building your Elevator should be done once you have the initial func_tracktrain
functional. Create the initial func_tracktrain
and the path_track
s and then test your map.
Simple Elevator
For this project I’ve used the dynamic elevator and prop doors. The elevator prop is: models/props_lab/freightelevator.mdl
.
The doors for the elevator are models/props_lab/elevatordoor.mdl
. Both the doors and the elevator are prop_dynamic
s. Your elevator can be created entirely as one func_tracktrain
instead of being parented to one like this project. You must also decide how the doors will function: will they move up and down with the elevator or will each floor have doors?
func_tracktrain
can be used in this same manner to create elevators, trains, boats, effects, etc. What you create and how you do it is up to your imagination.
One nice addition for your elevator is a trigger_multiple
placed on the inside. Parent this to the func_tracktrain
or the elevator. You can use this to sense when the player has entered or exited the elevator. To illustrate that I’ve created one for this project with a single output.
My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
---|---|---|---|---|---|---|
OnEndTouch | prop_door* | SetAnimation | close | 0.00 | No |
When the player exits the elevator the prop doors will close. Notice the asterisk. This will cause each of the 4 prop doors to be closed because they are named prop_door1, prop_door2, prop_door3 and prop_door4.
Each floor has a button to open the elevator doors by way of a func_button
.
My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
---|---|---|---|---|---|---|
OnPressed | prop_door1 | SetAnimation | open | 0.00 | No |
Advanced Elevator
In the more advanced sample file below the elevator can be called from each floor. Leaving the elevator will cause these doors to close, pressing the button on the outside wall will open the doors, when the elevator starts each time the doors will close. Everything on this elevator works very well but the simple elevator has a shortcoming. Neither of these elevators is not designed to go backwards. You should think about how your elevator will function and what it will take. This elevator can be made to go backwards with a variety of methods, the func_tracktrain
can be made to go backwards, each path_track
can have an alternate path and you can double the amount of logic_relay
s. For me, this is acceptable, because where I grew up in Detroit there were elevators which acted exactly like this one, they would start from the first floor and collect passengers as they went to the top, then they would return to the lower levels to start all over again. Just how much detail and time you put into the elevator is of course up to you.
Should all your floors be the same height to make it easier on creating the path for your Elevator? I don’t think so. To illustrate that I intentionally made these 4 floors different heights. The first floor is the only tricky part; each remaining path_track
is simple to get in place. I don’t think there’s a right and wrong way to create these elevators, if it’s working the way you want, without errors, then it’s right.
Notice the differences between the two sample vmf’s below. Each uses the same elevator and surroundings. One is simple and stops on each floor. This is done by adding an Output to each path_track to stop the func_tracktrain
and in this case another output to pen the doors. The more advanced version below doesn’t do that. Each path_track
has a logic_relay
it triggers. The trick is to have the elevator buttons Enable
or Disable
the logic_relay
s. A logic_relay
that is disabled won’t do anything when it’s triggered.
These buttons are textured with tools/toolsnodraw
and each one is parented to the elevator. For each button is an env_sprite
, a really cheap way to create buttons but effective. When the Player presses any of the 4 buttons the sprite color is changed, a series of logic_relay
s are either Enable
d or Disable
d, the door animation is changed and the elevator is told to start forward.
One thing I didn’t do for the simple elevator in this project is create the elevator so it can be called back to a floor from outside the elevator. This can be done by applying the outputs from these buttons to their respective floors. The more advanced elevator below can be called from each floor, and the player spawns on Floor 3 to illustrate this. Another consideration for your elevator would be custom materials for the buttons.
This is a rather long tutorial so I’m not going to detail each of the entity properties as I normally do. Please open the sample projects below and examine the properties I’ve used, and make changes as needed according to your desires and imagination.
See also
- Simple example VMF Note that pressing the elevator button while standing in the path of the door props can make but the player and the elevator become stuck, or let the player access the outside shaft.
- Simple example VMF backup
- Advanced example VMF Note that the door issue is also present here, and in this version the player can actually become stuck inside the world geometry.
- Advanced example VMF backup