Door creation

From Valve Developer Community
Jump to navigation Jump to search
English (en)Русский (ru)Translate (Translate)

In this tutorial, you will learn how to create a functioning brush-based door.

Brush or Point Based?

It is important to know the difference between a "brush-based" and a "point-based" door. For starters, brush-based doors are, obviously, created from a brush that is tied to an entity. You generally have more control over how the door is shaped and how it looks compared to a point-based door. Point-based doors, however, can have functioning opening hardware, such as handles, push bars, and keypads. They are, however, restricted to a select few models that may not be present in more modern titles, such as Portal 2 Portal 2.

Making the Doorway

Note.pngNote:The pictures were taken in the Portal 2 hammer editor, but it works the same in older versions as well.

To create a brush-based door, make a wall with a gap that the player can move through. See dimensions for sizing. To make a gap in the wall, use the Clipping Tool to create a separated section, then make a hole at the bottom of that section. Make sure to put a brush underneath the doorway or there will be a leak.

Door brush 1.png

Tip.pngTip:click on the image for a higher quality

Creating the Brush Door

To create the actual door, create a brush that fills the hole in the doorway. It is recommended to make the door have a different texture to make it stand out against the wall.

Door brush 2.png

Turning the Brush Into the Door

To turn the brush into a functioning door, select it and press ctrl+T. If you want a door that moves in a specified direction, select func_door then scroll down to the Move Direction property and set the value you want, or select up or down from the small dropdown. For a more traditional style door, select func_door_rotating. To make a func_door_rotating rotate around a different point than the center, drag the origin helper in the 2D view or the blue sphere in the 3D view to the point you want it to rotate around.

Door brush 4.png

To activate the door, go into the Flags tab and check either the On Touch, On Use, or both. To have the door close on its own, go to the keyvalues and scroll down to the Delay Before Reset value and set it to whatever delay you want. Keep in mind that the door will not start closing if it detects that there is an object blocking it. To make a door close manually instead of from a delay, go to the next section where we will talk about creating an activator for our door.

Making a Button for Your Door

If you want your door to be toggle-able, you need to create a func_button, or other entity that can activate and send an output, and set it to toggle the door open and close state. If you want a func_door_rotating to move when the player +USEes on the door, and also be able to open and close multiple times when you use it, you will have to create a button that moves with the door. First, name the door something like door1. Then create a brush that covers and extends slightly beyond the door and tie it to a func_button. Set the texture to tools/toolsinvisible and set the collision to None. Then, set its parent to the name you gave the door. When the door moves, so will it. Scroll down and set its reset time to 0 and also set its speed to 1000. We set the speed this high so it resets immediately. Then, go to the output tab. Create a new output and set it to this:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnPressed door1 Toggle 0.00 No

That should enable the door to be used multiple times.

An alternate way to open and close the door is by using trigger_multiples to automatically open and close the door when you approach it. Create a brush with the tools/toolstrigger texture and tie it to a trigger_multiple. Give it a name and then go to the outputs tab. Set the following outputs:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch door1 Open 0.00 No
Io11.png OnEndTouch door1 Close 0.00 No

Keep in mind that there are many ways to open the door, these are just two ways of doing this. For example, in Portal 2 you can open and close them with prop_button and prop_floor_buttons. Almost any entity that is capable of firing an output can open and close doors.

Todo: add more examples

Avoiding Graphical Bugs

When using a func_door, if it is the same width as the wall and moves into it, it will appear to phase in and out if the textures are different. The best way to avoid this is to scale down the width of the door and also to make a slot in the wall for where the door will slide into. This issue is not always present in func_door_rotating as it does not completely submerge into the wall, unless specified, so it is not as important in that case but should still be taken into account.

Door brush 10.png

Making Double Doors

When creating linked double doors, it is necessary that they have interconnecting outputs that open and close each other. First, make two doors through the process stated above and name them accordingly (e.g., door1 and door2). You will then have to choose a different method of opening and closing the doors in tandem based on the activation method you chose.

External Activator (button, trigger)

Add two logic_relay somewhere close to the doors. Name them something similar to door_open and door_close. Set the Start Enabled? property of door_close to Yes. Go to the properties of door_open and set the following outputs:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnTrigger door1 Open 0.00 No
Io11.png OnTrigger door2 Open 0.00 No

Repeat this for door_close but set the input of the first two to Close If using a button or similar entity that will toggle the door on every activation, also add these outputs:

  My Output Target Entity Target Input Parameter Delay Only Once
Io13.png OnTrigger !self Disable 0.06 No
Io11.png OnTrigger door_close Enable 0.05 No

Repeat this for door_close, but set the Target Entity of the second to door_open.

Now, go to your activator and set the outputs:

Toggle (eg. func_button)

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnPressed door_open Trigger 0.00 No
Io11.png OnPressed door_close Trigger 0.00 No

On/Off (eg. Trigger_multiple)

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch door_open Trigger 0.00 No
Io11.png OnEndTouch door_close Trigger 0.00 No

Now, when you trigger door_open (when enabled), it will open both doors and when you trigger door_close (when enabled), it will close both doors.

If using a button to toggle the door, here is a diagram to display how the enable and disable outputs work:
Player uses the button to open --> Button triggers open relay --> Open relay opens doors and enables the close relay (but does not fire it) and disables itself
Player uses the button to close --> Button triggers close relay --> Close relay closes doors enables the open relay (but does not fire it) and disables itself

When the player uses the button, it will try to trigger both relays, but because one is disabled it cannot fire and therefore only one relay is triggered.

If using two buttons that are parented to either side of the door, name them something like button_left and button_right and make one button, for the sake of this tutorial button_left activate the relays while the other, in this case button_right, press button_left when it is pressed:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnPressed button_left Press 0.00 No

The reason why we are using two logic_relays to open and close the door instead of using the Toggle input is simple: if one door gets blocked and prevented from opening, it will default back to the position it was in. This is very problematic because the doors could get desynced and alternate between open and closed. So, to prevent this, we make it so that there are set opening and closing, so that if one door does get blocked it can sync back up with the other by using it a few times.

Flags (Use Opens, Touch Opens)

Todo:  check and see if this method still works


Add two logic_relay's somewhere near the doors (the location is not important, but it helps for organizational reasons to keep them close) and name them as well (e.g., door1_relay and door2_relay). Third, open the properties of the first door, go to the 'Outputs' tab, and add an output similar to the following:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnOpen door2 Open   0.00 No


Do this for the other door too, but change the Target Entity to door1. What these outputs do is open one door when another one is opened (whether that be done via Touch, Toggle, a button, etc.). At this point, you could save and compile to test the doors out if you wanted, but they would only be able to open each other, not close each other. That is where the logic_relay's come in.

Now normally, you would think that you could repeat the process for closing the doors via Outputs (i.e., having one door be closed by the other), but such is not the case. If you try it out for yourself, you will find that the game crashes as soon as you go to close one of the doors. So, to work around this little bug, you need to introduce a logic_relay for each door. If you've followed the above process so far, you should already have the two relays placed and named. Now, open the properties of the first door and add an output similar to this:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnClose door1_relay Trigger   0.00 No


Again, repeat this for the other door, changing the Target Entity to door2_relay. Next, open the properties for the first relay and add an output like so:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnTrigger door2 Close   0.00 No


Repeat this for the other relay, changing the Target Entity to door1. Now save and compile, and you should have a working set of double doors.

To help you understand this concept of Outputs and logic_relay's better, here is a little diagram for the above example:

Player opens door1 -->The opening of door1 triggers door2 to open via the Output of door1
Player opens door2 -->The opening of door2 triggers door1 to open via the Output of door2
Player closes door1 -->The closing of door1 triggers door1_relay -->The triggering of door1_relay triggers door2 to close
Player closes door2 -->The closing of door2 triggers door2_relay -->The triggering of door2_relay triggers door1 to close