首页 > > 详细

CST8237编程讲解、辅导Java,Python编程、CS,Java程序设计调试讲解Java程序|讲解数据库SQL

CST8237: Games Development
Lab 2: Roll a Ball
13 January 2017
Part I
In this assignment we are going to create a very simple game as an introduction to the basics of Unity3D. You
will not be using any pre-made assets for this game. This project is covered in the Unity3D documentation in a
(video) tutorial: http://unity3d.com/learn/tutorials/projects/roll-a-ball. There is no need to follow
the videos from the tutorial (unless you really want to). Here you can find complete and detailed instructions
for this assignment.
Remember, if this is the first time you open Unity, that you must choose the Free License version and login in
your account (you will have to create one if you haven’t done so yet).
As a general rule for the rest of the lab (and for developing in Unity, in general!), remember to:
• Play-test continuously to see what happens when you add new objects or change some functionality.
• Remember to exit play-test mode when you are done testing. Changes made in play-test mode will not
be saved anywhere!
• Use duplicate and prefabs wherever you can.
• Organize your elements in the Project View in folders, and nest game objects via Empty Game Objects.
• Save your scene regularly.
The Editor
1
• The Scene View: Where the game is visually constructed.
• The Game View: When the Play button is pressed, allows to see the game as it’ll be built.
• The Hierarchy View: Complete list of every object in the current scene.
• The Project Panel: Contains all assets (animations, models, scripts, sound, audio, prefabs) that can
be used in the game.
• The Inspector Panel: Allows to add, modify and remove components from all objects in the scene.
• File → Build Settings..., allows to build the game for any platform.
Unity3D Hotkeys: http://docs.unity3d.com/Manual/UnityHotkeys.html
1 Setting up the project
Create a new project from File → New Project. Choose a directory where you want to store your project and
a name. You don’t need to import any packages and make sure that the defaults are set for 3D in the selector.
You can re-arrange the panels in your view as you like, by choosing an option in the top right selector called
Layout. You can also modify manually your panels. A nice distribution is the one shown in this image:
Now save the current (opened by default) scene. Go to File → Save Scene, give it a name and a location
within the project folder. A recommended place is to put it in a new folder that you create for all scenes, in the
Assets folder. You should be able to see your scene in the Project View panel.
2 Creating the first game objects
We’ll start creating the floor of the game. You can create game objects in different ways. This time, go to the
Hierarchy View and click on Create. Select 3D Object → Plane.
In general, it’s always a good practice to create new objects located in the origin of coordinates (0, 0, 0).
Unity does not always do this by default (it depends on where your cursor is in the Scene View), but you can
easily set the game object’s position, rotation and scale to its default value: with the plane object selected
in the Hierarchy View, you should see its components in the Inspector View. The first component should be
a Transform component, with a gear-like button in the top right corner of the component. Click on it and
select the option reset. This will set the transform of the plane to position=(0, 0, 0), rotation=(0, 0, 0) and
scale=(1, 1, 1).
2
Another good practice is to give all game objects in your scene a meaningful name. In the Hierarchy View,
do right click on the plane object and rename it to ground or floor.
At this point, we only have one game object in the scene, so it is easy to locate it. However, as soon as there
are may objects, you can easily center the view in the Scene View either by double-clicking in the plane in the
Hierarchy View, or by selecting it and, with the mouse over the Scene View, press the key F.
Now, we’ll scale the game object. You can either do it manually, using the scale tool and dragging the axis,
or by modifying the scale values in its transform component. Set the scale to (2, 1, 2).
Now, let’s add a Sphere to the scene. With no elements selected in the Hierarchy View1
, select the option in
the menu GameObject → 3D Object → Sphere. Name the sphere “Player”. Reset the sphere, as you did with
the plane, to be sure it’s located at the center of coordinates.
If you center the view on the sphere, you will realise that it’s buried in the plane. This is because the center
of the sphere is at the origin of coordinates. To put the sphere on the ground, we need to translate it half a unit
in the positive Y coordinate (the sphere radius is, by default, 1 unit). As before, you can change its translation
with the Translate tool, but it’ll be easier to set it in the transform to (0, 0.5, 0). After this, you’ll see that the
sphere is laying perfectly on the floor of the scene.
3 Adding lights
Select the default light DirectionalLight in the Herarchy View, and delete it. Now, let’s add a better light. Click
on Light → Directional Light, give it a nice name and reset its position. We’ll change now its rotation (in its
transform component) to (30, 60, 0) to affect how the lights affects the scene. For directional lights, the position
is not important, as it affects all objects equally.
Another component in the light game object is Light. One of the parameters of this component determines
if the light should cast shadows on the objects that it illuminates. Let’s add shadows by selecting Soft Shadows
in the Shadow Type selector and Very High Resolution in the Resolution option.
Now we’ll add a coloured light. Given that we have already a light in the scene, right click on it and select
Duplicate. Change its name to “Fill Light” and its rotation to (−30, −60, 0). This will be hitting our scene
from below. In the Light component of the new light, set its intensity to 0.2 to dim the light, and change it’s
color to a pale blue (i.e. RGB = (173, 255, 255)). We don’t need shadows from this light, so you can turn them
off.
Finally, let’s organize these two lights in the Hierarchy View. Create an empty game object and reset it to
the origin. Give it a meaningful name that indicates that it will contain all lights of the game (i.e. “Lights”).
Then, drag and drop both lights into the new game object, in the Hierarchy View; this will add these lights as
children of the new game object. Note that it is important to have reset the parent before adding the children:
otherwise, the children will inherit the transformations (translations, rotations, etc.) of the parent. In other
words, the transformation of an object that is a child of another are relative to the one of the parent.
1Note: with an element selected, you would be adding the new object as a child!
3
4 Moving the player
Select the sphere (player) on the Hierarchy View. We want this player to collide with other elements on the scene,
which requires physics. For this we need to add a new component to the game object, of type rigidbody. With
the player selected, click on the Add Component button on the Inspector View. Select Physics → Rigidbody.
In order to capture the player’s input and move the sphere, we need a script. In the Project View, create a
new folder to keep our scripts (name it, for instance, “Scripts”). There are several ways of creating a new script.
In this case, you will select the player in the Hierarchy View, and add a new component of type New Script,
giving it the name “PlayerController”. Make sure that CSharp is selected for the language of the script. This
operation creates a new script and also attaches it to the game object selected. The script will appear now as
a new component of the player, and you can double click on it to open it (note that, by creating the script like
this, you have to move the script to the Scripts folder).
Once the script has been open in MonoDevelop, you’ll see that the script has this aspect:
1 using UnityEngine ;
2 using System . Collections ;
3
4 public class PlayerController : MonoBehaviour {
5
6 // Use this for initialization
7 void Start () {
8
9 }
10
11 // Update is called once per frame
12 void Update () {
13
14 }
15 }
Delete the contents of the class and write the following:
1 using UnityEngine ;
2 using System . Collections ;
3
4 public class PlayerController : MonoBehaviour {
5
6 public float speed ;
7
8 void FixedUpdate ()
9 {
10 float horAxis = Input . GetAxis ( " Horizontal " ) ;
11 float verAxis = Input . GetAxis ( " Vertical " ) ;
12 Vector3 movement = new Vector3 ( horAxis , 0.0 f , verAxis ) ;
13
14 GetComponent < Rigidbody >() . AddForce ( movement * speed * Time . deltaTime ) ;
15 }
16 }
The main points of this snippet of code are:
• A public variable speed.
• We are coding in the FixedUpdate() function, as the operations involve physics.
• We capture the input using the GetAxis() function in both axis. This takes the input from the arrow keys.
• We form a vector with the direction the ball should move.
• We are moving the player by applying a physics force. This force is composed of the direction (movement),
multiplied by a speed and by Time.deltaTime. The latter value contains the time since the last update
call, and assures a smooth movement (try to remove it and see what happens!).
• You can check the meaning of any method by highlighting it in the code and pressing Crtl. (Cmd) + ’.
Now, save the script and go back to the Unity editor. Potential compilation errors should appear in the
Console window (Window → Console), but there should be none. You can test the game by pressing the Play
button at the center top of the screen, and move the player with the arrow keys.
4
Actually, nothing is moving... why? The variable speed has a default value of 0. As this is a public variable,
it will show up in the script component of the player. Look for it and change it’s value to 500.
5 Moving the Camera
Now we are going to place the camera in a better position for the game. Select the camera in the Hierarchy
View and modify its transform, setting the position to (0, 10, −10) and its rotation to (45, 0, 0). Test your game
by clicking on the Play button at the top.
While this is nice, it’s better to move the camera with the player. For doing this, in the Hierarchy View,
drag and drop the camera onto the player, so you’ll make the camera a child object of the player. As we said
before, this will make the camera’s transform be relative to the player’s transform, so the position of the camera
(0, 10, −10) will be relative to the player’s position. Without doing anything else, play test your game.
Ups! Of course, the sphere is rotating, and the camera inherits this rotation too! This probably was a bad
idea, for this game. In a normal 3D person shooter, the target of the camera does not rotate around all its
axis... but here our ball does! So, we need to change this. We’ll detach the camera from the player: drag and
drop the camera away from the Player in the Hierarchy View.
We’ll control the movement of the camera with another script. Add a new Script component to the Camera,
name it CameraController and place it in the appropriate folder. Open the script for editing and you’ll see
again the default code for a C# script. Replace it with the following code:
1 using UnityEngine ;
2 using System . Collections ;
3
4 public class CameraController : MonoBehaviour {
5
6 public GameObject player ;
7 private Vector3 offset ;
8
9 void Start () {
10 offset = transform . position ;
11 }
12
13 void LateUpdate () {
14 transform . position = player . transform . position + offset ;
15 }
16 }
Highlights of this code:
• A public game object, the player, target of the camera.
• A private offset, from the player to the camera.
• We use start to initialize the offset. This takes the initial position of the camera (note that we can use
this vector because originally the player is at the origin).
• We modify the position of the camera (through its transform, directly accessible through the variable
transform), by adding the offset to the position of the player.
• We are doing this on the LateUpdate() method. LateUpdate() is the appropriate place for follow cameras,
procedural animations and gathering last known states.
Save the script, go back to the editor and play-test your game. Obviously something is missing, the camera
doesn’t move with the ball. You have a hint in the console output, there is an error. The problem is that the
public game object reference player of the script is not assigned. With the camera selected in the Hierarchy
View, drag and drop the player from the Hierarchy View onto the player field in the script component of the
camera. Play-test the game again, the camera should move now with the player.
6 Prefabs: walls and pick-up objects
Let’s start creating the walls for the game. Create an empty game object in the hierarchy and call it “Walls”.
Reset it. Create an object of type Cube and make it a child of “Walls”. Give it a name (it’ll be the west wall)
and modify its transform setting its position to (−10, 0, 0) and its scale to (0.5, 2, 20.5).
5
Now, duplicate the wall to create the east wall, giving it an appropriate name. Change its position to
(10, 0, 0). Duplicate the east wall to create the north wall. As we need to rotate this one, change its rotation
to (0, 90, 0) and its position to (0, 0, 10). Duplicate the north wall to create the south one, and set its position
correctly (which one this would be?). Play-test to see if the collisions work.
We’ll create the pick-up objects now. Let’s create a new cube in the hierarchy (don’t forget to reset it)
and name it “PickUp”. Now the pick up is at the same location an the player. To make things easier, let’s
deactivate the player by unticking the tick at the top of the Inspector View, while this is selected. This will
make the object disappear, and inactive in the game.
Let’s change the transform of the new pickup cube so location is set to (0, 0.5, 0), its rotation to (45, 45, 45)
and its scale to (0.5, 0.5, 0.5). We are going to animate this cube with a script, by allowing it to rotate around
its center. With the cube selected, add a new C# script component, called “Rotator”. Place the script in your
Scripts folder and open it for editing. Modify the script so it contains the following code:
1 using UnityEngine ;
2 using System . Collections ;
3
4 public class Rotator : MonoBehaviour {
5
6 // Update is called once per frame
7 void Update () {
8 transform . Rotate (new Vector3 (15 ,30 ,45) * Time . deltaTime ) ;
9 }
10 }
Things to note:
• We are using Update() in this occasion. The movement is not an effect of any physics reaction, so the
place to do the changes is in Update().
• We are applying an arbitrary rotation in the three axis, smoothing it with the time between frames.
Save your changes, go back to the editor and play-test it.
Now, it would be a pain to repeat all this process for each pick-up object that you want in your scene. Even
duplicating objects is not a good idea, as you may want to apply later changes and you would have to modify
all objects one by one. This is a good occasion to use prefabs.
Create a new folder in your Project View, called “Prefabs”. Now simply drag the pick up object from the
hierarchy and drop it into the new folder. This simple step creates the prefab. Now you can delete the pickup
from the hierarchy, as this game object is saved as a prefab with all its components and settings.
The prefab asset is like a blueprint of your game object. You can drag and drop the prefab in the hierarchy
to create copies of this prefab in the scene, and any change you make in the prefab (by having the prefab
selected in the Project View, not selecting a copy in the scene), you’ll make the change effective in all copies of
the prefab in the scene.
Let’s then add the pick-ups. First, create an empty object in the hierarchy to hold all the pick-up objects,
and give it a proper name. Did you forget to reset it? Then do it! Now, drag and drop as many pick-ups as
you want from its prefab to the hierarchy. Make all of them children of your pick-up container.
Once this is done, distribute all pick-ups around your level. You can do this manually by clicking on the
Y cone of the gizmo of the upper right of the Scene View. Iteratively, select each pickup object and place it
wherever you want in the XZ plane, by using the arrows displayed in the Scene View (note: make sure the view
is in global coordinates):
Activate the player back, by ticking the tick near its name on the Inspector View panel. You should see it
reappearing in the scene. Play-test your game. You’ll see that the player collides with the pickups, and all of
them are rotating around their axis.
6
7 Collisions vs. Triggers: picking pick-ups
If we don’t want to have a physical reaction when colliding with a collider, we must indicate that the collider
of the game object must act as a trigger.
Select the pick-up prefab in the Project View and look for the Box Collider component in the Inspector
View. You will see that there is a field called IsTrigger, unchecked. Check it and this collider will act as a
trigger collider. As you are modifying the prefab, you can check how all pick-ups in the scene have now this
field ticked.
If you play-test the game now, you’ll see that the sphere goes through the pick-ups without any physical
reaction. We need to detect this collision in a script, and we’ll do it in PlayerController. Open the script and
add the following function:
1 void OnTriggerEnter ( Collider other )
2 {
3 if( other . gameObject . tag == " PickUp " )
4 {
5 other . gameObject . SetActive ( false ) ;
6 }
7 }
What is this doing?
• OnTriggerEnter() is a function that is called when other game object’s collider, configured as a trigger,
collides with the collider of the game object that has this script as a component (i.e., in this case, when a
pick-up collider collides with the player’s collision).
• We need to check if we are colliding with a pick-up. For this we check the tag of the game object.
• If we are colliding with a pick-up, we set the game object to inactive.
We still haven’t set any tag to the pick-up objects, so let’s do it now. Again, select the pick-up prefab in
the Project View. You will see then, in the top of the Inspector panel, a selector named Tag, with the value
Untagged. Unity includes several default and useful tags for your game objects, and also allows you to create
new ones.
We are going to create a new tag clicking on this selector, and then in the sign ’+’. Then type “PickUp” as
the name of our new tag in the field Tag 0. This adds the new tag to the list of available tags, but it does not
assign the tag to the game object. Therefore, we need to select our prefab again, and assign the tag in the tag
option in the Inspector View. Again, after doing this, you can check that all pick-up game objects have been
assigned this new tag, as we have modified the prefab for these objects.
Finally, play-test your game and check that the pick-up objects are now destroyed when the player collides
with them.
7
8 Counting, displaying the count and finishing the game
Counting the number of pick-ups that are collected is quite straightforward. We’ll do this in the PlayerController
script. Perform the following steps:
• Add a private int count variable to count how many pick-ups are collected.
• Add the method Start, and initialize this variable to 0.
• Add 1 to this value every time a pick-up collides with the player.
Now, we want to add a text to the screen to display the count of collected pick-ups2
.
First of all, create a Canvas object by clicking on Create → UI → Canvas. Then, with the canvas object
selected, do right click on UI → Text to create a new text field. Give a name to this game object (i.e.
“ScoreText”) and, in the Inspector View panel, change its default text to something like “Score: 0”, set the font
color to white and the font size to 24.
In order to locate this text on the screen, you must click on the button at the top left corner of the Rect
Transform component of the text game object:
Press Alt and Shift to reveal pivot and position, after clicking this button. Then, select the top left option
of the available choices. You should see the text location on the screen, in the Game View panel.
Duplicate the text you have just created and give it another name (i.e. “WinText”). Change its default
text to something like “You Win!” and its horizontal alignment to center. Repeat the process that positions
the text on the screen, but this time choose the middle center option (this should place the text in the center
of the screen).
Finally, we’ll add code to the PlayerController script to manage how this text is displayed. Modify the code
so it looks like this:
1 using UnityEngine ;
2 using System . Collections ;
3 using UnityEngine . UI ;
4
5 public class PlayerController : MonoBehaviour {
6
7 public float speed ;
8 private int count ;
9 private int numPickups = 8; // Put here the number of pickups you have .
10 public Text scoreText ;
11 public Text winText ;
12
13 void Start ()
14 {
15 count = 0;
16 winText . text = " " ;
17 SetCountText () ;
18 }
2Note that this is done differently here from the online tutorial. In the videos, the version of Unity used is 4.5, whereas we are
using 5.2. The instructions here show what you’ll find in Unity3D 5.2 (GUI elements are one of the main changes after version 4.5).
8
19
20 void FixedUpdate () {...} // NO changes
21
22 void OnTriggerEnter ( Collider other )
23 {
24 if( other . gameObject . tag == " PickUp " )
25 {
26 other . gameObject . SetActive ( false ) ;
27 count ++;
28 SetCountText () ;
29 }
30 }
31
32 private void SetCountText ()
33 {
34 scoreText . text = " Score : " + count . ToString () ;
35 if( count >= numPickups )
36 {
37 winText . text = " You win ! " ;
38 }
39 }
40 }
Note that we have added a new using statement to be able to use the class Text. Now save the script, go
back to the editor, and assign the text to the variables in the script component of the player. Play-test your
game to check that the score goes up after every pick up and that it displays the “You win!” message when the
game is over.

联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!