WiseSpring: phys_spring

From Valve Developer Community
Jump to: navigation, search

This tutorial was originally created by wisemx. It was originally posted on SDKnuts.net.

Valve only used the phys_spring three times in HL2.

  1. d1_trainstation_05, plug Gordon has to plug back in.
  2. d2_coast_08, plug you have to pull loose to disable Combine forcefield.
  3. d3_c17_08, platform Gordon rides while fighting Combine Soldiers.

The most interesting use has to be the third example; the platform has a phys_spring at each corner which gives it a nice mass-constrained-in-the-air effect.

“nudel” (from Germany) asked if I’d like to participate in a phys_spring contest. One of the rules was that we would use a terrain he created and build a bridge across it with HL2 phys_spring entities. Another rule was that we could not use any length constraints, like I do in some of the tutorials on this site. When you are using swing or spring physics it’s difficult to not use length constraints. This bridge was going to be a problem. The final submissions, Hammer vmf file, by both nudel and myself are in the download below. Both use terrain created by nudel, the water Structures were created by me.

If you compile and run mine you will notice that it is swinging/springing violently when the map starts. This is because I start each of the boards for my bridge Motion Disabled, which by the way are all func_physbox. When the map starts I drop the player on a trigger_once and enable motion on all of the bridge boards. But you’ll notice that each of my bridge boards have a unique name so I can attach the phys_spring and rope entities to them. This is a little trick that will be very useful for you. The name for each of my boards begins with “board”, for example “Board10”.

My trigger_once Output to enable motion on all of the boards at once looks like this:

  My Output Target Entity Target Input Parameter Delay Only Once
Io11.png OnStartTouch Board* EnableMotion 0.00 No

The only reason I did this is because from now on my springing/swinging bridge will be affected by its own mass and interaction from the player and I wanted it to start out springing. I’ve made it so these boards will not break by checking the flag Only break on Trigger. This bridge would work just as well if it is allowed to break, I tested it that way and it would still retain the spring effect even if the broken bridge fell to both sides of the span.

To get this working like I wanted it I had to use phys_ballsocket entities at each corner of each board and specify the Entity 1 and Entity 2 properties.

Example: First swinging/springing board:

  • Class: func_physbox
  • Name: Board01
  • Disable Shadows: No
  • Prop Data: Wooden.Medium
  • Strength: 0
  • Material Type: Wood
  • Disable Receiving Shadows: No
  • Mass Scale: 0
  • Flags: Ignore +USE for pickup, Motion Disabled, Not affected by Rotor Wash, Only Break on Trigger, Don’t take Physics Damage

Each board has 2 phys_spring entities, 4 phys_ballsocket entities and 4 keyframe_rope entities. The ropes were added last, for appearance only. Each of the phys_spring, phys_ballsocket and keyframe_ropes specify the name of the board(s) they are attached to.

When you create ropes like this use these steps:

  1. Create and place the move_rope, give it a name plus the properties you want for your rope or cable. The default texture is cable so if you want the appearance of rope change Rope material to “cable/rope”.
  2. Create your first keyframe_rope and give it a name. We’re going to let Hammer assign the other names based on this one.
  3. Set the properties and for both of these flag Auto resize just to keep it from looking weird.
  4. Now back to your move_rope set the Next KeyFrame to the name of your keyframe_rope.
  5. In the 2D view ports clone your first keyframe_rope by holding Shift while you drag it to a new location. If you do this right your Next KeyFrame will be set each time and the cloned keyframe_rope will have a unique name give to it by Hammer.

When I created the ropes for the bridge I used that method for each side. On each side of the bridge there is one move_rope and a series of keyframe_ropes. In this example getting the right movement out of the phys_spring was a challenge. This was clearly not the right place to use these but in the end it works pretty well. Each of the phys_springs in this example has the same properties, I experimented with changing this for just the boards towards the center of the bridge but when I did that they all fought each other and it looked odd, but it was fun to watch the perpetual motion.

  • Class: phys_spring
  • Spring Length: 5 (How long spring would be if it was at rest.)
  • Spring Constant: 500 (Stiffness of spring. Larger numbers less spring stretch.)
  • Damping Constant: 2.0 (How much energy spring loses. Larger numbers less bouncy.) Relative Damping Constant: 0.1 (Amount of energy spring loses proportional to the relative velocity of two objects spring is attached to.)
  • Break on Length: 0 (If spring's length ever exceeds this length break.)

Take these examples and play with them, I’d be interested in seeing something you use the HL2 phys_spring for. One other project I created with this one is also included with the file below, it shows how to use the springs to bounce an object around, might be helpful but it’s not something I completed, was just for testing.

See also