Panning & Magically Appearing Text


I'm going to show you how to create text that magically appears when a camera pans past an object between them. This'd be useful for introductory credits or a main menu.

The finished product looks like this (High-Def):

news post image

Alright, first off, we're going to make a little train that travels from point A to point B.
Figure out where you'd like the pan to start, and place a path_track there, and name it train_point01. Place another path_track where the pan ought to end, and name it train_point02. Go back to train_point01 and make sure it's "Next Stop Target" points to train_point02.

Now, you have two choices, and it doesn't really matter which one you choose: either edit the angles of both path_tracks so that they face in the direction you'd like the camera to face whilst panning and change the "Orientation Type" of both to "Face this path_track's angles," OR face the camera itself the correct way (once we've made the camera, of course), and set the path_track's "Orientation Type" to "No change." Again, doesn't really matter which you do, they oughtta have the same end result.

news post image

Now, before we make the camera, we need to make the train that it'll be parented to. Create a simple brush textured entirely with tools/nodraw, and place it somewhere. For convenience, I've placed it right on train_point01, so I don't have to worry about how or when it's going to move to the first point. As usual, name it something snappy and memorable, like train. Make sure it's "First Stop Target" points to train_point01, then go ahead and set the max and initial speed to whatever you want. 32u/s is what I've used in the example video, but if you want a really slow pan, try something like 16u/s or even 8u/s.

news post image

Finally, time to make the camera. Actually, it's a point_viewcontrol, but I like to call it a camera. I've even named it camera. Create one of your very own, name it, then parent it to train, or whatever you named your func_tracktrain. Make sure only the "Freeze Player" and "Infinite Hold Time" flags are ticked.

news post image

Create an info_player_start and a logic_auto. I like to keep them near each other, but you don't have to. We're going to add two outputs to the logic_auto: the first being OnMapSpawn Enable camera with a delay of 0.00s, and the second being OnMapSpawn StartForward train with a delay of 0.01s. If you can't understand that syntax, have a look at the screenshot.
If you want, you can now compile the map and watch your camera pan aimlessly.

news post image

Alright, now we have to make some text to display. Make sure they are on a plane perpendicular to the camera; parallel to the direction of motion of the func_tracktrain.
For testing purposes, I've carved these letters our of separate world brushes. Texture ONLY the front faces of these brushes with something (I've used lights/white here, even though it's not going to be casting light), and put tools/nodraw on all the other faces.

news post image

Turn each letter into a func_rot_button, and rotate them 180 degrees around the Z-axis. If you've applied some kind of custom texture to them, turn on texture lock before you rotate them (just remember to turn it back off when you're done).

news post image

Give each letter a unique name (it helps if they go in numerical order, because many words end up repeating letters), parent each to train - your func_tracktrain - and set "Distance" to "180." Set "speed" to something relatively low; 720d/s or so. I have it set to 2280 because I've gotten the timing correctly (more on this later). Do this for each letter, and remember that the only setting that's going to change from letter to letter is it's name.

Remember also to change "Delay Before Reset" to "-1" so that the letters won't flip around again, and change "Sounds" to "Silent" so that it won't make any noise when moving.

news post image

Create a func_physbox behind each letter, covered with tools/nodraw. All of these will be parented to train rather than to the letter. Name them - again, each name must be individual - I've chosen just to append the letter's name with _helper. Make sure "Disable shadows" is set to "Yes," set "Strength" to "1," and "Material Type" to "None." As far as Flags go, make sure "Break on Touch," "Break on Pressure," and "Break immediately on Physics" are all ticked. To be entirely honest, I'm not sure all these are even needed, but it doesn't hurt to have them.

Now, this next part might be a little confusing, but it will make sense in a bit. For each func_physbox, add the following output: OnBreak Press X with delay 0.00s, where X is the name of the accompanying letter. For instance, letter1_helper would have an output of OnBreak Press letter1, letter2_helper would have an output of OnBreak Press letter2, and so on.

news post image

Hopefully all this will begin to make sense now.

Create a thin trigger_hurt perpendicular to the path that train will be traveling along. It doesn't need to be named, but make sure it's doing "Damage Type" of "Bullet." For flags, tick "Pushables," "Physics Objects," and "Everything."

news post image

This trigger should be behind some vertical object that the camera will pass close to; in my case, a pillar. You could use a wall, tree, or person, but situate the trigger such that when the camera is facing the midpoint of the vertical object, the trigger is completely obstructed from view.

In the screenshot here, the path the camera will travel is the orange line at the top, the green rectangle near the bottom with the beveled edges is the pillar, and the trigger_hurt is the purple box at the very bottom.

So, to explain what's going on here; the train is moving down the path, carrying the camera and letters and letter helpers with it. As the letters and their helpers pass the trigger, it destroys the helpers, and when the helpers die, they cause the backwards-facing letters to rotate 180 degrees, becoming visible.

news post image

Earlier I mentioned that it was a good idea to set the rotation speed of the buttons to a low number.

Well, go ahead and compile your map, and watch it run.

First, you'll notice that some of the letters begin turning too soon and some turn too late; this is because of the position of the helpers relative to the letters. The helpers need to be moved towards the center of the text span; as for how close to the center each individual helper needs to be moved, you're gonna have to do a little guesswork. I'm sure there's some sort of trigonometric formula or equation that could be used to easily determine how far each helper needs to be moved, but I'm too sick of trig at the moment to attempt to find one.

Keep the rotation speed low until each helper is in such a position that you cannot see it rotate at all by the time it emerges from behind the pillar.

news post image

Remember when we made the text, a few steps ago? Well, if you want to use a specific font for your text, you can create a texture with a transparent background, apply it to one long brush, then chop that brush up with the knife/clip tool, and then turn each of those into a func_rot_button, again using texture lock to ensure the letters don't flip around or become misaligned.

news post image

Now, repeat the same steps as with the brush-based letters, and you'll wind up with something like this


That's about it for now - I hope I've given everyone plenty of ideas! If and when you create something involving or building off this technique, please share your results!

- dissonance

View comments ( 7 )

Back to top