====== Lab 2: Collect Them All - Picking Up "Home Made" Objects ======
{{:public:t-vien-15-3:lab2-image.png?500|}}
===== Goal =====
The goal of this lab is to create an interactive scene where you can walk around and pick up various "home made" textured objects you have created with Blender 3D.
===== Preparation =====
- **Install Blender** You need to install Blender 3D on your own machine before you start. You get the latest version from the [[http://www.blender.org/|Blender 3D Home Page]].
- **Install Gimp** (or similar) It is also good to have an image editing program ready, such as Photoshop or the powerful but free [[http://gimp.org|Gimp]] image editor.
- **Set Up Unity Folder** In Unity it may be a good idea to organize all of your VIEN work inside a dedicated ''VIEN'' folder in the **Project** panel. To do that, **right-click** on ''Assets'' and select ''Create->Folder'' and type ''VIEN'' as the name. Under the VIEN folder, create three more folders: ''Scenes'', ''Scripts'' and ''Props''.
===== Procedure =====
- **Basic Scene** In Unity, start with an empty scene. Add a floor (as a ''Plane'' game object) and replace the ''Main Camera'' with a ''FPSController'' from the ''Characters'' Assets Package. Make sure you can walk around your plane. Feel free to embellish this scene with other visuals (e.g. remove the skybox and add fog in **Window->Lighting**, sky color can be changed in the ''Camera'' component of the ''FPSController->FirstPersonCharacter'' game object). Save your scene in your "VIEN/Scenes" folder.
- **Create a Textured Object** In Blender, create a new object from scratch with some texturing and save it directly into your Unity project folder under "Assets/VIEN/Props" (the folders shown in the Unity **Project** panel are all in the same folders on the hard disk). For this step follow the instructions on the [[public:t-vien-15-1:blendertexturing|Blender Model Export and UV Texturing]]
- **Make Object Instance Sense Collision** Once you have instanced your new textured object as a **GameObject** in the scene (you can either drag it into the **Hierarchy** panel or drop it onto the plane in the **Scene** view), click on it in the **Hierarchy** view and in the **Inspector** panel click on **Add Component** and use the search box to search for a ''Sphere Collider''. Add this collider component to your game object. In the ''Sphere Collider'' check the ''Is Trigger'' check box. You have now created an invisible sphere around your object, which generates a trigger event if something collides with it. You can control the radius of this sphere directly from the ''Radius'' property in the **Inspector** panel.
- **Create a Pickable Behavior** You now have to add code to the object to tell it what to do when a collision is detected. In Unity, such behavior code is really just another component that can be added to game objects. We first have to create that component as an Asset, before we can attach it. So, in the **Project** panel, navigate to your ''Scripts'' folder (or create one under ''VIEN'' if you haven't already). Right-click inside that folder and select ''Create->C# Script''. Name the new script ''Pickable'', double-click it to open the editor and add the following method to the class that appears:
void OnTriggerEnter(Collider col) {
if (col.gameObject.tag == "Player") {
col.gameObject.SendMessage ("Pickup");
Destroy (gameObject);
}
}
Save the code (Ctrl-S) and back in the scene, select your object and in the **Inspector** press **Add Component** where you can use the search to find the ''Pickable'' script. Add it.
- **Tag the Player** To be able to identify the ''FPSController'' game object as the player, you have to give it a named tag. Select this game object in the scene and in the **Inspector** find the ''Tag'' property near the top. Select ''Player'' from a drop-down list of available tags. Now it is easy to "ask" this game object whether it's actually the player.
- **Test Collision** Hit **Play**, you should be able to walk around and when you collide with the object it should get destroyed. However, you will see an error stating that "SendMessage Pickup has no receiver". This is because your object has sent a message to the player, expecting a method there with a matching name. We will add this method next.
- **Create Inventory Behavior** In the same way you created the new ''Pickable'' script, create another C# script in your script folder called ''Inventory''. Edit this script in the following way:
- Add a public member variable to hold a sound: public AudioClip pickupSound;
- Add a method, with the name of the pickup message, to play the sound when called: void Pickup() {
AudioSource.PlayClipAtPoint (pickupSound, transform.position);
}
Save the code (Ctrl-S) and back in the scene, select your ''FPSController'' game object and in the **Inspector** press **Add Component** where you can use the search to find the ''Inventory'' script. Add it.
- **Test Inventory Behavior** Once you have added the ''Inventory'' behavior to your player, you have to associate the ''pickupSound'' variable of the ''Inventory'' component in the **Inspector** panel with a sound asset. You can use whatever sound effect you like. You just have to make sure that the sound file is somewhere under the Unity ''Assets'' folder so that you can browse to it. You can either fill in the value for the sound file by pressing the little target circle next to the edit box of the ''Pickup Sound'' property, or you can drag a sound from the **Project** panel right into the edit box. After you have provided the sound, you should play the scene and make sure you hear it when the player runs into the object.
- **Make a Pickable Object Prefab** In order to create multiple instances of your object, that now includes a behavior for being picked up, you can turn it into a **Prefab**. In the **Project** panel, navigate to your ''VIEN'' folder and create a new sub-folder called ''Prefabs''. Open that empty folder. Now drag the working instance of your object in the scene into this ''Prefabs'' folder (you are essentially storing the complete configuration of your game object into a template kind of structure that Unity calls a **Prefab**). Change the name of your new prefab object in the **Projects** panel into ''PickableObject'' or something like that (notice that the name also changes up in the scene). Now you can drag this prefab into your scene as many times as you want to make multple copies of it. If you wish to change any properties in all of them simultaneously, you can select the prefab instead of an object instance and use the **Inspector** to edit a property that then gets propegated to all instances of that prefab.
- **Add a Counter to Inventory** You should do this on your own. Maintain a state in the ''Inventory'' class that knows how many objects have been picked up. Display this number on the screen. To have a class write something onto the GUI, you override the ''void OnGUI()'' method of that class (inherited from ''MonoBehavior''. This method gets called whenever the GUI gets updated by Unity. Here is an example of that method being used to write a sample number on the GUI:
void OnGUI() {
int number = 2;
GUI.Label(new Rect(0,0,Screen.width, Screen.height),"Number:"+number.ToString());
}
- **Extend your Scene** From here you can go wild with making your scene interesting!