(*Note: This tutorial assumes you have both Half-Life AND Worldcraft v2.0. This tutorial is designed for those of you who are new to Level editing and CSG (Constructive Solid Geometry) or Brush-type maps. |
This tutorial covers: | - A swinging door
- Lifts with the func_plat entity
- And more ways to make a lift
|
Yes, its the long-awaited Tutorial #5 - This tutorial will be covering a few different topics, as listed in the title. I'm going to keep the intro short (yet again); Blue statements are the functions I want you to perform.
NOTE: I AM going to assume that by now you've mastered how to perform the functions we've done in the previous tutorials.
You came here for the tutorial -so without further ado, why don't you load up Worldcraft now. All tutorials are going to assume you have the latest version, and use the default setup with a 2-button mouse - you should also have all of the proper directories and tools configured before using this tutorial. Refer to the documentation, the WC Setup guide. I will be covering individual WorldCraft commands each time we execute a new command for the first time.
Once Worldcraft has been loaded, go up to the "File" menu item and click on "open". Choose the file from our last tutorial, and be sure the textures load up properly! In Half-Life, all textures are stored OUTSIDE of the map in .WAD files. These must be loaded by the map-editor so that you can apply them to various brushes. Without textures, your shapes and levels would be done in single colors; and who wants that?? Also, I personally like to have all of the menus and status bars turned on (you can select which ones are displayed from the "View | Screen Elements" menu). You may not want this if you have a small screen or are running at lower than 800x600 resolution; but at least note this: ALL Worldcraft menus and toolbars are DOCKABLE.
So I have mine arranged like this (Note: this screenshot was from v1.6; but I still suggest something similar to this setup) - it gives me a large main workspace for my maps, and an organized area for referring to textures, VISgroups, and some entity controls. Feel free to experiment around and find what's comfortable for you - as it is important that you have an arrangement that allows you to work freely and without frustration.
Okay, first on the list is to show you one more type of door. I've gotten several requests asking about how to create that swinging door you encounter throughout much of the game (i.e. Maintenance doors, etc), where you push them open. Its surprisingly simple to create; so let's go ahead and select our rotating door from before. Click the "To World" button. Then, set your grid spacing to 8 units. You may also want to zoom in some with the zoom tool. Use the selection tool to select the origin brush. Delete this brush. Also, select and delete the two buttons we had created. Now, Select our door. I'm tired of it swinging "into" our walls - so I'm going to make a simple door-frame piece that will help make things look a little better. In the XY view, drag the northern edge of the door down (south) 8 units - so that the Y coordinate changes from "0" to "-8". This will create an 8-unit gap between the door and the wall that we will fill with our "door frame". As an artistic note, I want to say now that this is STILL not the best way to do this; there are many more elegant and clean-looking ways to make a door rotate such that it does NOT appear to move "into" other objects... but I want to keep this simple; as well as let all of you figure some of these things out for yourselves through experimentation.
Now we're ready to add our frame, but first let's go back and make our door functional again. Click on the "Browse" button in the textures box and filter on "origin". Select an origin texture and then switch to block creation mode. In the XY view, drag out a new brush from coordinates (-192, 0) to (-176, -16). This should put the "X" center handle of this brush on the "-8" Y coordinate; which happens to be the edge of our door. Now, re-size the brush in the XZ or YZ views so that the brush is aligned top-to-bottom with the door. Press enter to confirm this brush. Next, use the selection tool (and the CTRL key) to select both this origin brush AND our door brush. Hit the "To Entity" button; and choose "func_door_rotating". Then, scroll down in the attributes list and change the "delay before close" to "1". Also, change the "move sound" to "Squeaky1" (leave the "stop sound" at "no sound"). Close this dialog box.
Once our door is defined, its time to make the door-frame brush. Browse the texture box and filter on "lab3_w6brd". Select this texture and switch to brush creation mode. Drag out a new brush in the XY view from coordinates (-192, 0) to (-176, -8). Then adjust it in the XZ or YZ views to be aligned (top to bottom) with the door. Once things are lined up, go ahead and hit the enter key to create the brush. Its probably tough to see your door frame brush with the origin brush in the way - so switch to the selection tool and click on the door. Now, hit the "Hide selected objects" button . This will remove the object from your view and let you see things more clearly. Hit the "Show all hidden" button again once you're done.
Compile and run your map, and test this new door out! It should have to be "pushed" against to open, and creak and squeak as it moves... Notice that if you let it close and push on it from the other side, it swings the other way.
Now, on to the "meat" of this tutorial... Lifts! Lifts are those wonderful platforms that raise up. Before we MAKE a lift; we're gonna need to make some space for one to do something... I've never given you a specific set of Z-coordinates; but I will need to today; so lets make sure everything lines up between your map and my tutorial here... go to "Edit | Select All", and then MOVE the entire contents of our map up or down in the XZ or YZ views until the BOTTOM of the floor brushes lie on Z coordinate (-64); and also make sure that the X coordinate of the far left outer-edge of our brushes (in the XY or XZ views) is (-512). NOTE: You may need to adjust your 3d camera position after doing all this.
Our current room has a pretty low ceiling, so let's raise it up some. Change the grid spacing to 8 units (you may want to zoom in on the map some), and go to our "second" room (the westerly one - on the left in the XY view). With the selection tool, grab the roof brush. MOVE this brush up in the XZ or YZ views so that the bottom of the roof brush lies on Z coordinate (168) - this should make for a nice, tall second room - but we now need to get the room sealed again... as our walls don't extend that high! So go ahead and select each wall (or all of them at once by using the CTRL key while clicking), and use the selection handles to RE-SIZE the brushes UP so that their upper edges lie on Z coordinate (168).
Here is the room with the roof moved and the walls stretched.
This ALMOST completes sealing the room.... But if you switch to camera mode, and point the camera from the room looking back at the hallway, and rotate the camera view pointing slightly upwards; you'll notice that we have a space ABOVE our hallway now that we didn't have before.
This is the camera showing the hole that we now have.
Since we didn't have it before, we now need to add a NEW brush there to plug this hole. So either select the current wall texture in the texture browser; or select another texture that you would like to use, and create a brush in the XY view that extends from coordinates (-272, 0) to (-256, -64). In the XZ or YZ view, re-size this to span from Z coordinate (64) to (168). Once you press enter to confirm the brush, you should see that it fills the gap.
Our room with the hole plugged.
Since our room is now ready, let's do one more preparatory step before adding our lift. Let's make a place for the character to step off of the lift once it raises him/her up... So pick a new texture for this "catwalk", and go to XY view coordinates (-496, 112) and create a new brush that extends to (-432, -16). In the XZ or YZ views, make the Z component of this brush run from coordinate (64) to (72). Confirm the brush placement; and we're ready to start making our lift!
Here is the "catwalk".
Its time again to choose a new texture. Pick one that you think will look like a good lift platform. I leave the texture choice and alignment up to you now, its a creative process and something you should know HOW to do by now at least. Back in brush creation mode, make a new brush in the XY view that spans coordinates (-496, -24) to (-432, -88). In one of the "Z" 2d views, make this brush span Z coordinates (64) to (72). Note: This is our LIFT right now. We have drawn it in its RAISED position. ALL "func_plat" entities will START in their "lowered" position IN the game, but must be created in the level editor in their "raised" position.
Switch to the selection tool, pick this lift brush, and hit the "To Entity" button. Now, choose entity type "func_plat". We need to edit several key values to make our lift function properly, so let's step through that. First up is the "height" key ("Travel Altitude" if you are in SmartEdit mode). This controls how far the platform moves up and down. The easiest way to show this is with a diagram, so here goes (yellow is text and such that I added with my image editing program):
This is the shot of our platform, with the "height" key being determined.
Go ahead and pick any Move sound and Stop sound you like. Once you have those filled in; its time to test your map. Now, the lift SHOULD work; but when you get in the game you'll notice its a little quirky. Compile and run the map; and you'll see what I mean.
You might have noticed 3 things, two of which are related:
- The lift
sometimes moves before you get on it. - The lift
STAYS "up" if you stay on it. - The lift
moves whenever you get close to it.
Let me address the second issue first. This is unfortunately just something that can't be helped - func_plat objects are designed to be 1 way (you can make them lower only with a negative value in the "height" ("Travel Altitude" if in SmartEdit mode) key. Now the other two issues can't be changed either; but they do clue us into some workarounds... The func_plat entity seems to activate whenever a player gets close to one; however, the platform is actually designed to activate whenever a player's location in the XY plane intersects the extents of the XY coordinates that the platform brush(es) make up. This is all done without regard for the Z axis (which is why you can be standing on the catwalk and move close to the lift and it will raise up); the catch to all of this is that the player is REALLY defined as a rectangular box roughly 32 units wide, 72 units tall; and 32 units FRONT TO BACK. This means that while you may not be "stepping" on the platform, the game engine detects that your player's BOUNDING BOX is activating the platform.
So what can we do about this?? Well, the simplest solution is to make sure the player "steps" on the platform while s/he is above it or level with it; so that the platform may rise, but the forward momentum of the player will be such that they can still climb on the train before it raises above them. Normally; I would advise making the floor such that the lift was actually on the same level (i.e. make an indent or recessed area of the floor that the platform sinks into without actually sinking into the actual floor brush itself). But, this would require messing with our floor brush; and this really is an example only... so lets do this instead: Pick a texture that you like for a floor or piece of metal, it doesn't matter. Now, create a new brush in the XY view spanning from coordinates (-432, 112) to (-272, -112). Re-size this in the XZ or YZ views so that it rests on the top of the floor brush; and is 8 units tall. Then, press enter to confirm this brush. Try running your map again, and notice how much better it works when your player is standing level with the platform BEFORE they get to it...
Here is the new "floor" brush. Now you might be asking yourself right now why this seems so different from most of the elevators and lifts you find throughout Half-Life. The simple fact of the matter is: Most of the lifts and elevators you see AREN'T func_plat entities. Let me show you how one other type of entity is great at masquerading as a lift: the func_door entity. That's right! I told you it was versatile... now here's where it shows its colors again. Allow me to demonstrate. Select our lift in WorldCraft and bring up the object properties box (ALT-ENTER). Change the entity class to "func_door", and change the angle to "down". Choose any "move sound" and "stop sound" values you want, and also change the "Delay before close" to "2". Now, the only catch to this whole thing is the fact that doors only move an amount equal to their thickness in the direction of travel. In this case; that's 8 units. So we need to alter this... And we do so with a little creative use of the "lip" key. The key can be negative; so all we have to do is take the "height" we calculated earlier (112 units), and subtract the amount that the door is already going to move (8). A little math shows us that we want to put in "-104" in the lip key; so go ahead and do that now. Only one thing remains to be configured. Platforms are drawn in their raised position; but doors are drawn in their CLOSED position. So if we want the "platform" as a door to start down at floor-level, we must go to the "flags" section of the entity properties window and check the "Start Open" flag.
The platform as a func_door entity.
Close the properties dialog box, and go compile the level. Note how the "platform" works now as a door. At this point it should work fairly similarly to what we were doing with the func_plat entity. One thing to try, just to see one way to make the func_door as a "platform" work differently than the func_plat, is to go BACK to the entity properties box for the func_door "platform" and check off the "Toggle" flag. This will make the lift stay at whatever level you step off (top or bottom); and it won't move until you trigger it again (although it is VERY sensitive and will re-trigger if you don't step off before the platform gets to the top or the bottom). Try compiling again and you'll see what I mean. Also, I won't be demonstrating it here; but you should see how the fact that this is a func_door means that the lift can be activated with triggers or buttons, just like our doors in Tutorials 3 and 4.
There is _1_ more platform type of entity that I have yet to cover: the "func_train" entity. This entity makes a moving platform that can travel between any number of points in any direction. Its not the simplest of entities to use; but I'll demonstrate a quick example of how to make one a lift that moves between a raised and lowered position. Note that I hope to have a more complete func_train (and func_tracktrain) tutorial up by mid-week. For now, select our platform, hit the "To World" button, and then hit the "To Entity" button, bringing up the entity properties box (doing this clears all of our settings out for the func_door; so that we start "clean" with this entity). Change the entity class to "func_train". Enter "path1" in the "first stop target" key. Fill in any sounds you like, and name this thing "train1". Then close this box, and switch to the entity creation tool. In the objects box (with the "To World" and "To Entity" buttons), choose entity type "path_corner". Switch to a grid spacing of 4; and in the XY view, place an entity at coordinates (-464, -60)... and yes, this is centered on our platform. Also, in the XZ or YZ views move the entity to Z coordinate (-44). Press enter to confirm it's placement, and note that the center of this entity will be used to line up the center of the func_train platform. Since this entity type has no substance; having it overlap brushes or other entities is not a concern; as long as it doesn't stick out into the "exterior" of our level.
Here is the first path_corner entity.
While its selected, open the entity properties dialog box. Name it "path1", and in the "next stop target" key, put in "path2". If you wanted the platform to pause for a couple of seconds, you could enter this into the appropriate key; BUT we're going to click over to the flags, and select "wait for re-trigger". I want the player to have to trigger/activate the func_train platform manually every time they want it to move. Go ahead and close the dialog box. Switch back to entity creation mode, and place another path_corner at XY coordinates (-464, -56), but this time with a Z coordinate of (68). Confirm the placement, and bring up the entity properties box. This path_corner should be named "path2"; and since we want the train to go back down to the first level, the "next stop target" is actually "path1". Once again, in the flags area click the "Wait for retrigger" flag.
This shows our two path_corner entities in position.
Almost there, we just need a button to trigger this func_train to move. And I have an easy way to make one. First off, a warning here again that these techniques (and indeed much of them in my tutorials) are solely to demonstrate the possibilities; they aren't meant to look good or be elegant
Switch to brush creation mode, and select a texture for our button; but realize that this button is going to be rather large. The brush should span XY coordinates (-496, -96) to (-432, -112); and Z coordinates (128) to (-32). Confirm the brush, select it, and then hit the "To Entity" button. Make it a func_button. Give it an angle of 270, and a target of "train1". Also, give it a lip of "4", and any sound you like. Now close the dialog box and compile and test your map.
Here is the new button.
For the last part of this tutorial; I was going to talk about lights. Up until now, we've done everything without lights, so the game renders things at full-brightness. Its rather ugly; but makes it easy to see details. So, what I am going to do, is recommend that you go download the .zip of the next tutorial and the example map; and I will explain the different lights that I placed within that map. I think this is easier than having to have you place each light in the map yourself. For those interested, the next tutorial I have planned (AFTER the lights tutorial) will cover func_trains some more; and func_tracktrains. |