Portal 2

Portal 2

Not enough ratings
p0rtalmaster's Hammer Guide Series Part 15/19
By The Sojourner
Hello and welcome to part 15/19 of my series of mini-guides, designed to help you learn perhaps what is the biggest part of the Portal 2 Authoring tools: Hammer.

For a super-quick version of this series, please check out my other guide, Hammer for the Flustered.
   
Award
Favorite
Favorited
Unfavorite
Intro
As GLaDOS once said, sometimes testing has to occur outside of the confines of the testing chambers. When that happens, we want to make sure you understand what's out there and how to make it for yourself. So come with me on a journey outside of the testing chambers and into the "wild."
Circuit Breakers and Industrial Buttons


Breakers are most prominent when activating the lights in underground areas, but they were also used to activate the paint pumps. These breakers typically stay "open" and never "close" (although you can adjust the I/O with a logic_branch so that they toggle, just like the very special one in Portal Stories: Mel). In coop, two of them are used in tandem, and they "close" as soon as they are done "opening."



To make a simple breaker on a wall you'll need:
  • A prop_static for the box part (model to use: models/props_gameplay/circuit_breaker_box.mdl)
  • A prop_dynamic for the lever part (model to use: models/props_gameplay/circuit_breaker_lever.mdl), parented to...
  • A func_door_rotating, 2×2×10, centered around the lever's hinge
  • A func_button
  • For FX (optional but recommended), an ambient_generic or two (some good sounds to use are World.LightPowerOnSwitch, World.LightPowerOff01 (thru 05), and World.a303BigSwitch)
  • For FX (optional), two env_sparks, named the same thing
NB Everything except the prop_static and func_button will need a name.

Settings for the func_door_rotating (important):



NB unless your breaker (for reasons unknown) is on the floor or ceiling, you'll need to check off either the "X axis" or "Y axis" flags on your func_door_rotating (depending on orientation), just as with flip panels. It may also help to check off the "Don't move" flag on the func_button though this is not required.

Now for the I/O. As noted above, there are multiple ways to implement breakers. Let's show off the I/O for a simple breaker:



How about those factory buttons we see all the time? It's essentially the same process as making a breaker, except there's no func_door_rotating nor env_sparks, and the button part is parented to a func_movelinear instead. Here are the parts and assembly:



  • Two prop_dynamics for the button knob and base parts (models to use: models/props_gameplay/push_button_base.mdl and models/props_gameplay/push_button_knob.mdl). Parent the knob to...
  • A func_movelinear, 2×2×2
  • A func_button, 5 units long, 8 units wide, and 11 units high (that is, dimensions 5×8×11)
  • For FX, an ambient_generic (sound set to World.LightPowerOnMd)
NB As before, everything except the func_button will need a name.

Settings for the func_movelinear and func_button (important):



The "Delay Before Reset" keyvalue here is essentially identical to the timer settings on a PeTI pedestal button, the only difference is now you can choose any length of time you want or need (instead of being limited to 3-30 seconds or infinite time).

And here's the I/O for the button — fairly simple stuff, as it's just the func_button you need to send outputs from:



In order to make these buttons behave like a pedestal button (prop_button), you'll need to add extra outputs from the func_button using the OnPressed and OnOut outputs, much like I've done here.

These buttons are also useful when attached to those yellow behind-the-scenes elevators, such as in the Underground-themed "large lake of deadly goo" map. The models to use are different but the process for creating them is the same (though you will need to parent what you can to the elevator).

NOTE: for extra effect...

You can also add a couple of env_sprites (one for "on", one for "off") with these settings:



With the breaker, switch them via the ShowSprite and HideSprite inputs whenever the func_door_rotating is fully open or fully closed. With the button, do it when the button is pressed or released (i.e. the OnPressed and OnOut outputs).
Crushers
Did that deadly pit kill you? No? Then how about a MASHY SPIKE PLATE!!



Crushers are relatively simple given what you've been through so far. You only need:


  • Two trigger_hurts — one for the front and one for the back
  • Two trigger_multiples — one for the front and one for the back, named the same as each of the trigger_hurts since these are to kill test objects (cubes, turrets, etc.) whereas the trigger_hurt is for test subjects.
  • A func_brush (for solidity since the crusher model isn't solid) parented to...
  • A prop_dynamic (set the model to models/anim_wp/cursher/crusher.mdl)
All of the triggers should start disabled. On each of the trigger_multiples, you'll need to first set the "Delay Before Reset" keyvalue to "0" and make sure only the NPCs, Physics Objects, and Physics debris flags are checked (on the Flags tab).

Outputs for the trigger_multiples (similar as when working with deadly goo):



As with panels, you'll need a logic_auto with these outputs to ensure that the triggers and func_brush actually follow the crusher:



For esthetics (and correcting for the sound absent in the crusher animations), we may also need some ambient_generics. Some sounds to use are World.SlowCrusherCloseStart and World.MpCoopTbeamMazeCrusherImpact (the crusher model has its own sounds when un-crushing). Optionally, you may also want to include a crusher plate using a prop_static (model to use: models/props_gameplay/crusher_floorplate.mdl). Be sure to move it 0.25 units out of the wall you intend to place it on or (better yet) create a 192×192×32 hole for it.

In order to keep the crusher going, you'll need a logic_timer with a Refire Interval of approximately 7-8 seconds and the following I/O:



Make sure you have a proper hole for your crusher, as they require a big one. You'll need 256 units of space (2 PeTI voxels) to let it crush stuff, in addition to 448 units (3½ PeTI voxels) for the crusher arm. The width and height of your hole are both 192 units (1½ PeTI voxels) per crusher, plus an extra 32 units on all the sides (unless you're tight on space).

Now, some of you may wish to control Aperture's crushers. Well, hopefully by now you can figure out for yourself the best way to do that...use a button or trigger_once — something predictable or so spend extra time and logic entities making it predictable.

So, where do we send input? Well, you can toggle the timer simply by using the Toggle input. You may also need to use the FireTimer and/or ResetTimer inputs, respectively, when the timer enables. All of this is perhaps best done in a logic_branch (I used the Enable/Disable inputs for the logic_timer; Initital Value is 1):

Grinders/Shredders
Ah, not falling for the mashy spike plate, eh? All right then, let's try... a SPINNY BLADE WALL!!



Grinders a.k.a. Shredders are never really activated or deactivated — they often just keep on running. You'll need:


  • A trigger_hurt, same type as with the crushers but fitted to cover the pit that the grinders lie in
  • A trigger_multiple, same type as with the crushers with the same outputs but fitted to cover the pit that the grinders lie in
  • A couple of prop_dynamics, models set to models/props_gameplay/shredder_left_b.mdl and models/props_gameplay/shredder_right_b.mdl
  • A couple of prop_statics, models set to models/props_gameplay/shredder_left_a.mdl and models/props_gameplay/shredder_right_a.mdl
  • A func_rotating for each prop_dynamic, 16×16×1024, centered on each of the grinder models
NB it is important NOT to use the in-built animation for the grinder model models\props_gameplay\shredder.mdl, as it has a visual glitch (a skip of sorts as the animation is about to loop). That's why we need separate rotators for the props to be parented to.

Settings for each func_rotating:



Yes, even the stuff on the Flags tab is important. Otherwise your grinder/shredder will not rotate correctly.

Now suppose you did actually want to shut off the grinders for whatever reason (maybe to spare all those poor turrets). In that case here is an I/O sampling from a button via a logic_branch (for toggling of course; Initital Value is 1):



Grinders/shredders also need a pit: 1024 units (10 PeTI voxels) long, 256 (2 PeTI voxels) units wide, and at least 192 (1½ PeTI voxels) units deep. Typically there are steep surfaces around the edges of the pit for these deadly things.
Conveyor Belts


No, no I'm not even gonna go there. The VDC Wiki has done too good a job for me to want to repost the stuff here, so for this section I'll defer you to...

Now go complain that the rest of the VDC Wiki isn't like this page or so update it :P
Mistakes to Avoid & More Information

  • Incorrect angle in the breaker levers
  • Sloppy crusher design
  • Sloppy grinder design
  • Sloppy conveyor belt design

More information from the VDC Wiki:
Master Guide List
Please note that there are still some works in progress. This section will be updated as I finish more guides for you!

You are currently viewing part 15/19 in the series.

| 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

Previous Guide (compiling a map)
Next Guide (about the Aperture Science Pneumatic Diversity Vent)

Please feel free to leave a well-reasoned question or comment below. Either I or a qualified Test Chamber Associate (you'll know because they make all the good maps on the workshop) will respond. If your question or comment is not well-reasoned, I recommend reading over my guides again until you understand them 100%. No further information is required here or will be provided, and you will become an excellent Test Chamber Designer — using Hammer!

9 Comments
reivaxo 10 Feb, 2020 @ 8:13pm 
Thanks, that is very helpful!
TutoredSpider12 26 Jul, 2019 @ 12:00pm 
Select a brush and press Ctrl+T and select func_movelinear from the dropdown menu on the window that pops up
InsanityWaffles 9 Feb, 2018 @ 11:35am 
How do I make a func_movelinear?
TeamSpen210 26 Aug, 2017 @ 11:28pm 
Textures in the 'lights/' folder are rather special - many are setup so the brush itself generates the light. For the walls, search 'gradient' - there's some textures which include the orange glow in them.
Mikan 17 Aug, 2017 @ 4:04pm 
I have a question about the conveyer: The beginning and the end have the "lights/light_orange001" texture, but how do you achieve the orange glow?
Theezakje 27 Jul, 2016 @ 12:30am 
Thanks for making this p0rtal, I just found the right sound for the lever!
Person Meetup 20 Jul, 2016 @ 3:37pm 
Thanks!
The Sojourner  [author] 18 Jul, 2016 @ 7:37pm 
You'll need to check either the "X axis" or "Y axis" flags on the func_door_rotating (depending on the orientation of your breaker) to get it to rotate correctly. I'll update the guide with that detail that I seemed to have overlooked. Thanks :p2apertue:
Person Meetup 18 Jul, 2016 @ 7:57am 
Question: When I activate the circuit breaker in-game, it heads towards the right. How do I fix this?