Introduction
The tutorial demonstrates how to make a lift whose button (seemingly) moves along with it.
Setup
The first thing to do is create the elevator. As shown in the picture above, create it with a button as part of it. Select the whole thing and turn it into a
func_train. Set its
Name (
targetname) to
train1
. Set the
First stop target (
target) to
p1a
.
what a mess Create the two
path_corner for the elevator. Give the lower path_corner a
Name (
targetname) of
p1a
. Set its
Next stop target (
target) to
p1b
. In the Flags properties, enable the
wait for retrigger flag. Give the upper path_corner a
Name (
targetname) of
p1b
. Set its
Next stop target (
target) to
p1a
. In the Flags properties, enable the
wait for retrigger flag.
The last thing to do to make this mostly functional is add a set of buttons (one at the top and one at the bottom) to trigger the train. These buttons will be invisible, and must be non-solid. A normal
func_button cannot be non-solid, but a
func_rot_button can be. So, create a small block in the area where the elevator button will be at each position of the elevator (ie: top and bottom). The size and texture of the button doesn't matter, as it will be invisible and non-solid. As you can see in the above picture, I've simply used a small cube with the AAATRIGGER texture on it. Turn the cubes into (separate) func_rot_button entities.
Select the lower func_rot_button and give it a
Target (
target) of
train1
. Set the
Render Mode (
rendermode) to
Texture (1)
. Set the
Distance (deg.) (
distance) to
0
. Normally you'd need to make an origin brush a part of this entity but since it doesn't rotate, its unnecessary. In the Flags properties, enable the
Not solid flag.
Select the upper func_rot_button and give it the exact same settings.
At this point, you can run the level and the elevator will work. However, the two buttons will always be usable. Pushing a button while the elevator is moving will cause the elevator to stop moving. Pushing the lower button while the elevator is at the top position (and no "button" is present in the lower area) will cause the elevator to move down. This is not what we want! However, this is quite easy to correct.
Coordination
Somewhere close to the lower func_rot_button, create a
multi_manager, a
multisource, and an
env_global. Create the same entities near the upper func_rot_button.
Select the lower env_global. Set its
Name (
targetname) to
g_lowbutton1
. Set its
Global state to set (
globalstate) to
glowbutton1
. Set its
Trigger Mode (
triggermode) to
Toggle (3)
. (This means that every time the env_global is triggered, it will switch between on and off.) Set the
Initial state (
initialstate) to
On (1)
. In the Flags properties, enable the
Set Initial State flag.
Select the lower multisource entity. Give it a
Name (
targetname) of
m_lowbutton1
. Set the
Global state master (
globalstate) to
glowbutton1
.
Select the lower multi_manager entity. Give it a
Name (
targetname) of
lowbutton1
. Turn off SmartEdit and give it a key of
g_lowbutton1
with a value of
0
, and a key of
train1
with a value of
0
.
To put these three new entities into use, select the lower func_rot_button and give it a
Target (
target) of
lowbutton1
.
Master (
master) of
m_lowbutton1
. Select the lower path_corner and set its
Fire on pass to
g_lowbutton1
.
And for the upper set of entities...
Select the upper env_global. Set its
Name (
targetname) to
g_highbutton1
. Set its
Global state to set (
globalstate) to
ghighbutton1
. Set its
Trigger Mode (
triggermode) to
Toggle (3)
. (This means that every time the env_global is triggered, it will switch between on and off.) Set the
Initial state (
initialstate) to
Off (0)
. In the Flags properties, enable the
Set Initial State flag.
Select the upper multisource entity. Give it a
Name (
targetname) of
m_highbutton1
. Set the
Global state master (
globalstate) to
ghighbutton1
.
Select the upper multi_manager entity. Give it a
Name (
targetname) of
highbutton1
. Turn off SmartEdit and give it a key of
g_highbutton1
with a value of
0
, and a key of
train1
with a value of
0
.
Select the upper func_rot_button and give it a
Target (
target) of
highbutton1
.
Master (
master) of
m_highbutton1
. Select the upper path_corner and set its
Fire on pass to
g_highbutton1
.
Notes
Ugh... what a mess!
Ok, that's it. To explain in a more simple manner, when you get on the elevator and push what you think is the button, you're actually pushing the invisible func_rot_button. It triggers a multi_manager that toggles an env_global, disabling the button you just pushed. Then it triggers the elevator to move to its next path point. When it gets to the path point, another env_global is triggered, enabling the button on the level you just arrived on.
Since env_global entities are used to set the state of the button masters, you can check the state of the buttons in your level by typing
impulse 104
at the Half-Life console. (I just have a key bound to "impulse 104"). This is VERY useful when you're using env_globals and for some reason or other they don't appear to be working.
Example
For a more concrete illustration, check out the example map linked below.
This article was originally published on the
Valve Editing Resource Collective (VERC).
TWHL only archives articles from defunct websites. For more information on TWHL's archiving efforts, please visit the
TWHL Archiving Project page.