====== Lab 4: Puzzle Room ====== {{:public:t-vien-15-3:lab4-image.png?500|}} ===== Goal ===== The goal of this lab is to create an interactive indoor environment, with simple puzzle logic implemented in C#. The puzzle works in the following way: The player/user has to configure a set of switches into a secret pattern to unlock and open a door to get out. ===== Preparation ===== * You should make sure you have the scripts that were used in this weeks [[https://plus.google.com/events/cbmvocshajn4lmv0lipflhsjdj8|Scripting Demo]], you can download them in all in one zip file: [[http://www.ru.is/~hannes/classes/VE2015/VIENDemo4Scripts.zip|VIENDemo4Scripts.zip]]. Note that they won't run in your project (unless the rest of the project happens to be exactly the same as the demo), but you should be able to adapt the code to your purposes in this lab. * You can import the "Prototyping" asset package from **Assets->ImportPackage** to get some tile-able textures for indoor walls, floor and ceiling, or you can import complete modular indoor environments such as the "Corridor Lighting Example" from the Asset store (seen in the image above). ===== Documentation ===== * There is a good set of [[http://unity3d.com/learn/tutorials/modules/beginner/scripting|short tutorials on scripting]] on the Unity 3D page. You should also keep the Unity 3D [[http://docs.unity3d.com/Documentation/ScriptReference/index.html|scripting reference]] close at hand. ===== Procedure ===== - **Floor, Walls and Ceiling** You can use any method you like and construct any layout you wish. The requirement is simply that you have a fully enclosed indoor environment - and that it is in the appropriate scale (e.g. a person needs to fit in there and move around freely). Here are some useful tips: - You can use **Plane**s for floors and ceilings, and **Quad**s for your walls (2-3 meters is a good height for walls). - Both planes and quads are single-sided (there is no thickness to them and the polygons that they are made from have one front facing side) - Use the ''Transform'' component of your building blocks directly to type in exact values for ''Position'', ''Rotation'' and ''Scale''. That way you ensure things line up. - Use **Ctrl-D** to duplicate a **GameObject** (e.g. a wall segment). - Hold down **Ctrl** to manipulate objects in a **snap-to-grid** mode. - **Lights** Insert some **Point Light** sources, which provide some realistic localized lighting. - **First Person Controller** Insert a **FPSController** game object and test out your layout. You may want to adjust the ''Height'' property of the **Character Controller** component and/or the ''Max Forward Speed'' of the **Character Motor** component to provide the right sense of scale in the environment. - **Door(s)** Identify one or more wall panels as doors. Give them a different visual appearance and name them uniquely (e.g. ''Door1''). - **Scene Hierarchy** You may notice that your **Hierarchy** panel will quickly fill up with rather static game objects, such as walls. It is a good idea to gather such static scenery objects under new parents in the hierarchy. This allows us to quickly re-position them together as a single object, and also reduces the clutter. Create a new parent object through **GameObject->Create Empty** and then drag and drop all your walls, floor and ceilings (you can multi-select by holding CTRL or SHIFT) onto that new parent. Rename the parent as something that describes the group, e.g. ''Room''. - **Puzzle Object and Puzzle Pieces** In this environment the player will **not** be collecting objects and therefore will not need an inventory. Instead, you should implement a new **Puzzle** game object (it can sit at the top of the hierarchy, created as an **Empty** object) that contains a puzzle behavior (script). Then, in the same way you created pickable objects in the past, create three **Puzzle Piece** objects around the environment that have the following behavior: (1) They are either in an On or Off state - this should be visible somehow (e.g. color, rotation, effect); (2) When the player collides with the object, the state toggles; - **Door Opening Mechanism** Attach a movement behavior to the door(s). You can use the ''SlideMechanism'' script (from the source files distributed above). Remember that you have to assign a couple of transforms to the ''Start Marker'' and ''End Marker'' public variables for this script to work. You can do that by creating a couple of empty game objects, marking those locations, and then dragging those objects into the corresponding variable slots in the sliding script component. You can make some of your doors simply open when the player collides with them, but pick at least one door that is locked (and can only be opened by solving the puzzle, see below). - **Puzzle Logic** As you toggle different puzzle pieces around the environment, the puzzle object should update its own ''solved'' state. Initially this state should be ''false'', but when a certain combination of On/Off states in the puzzle pieces occurs (you pick the pattern), the puzzle object should switch ''solved'' to ''true'' **AND open one or all of the doors**. You have complete freedom in how you implement this, but keep the following in mind: - If your script needs to access other game objects, you can find any game object by name and assign it to a variable like this: ''go = GameObject.Find ("Door");'' - but only do this once in your script (in the ''Startup'' method), since this is costly. - If your script needs to access a specific component (e.g. another script or property) in another game object, you can request a component by type like this: ''inventory = GameObject.Find ("Player").GetComponent ();'' - It would be best to have the entire puzzle logic inside the puzzle object itself (the puzzle pieces don't even have to know they are part of a puzzle). For example, the puzzle object could possess references to each of the toggling objects and check for their state in each update, comparing them to the solution. - **OPTIONAL: Provide hints** To be fair to the person trying to get out of your environment, you can leave visual cues to what the correct solution is. Use your imagination. - **OPTIONAL: Flashlight** Attach a spot light source to your camera for an additional "spooky" effect if it's a dark room. - **OPTIONAL: Outdoor Environment** What's on the other side of the final door?