Floor button: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
mNo edit summary
(Rewrite Template:Lang to Template:LanguageBar. This action was performed by a bot.)
 
(79 intermediate revisions by 26 users not shown)
Line 1: Line 1:
=Introduction=
{{LanguageBar|Creating a button and door}}
In this tutorial you will learn how to create a 1500-Megawatt Aperture Science Heavy-Duty Supercolliding Superbutton which whens stepped on or weighted down with a box will open a specified door.
{{Back | Portal Level Creation}}
{{DISPLAYTITLE: Portal - Tutorial - Floor Button}}
{{toc-right}}


=The Door=
This tutorial will show step-by-step how to create the '''floor button''', a test element commonly seen throughout the [[Portal]] test chambers. The floor button is activated by a [[Box dropper|weighted storage cube]] being placed on it, or when a player stands on it, and it can be used to trigger other test elements such as doors, platforms and elevators.
First thing is to make the door which will open on activation of the button.
==Door Frame==
1. Create a prop_static in your door way. The ''World Model'' should be set to '''models/props/door_01_frame_reference.mdl''' or '''models/props/door_01_frame_wide_reference.mdl''' (either will work fine).


==Doors==
{{clr}}
[[Image:Buttonanddoor1.jpg|right|thumb|How to align the func_door.]]
 
1. Create a prop_dynamic with the following settings:
== Construction ==
::{|
=== Base Brush ===
!  Property Name || Value
[[File:Floor button base.png|300px|thumb|right|Base Brush]]
|-
Create a <code>128L*128W*8H</code> [[brush]] and tie it to a <code>[[func_detail]]</code>. Texture the sides of the brush with ''signage/hazard_orange_03b'' texture the top with <code>concrete/concrete_modular_floor001a</code>, and texture the bottom with <code>[[Tool_textures#nodraw|tools/toolsnodraw]]</code>.
| World Model || models/props/door_01_lftdoor_reference.mdl
{{clr}}
|-
 
| Name || door_left_model
=== Corner Overlays ===
|}
[[File:Floor button overlays.png|300px|thumb|right|Corner Overlays]]
Align it to the left, inside of the door frame.
Place four [[Hammer Overlay Tool|overlays]] with the texture <code>signage/overlay_button_accent</code> on top of the brush. Position them in the corners and rotate them so they look like in the picture on the right.
 
{{clr}}
 
=== Button Model Bottom ===
[[File:Floor button prop base.png|300px|thumb|right|Button Model Bottom]]
Create a <code>[[prop_static]]</code> entity and set its ''World Model'' to <code>models/props/button_base_reference.mdl</code>. Position it in the middle on top of the base brush. Rotate it so that the sign with a box and an arrow on the rim of the button faces the way the player will enter the room.
 
{{clr}}


2. Create a 56Lx8Wx104H block brush with texture [[nodraw]] centered and inside the door model. Tie it to a [[func_door]] entity with the following settings:
=== Brush Door ===
::{|
[[File:Floor button door.png|300px|thumb|right|Brush Door]]
!  Property Name || Value
Create a <code>60L*60W*8H</code> eight-sided [[Primitive#Cylinder | cylinder]] textured with <code>tools/toolsnodraw</code> above the base brush, in the same place as the button base prop. Tie this brush to a <code>[[func_door]]</code> entity, go to the flags tab to make sure that all flags are unchecked and then set the following keyvalues:
{| class="standard-table sortable"
|-
|-
| Name || door_left
! Property Name !! Value
|-
|-
| Speed || 250
| Name || floor_button_door
|-
|-
| Stop Sound || Doors.FullClose8
| Speed || 25
|-
|-
| Delay before Reset || -1
| Delay Before Reset || -1
|-
|-
| Lip || 12
| Move Direction || {{vec3|90|0|0}}
|-
| Move Direction || (This will be different for which way your door is facing)
|}
Also make sure that you uncheck ''Touch opens'' under ''Flags''.
{{note|You can also put a blocking damage if you don't want the player to get stuck inside it. Also, you can turn on Forced Closed for it to close even if the player tried to jam it open with a camera or cube.}}
[[Image:Buttonanddoor2.jpg|right|thumb|Final door.]]
3. Repeat steps 1-3 but change the following:
For the '''prop_dynamic''':
::{|
!  Property Name || Value
|-
| World Model || models/props/door_01_rtdoor_reference.mdl
|-
| Name || door_right_model
|}
And for the func_door:
::{|
!  Property Name || Value
|-
| Name || door_right
|}
|}


4. Set the parent of '''door_left_model''' (the prop_dynamic) to '''door_left'''. Also set the parent of '''door_right_model''' to '''door_right'''.
{{clr}}
 
=== Button Model Top ===
[[File:Floor button origins.png|300px|thumb|right|Button Model Top]]
Create a <code>[[prop_dynamic]]</code> entity. Set its ''World Model'' to <code>models/props/button_top_reference.mdl</code>, set its ''Pitch Yaw Roll (Y Z X)'' to the same as the button base prop's and set its ''Parent'' to <code>floor_button_door</code>. Finally, position it in the same place as the base prop, except the origin of the button prop should be 2 units above the origin of the base prop.
 
{{clr}}
 
=== Pressed Trigger ===
[[File:Floor button triggers.png|300px|thumb|right|Pressed Trigger]]
Create a <code>48L*48W*2H</code> brush textured with <code>[[Tool textures#trigger|tools/toolstrigger]]</code>. Tie this brush to a <code>[[trigger_multiple]]</code> entity and set its ''Name'' to <code>floor_button_trigger_player</code>. Go to its flags and make sure ''Clients'' is the only flag that is checked.
 


=The Button=
Next create a <code>8L*8W*2H</code> eight-sided cylinder brush, also textured with <code>tools/toolstrigger</code> in the same place as the <code>floor_button_trigger_player</code> brush and tie it to a <code>trigger_multiple</code> entity. Set its ''Name'' to <code>floor_button_trigger_box</code> and make sure only the ''Physics Objects'' flag is checked. Next, set its ''Filter Name'' to <code>filter_boxes</code>. If you have created a [[box dropper]] in your level, you should already have this entity, but if you don't, create a new <code>[[filter_activator_name]]</code> entity with the ''Name'' <code>filter_boxes</code> and set its filter to the name of your weighted storage cube.
==Models==
[[Image:Buttonanddoor3.jpg|right|thumb|How to align the button models.]]
1. Create a [[prop_static]] with a ''World Model'' of '''models/props/button_base_reference.mdl'''.


2. Create a [[prop_dynamic]] aligned on top of the prop_static with the following settings:
::{|
!  Property Name || Value
|-
| World Model || models/props/button_top_reference.mdl
|-
| Name || button_top_model
|}


==Movement==
Now add the following outputs to <code>floor_button_trigger_player</code>:
1. Next create a 58Wx59Lx9H '''cylinder''' brush with 8 sides and textured with [[nodraw]]. Move this brush right underneath your prop_dynamic. Tie the cylinder to a func_door with the following settings:
{| {{OutputsTable}}
::{|
!  Property Name || Value
|-
|-
| Name || button_top_door
| [[File:Io11.png]] || OnEndTouchAll || floor_button_door || Close || &nbsp; || 0.00 || No
|-
|-
| Speed || 25
| [[File:Io11.png]] || OnEndTouchAll || floor_button_trigger_box || Enable || &nbsp; || 0.00 || No
|-
|-
| Delay before Reset || -1
| [[File:Io11.png]] || OnStartTouch || floor_button_door || Open || &nbsp; || 0.00 || No
|-
|-
| Move Direction || 90 0 0 (or Down)
| [[File:Io11.png]] || OnStartTouch || floor_button_trigger_box || Disable || &nbsp; || 0.00 || No
|}
|}
Also make sure nothing is checked under ''Flags''.


2. Set the Parent of '''button_top_model''' to be '''button_top_door'''.


==Triggers==
Next, add the following outputs to <code>floor_button_trigger_box</code>:
[[Image:Buttonanddoor4.jpg|right|thumb|The larger trigger_multiple.]]
{| {{OutputsTable}}
1. Create a 48Wx48Lx1H block brush textured with [[toolstrigger]]. Place it right on top of the '''button_top_model'''. Tie this brush to a [[trigger_multiple]] with the following settings:
::{|
!  Property Name || Value
|-
|-
| Name || button_trigger_player
| [[File:Io11.png]] || OnEndTouchAll || floor_button_door || Close || &nbsp; || 0.00 || No
|}
We will set up the Output later.
[[Image:Buttonanddoor5.jpg|right|thumb|The smaller trigger_multiple.]]
2. Next create a 7Wx7Lx1H '''cylinder''' brush with 8 sides and textured with [[toolstrigger]]. Put this brush directly on top and in the center of the '''button_top_model''' and tie it to a [[trigger_multiple]] with the following settings:
::{|
!  Property Name || Value
|-
|-
| Name || button_trigger_box
| [[File:Io11.png]] || OnEndTouchAll || floor_button_trigger_player || Enable || &nbsp; || 0.00 || No
|}
And the only the following ''Flags'' are checked:
*Pushables
*Physics Objects
*Everything (not including physics debris)
We will set up the Output later.
 
3. Create a [[filter_activator_name]] nearby your button with the following settings:
::{|
!  Property Name || Value
|-
|-
| Name || button_filter_boxes
| [[File:Io11.png]] || OnStartTouch || floor_button_door || Open || &nbsp; || 0.00 || No
|-
|-
| Filter Name || (The name your box entity has)
| [[File:Io11.png]] || OnStartTouch || floor_button_trigger_player || Disable || &nbsp; || 0.00 || No
|}
|}


4. Select your '''button_trigger_box''' trigger and set the ''Filter Name'' to '''button_filter_boxes'''.
{{clr}}
 
 
=== Interaction Sounds ===
[[File:Floor button ambients.png|300px|thumb|right|Interaction Sounds]]
Create two <code>[[ambient_generic]]</code> entities near the button.  
 


5. Create two [[ambient_generic]] entities and give one the following settings:
Set the following keyvalues on the first one:
::{|
{| class="standard-table sortable"
! Property Name || Value
|-
! Property Name !! Value
|-
|-
| Name || button_down
| Name || button_down
Line 128: Line 100:
| Sound Name || Portal.button_down
| Sound Name || Portal.button_down
|-
|-
| Source Entity Name || button_top_model
| SourceEntityName || floor_button_door
|}
|}
and the other with
 
::{|
 
! Property Name || Value
Set the following keyvalues on the second one:
{| class="standard-table sortable"
|-
! Property Name !! Value
|-
|-
| Name || button_up
| Name || button_up
Line 138: Line 113:
| Sound Name || Portal.button_up
| Sound Name || Portal.button_up
|-
|-
| Source Entity Name || button_top_model
| SourceEntityName || floor_button_door
|}
|}


6. Now go back and select the cylinder [[func_door]] brush under the button, '''button_top_door''' and setup the Output as below:
 
::{|
Next, add the following outputs to <code>floor_button_door</code>:
!  || My Output || Target Entity || Target Input || Parameter || Delay || Only Once
{| {{OutputsTable}}
|-
| [[Image:Io11.png]] || OnClose || door_left || Close || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnClose || door_right || Close || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnClose || button_up || PlaySound || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnOpen || door_left || Open || <none> || 0.00 || No
|-
|-
| [[Image:Io11.png]] || OnOpen || door_right || Open || <none> || 0.00 || No
| [[File:Io11.png]] || OnClose || button_up || PlaySound || &nbsp; || 0.00 || No
|-
|-
| [[Image:Io11.png]] || OnOpen || button_down || PlaySound || <none> || 0.00 || No
| [[File:Io11.png]] || OnOpen || button_down || PlaySound || &nbsp; || 0.00 || No
|}
|}


7. Select the larger [[trigger_multiple]], '''button_trigger_player''' and setup the Output as below:
{{clr}}
::{|
 
!  || My Output || Target Entity || Target Input || Parameter || Delay || Only Once
|-
| [[Image:Io11.png]] || OnEndTouchAll || button_trigger_box || Enable || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnEndTouchAll || button_top_door || Close || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnStartTouch || button_trigger_box || Disable || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnStartTouch || button_top_door || Open || <none> || 0.00 || No
|}


8. Select the smaller, cylinder [[trigger_multiple]], '''button_trigger_box''' and setup the Output as below'
=== Lighting ===
::{|
[[File:Floor button light.png|300px|thumb|right|Lighting]]
|| My Output || Target Entity || Target Input || Parameter || Delay || Only Once
Create a <code>[[light]]</code> entity in the middle of the base prop, 8 units above the base brush. Set the following keyvalues on it and the button should now be finished, ready to be implemented in a map:
|-
{| class="standard-table sortable"
| [[Image:Io11.png]] || OnEndTouchAll || button_trigger_player || Enable || <none> || 0.00 || No
|-
|-
| [[Image:Io11.png]] || OnEndTouchAll || button_top_door || Close || <none> || 0.00 || No
! Property Name !! Value
|-
| [[Image:Io11.png]] || OnStartTouch || button_trigger_player || Disable || <none> || 0.00 || No
|-
| [[Image:Io11.png]] || OnStartTouch || button_top_door || Open || <none> || 0.00 || No
|}
[[Image:Buttonanddoor6.jpg|right|thumb|The final product.]]
9. Finally, create a [[light]] entity underneath the top of the button but still inside the base. Give it the following properties:
::{|
! Property Name || Value
|-
|-
| Brightness || 251 159 57 30
| Brightness || 251 159 57 30
Line 193: Line 140:
|}
|}


You have now created a button which will open a door by a player standing on the button or a box weighing it down. Only those two things will work on it. Download the tutorial .vmf [http://www.remmiz.com/portal/maps/buttondoortutorial.vmf | here].
{{clr}}
{{clr}}


=Theory=
== Implementation ==
This is the most basic button and door setup. You can also have the triggers turn off or on other things in the map, have them trigger a [[logic_choreographed_scene]] or just about anything. For the Portal feel you can have them trigger [[Creating indicator lights|indicator lights]] based on the button up or down status.
[[File:Floor button ingame.png|300px|thumb|right|The floor button in-game]]
Place the button where it should be in the map. Add the outputs that should fire when the button is activated. The outputs that should be fired when the button is pressed should be the ''OnOpen'' output on <code>floor_button_door</code>, and similar the ''OnClose'' output when the button is released.
 
[[Category:Portal]]
[[Category:Level Design]]
[[Category:Tutorials]]

Latest revision as of 17:52, 18 July 2025

English (en)Русский (ru)Translate (Translate)
Portal Level Creation

Warning: Display title "Portal - Tutorial - Floor Button" overrides earlier display title "Floor button".

This tutorial will show step-by-step how to create the floor button, a test element commonly seen throughout the Portal test chambers. The floor button is activated by a weighted storage cube being placed on it, or when a player stands on it, and it can be used to trigger other test elements such as doors, platforms and elevators.

Construction

Base Brush

Base Brush

Create a 128L*128W*8H brush and tie it to a func_detail. Texture the sides of the brush with signage/hazard_orange_03b texture the top with concrete/concrete_modular_floor001a, and texture the bottom with tools/toolsnodraw.

Corner Overlays

Corner Overlays

Place four overlays with the texture signage/overlay_button_accent on top of the brush. Position them in the corners and rotate them so they look like in the picture on the right.

Button Model Bottom

Button Model Bottom

Create a prop_static entity and set its World Model to models/props/button_base_reference.mdl. Position it in the middle on top of the base brush. Rotate it so that the sign with a box and an arrow on the rim of the button faces the way the player will enter the room.

Brush Door

Brush Door

Create a 60L*60W*8H eight-sided cylinder textured with tools/toolsnodraw above the base brush, in the same place as the button base prop. Tie this brush to a func_door entity, go to the flags tab to make sure that all flags are unchecked and then set the following keyvalues:

Property Name Value
Name floor_button_door
Speed 25
Delay Before Reset -1
Move Direction 90 0 0

Button Model Top

Button Model Top

Create a prop_dynamic entity. Set its World Model to models/props/button_top_reference.mdl, set its Pitch Yaw Roll (Y Z X) to the same as the button base prop's and set its Parent to floor_button_door. Finally, position it in the same place as the base prop, except the origin of the button prop should be 2 units above the origin of the base prop.

Pressed Trigger

Pressed Trigger

Create a 48L*48W*2H brush textured with tools/toolstrigger. Tie this brush to a trigger_multiple entity and set its Name to floor_button_trigger_player. Go to its flags and make sure Clients is the only flag that is checked.


Next create a 8L*8W*2H eight-sided cylinder brush, also textured with tools/toolstrigger in the same place as the floor_button_trigger_player brush and tie it to a trigger_multiple entity. Set its Name to floor_button_trigger_box and make sure only the Physics Objects flag is checked. Next, set its Filter Name to filter_boxes. If you have created a box dropper in your level, you should already have this entity, but if you don't, create a new filter_activator_name entity with the Name filter_boxes and set its filter to the name of your weighted storage cube.


Now add the following outputs to floor_button_trigger_player:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnEndTouchAll floor_button_door Close   0.00 No
Io11.png OnEndTouchAll floor_button_trigger_box Enable   0.00 No
Io11.png OnStartTouch floor_button_door Open   0.00 No
Io11.png OnStartTouch floor_button_trigger_box Disable   0.00 No


Next, add the following outputs to floor_button_trigger_box:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnEndTouchAll floor_button_door Close   0.00 No
Io11.png OnEndTouchAll floor_button_trigger_player Enable   0.00 No
Io11.png OnStartTouch floor_button_door Open   0.00 No
Io11.png OnStartTouch floor_button_trigger_player Disable   0.00 No


Interaction Sounds

Interaction Sounds

Create two ambient_generic entities near the button.


Set the following keyvalues on the first one:

Property Name Value
Name button_down
Sound Name Portal.button_down
SourceEntityName floor_button_door


Set the following keyvalues on the second one:

Property Name Value
Name button_up
Sound Name Portal.button_up
SourceEntityName floor_button_door


Next, add the following outputs to floor_button_door:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnClose button_up PlaySound   0.00 No
Io11.png OnOpen button_down PlaySound   0.00 No


Lighting

Lighting

Create a light entity in the middle of the base prop, 8 units above the base brush. Set the following keyvalues on it and the button should now be finished, ready to be implemented in a map:

Property Name Value
Brightness 251 159 57 30
BrightnessHDR 251 159 57 20

Implementation

The floor button in-game

Place the button where it should be in the map. Add the outputs that should fire when the button is activated. The outputs that should be fired when the button is pressed should be the OnOpen output on floor_button_door, and similar the OnClose output when the button is released.