Professional Documents
Culture Documents
Management
Submitted by
BACHELOR OF TECHNOLOGY
In
awarded by the
May 2015
ACKNOWLEDGEMENT
It would be really very unfair without the mention of our friends and
families. The immense love and moral support they have given is truly
unmeasurable.
CERTIFICATE
………………………………………. …….………………………..
Prof, (Dr.) S. N. Chaudhuri Dr. Anil B. Adhikari
Director Principal
KIEM, Mankar (Burdwan) KIEM, Mankar (Burdwan)
……………………………………….
Mr. Barun Kumar Das
Project Guide
Dept. of CSE
KIEM, Mankar (Burdwan)
PROJECT REPORT ON
Abstract 1
1 Introduction 2
2 Game Design 3
2.1 Game Design and Concepts
2.1.1 Initial Concept
2.1.2 Seceond Iteration
2.1.3 Final Concept
2.2 Devlopment Process
3 Game Engine 5
3.1 Game Framework
3.2 Unity 3D
3.3 Car Physics 6
3.4 Advance Car Physics 7
4 The Game Camera 8
4.1 Basic Camera
4.2 Smooth Camera
5 The Other Camera 10
6 Materials And Methods 10
6.1 Implementing The A*algorithm
6.2 The First modified A*algorithm : reducing 12
waypoints by a line-of-sight algorithm 13
6.3 Dynamic path finding algorithm for random
obstacles avoidance 13
7 Designing The Car Model 14
8 Creating Terrain 25
8.1 Basic Concept 25
9 Track Design 35
9.1 Add Road Marker 36
9.2 Insert Road Marker
36
10 Coding 39
10.1 AI Script 39
10.2 Path Finding Script
42
10.3 Car Camera Script
10.4 Speedometer Script 53
55
11 References 58
12 Conclusion 59
ABSTRACT
In the end, our case study will show that this development process was
an appropriate choice for our game development project.
1|Page
1. Introduction
Developing software applications is a time-consuming process, and with
time-consuming processes come high costs. During the last years, several
software development methodologies, often known as agile software
development, have become widely used by software developers to address this
issue. Many different development methodologies can be more or less good,
depending of the task and application type.
3D graphics – The game must contain 3D models, and render these in the
game. 3D environments were never a requirement, and platform games with
2D environment could still open up for 3D objects.
Impressive result – The game result must impress whoever plays the
game. It should last long, and make the players come back and play it over
and over again.
With these choices made, we soon had our development environment set to use
Unity 3D supporting the framework, and Blender and 3D Studio MAX for modelling
the graphical components. For some of the sound effects we also made use of Adobe
Audition 2.0.
2|Page
2. Game Design
2.1. Game Design and Concepts
In this project, we were left free to decide what type of game we wanted to develop.
The suggestion was that a racing game would be suitable, since such a game usually
do not depend on advanced assets, e.g. animated models. After some
brainstorming, it was decided that a racing game should be developed. However,
there were two different racing game ideas, which will be described below.
In compliance with our development process, the game concept evolved, as more
and more features were added. To further explain how the game concept evolved,
the development has been divided into three parts.
In addition to the other improvements, one change was made to the points system.
It should be possible to collect three types of coins, worth 50, 100 and 200 points.
2.2. Development Process
In a software development project, the resulting product is required to fulfil many
different qualities. Examples of such quality requirements are:
3|Page
robustness, availability, maintainability, dependability and usability. To meet such
varying demands, it is important to base the work on a well prepared strategy. In
software engineering, the term for such a strategy is commonly known as software
process, which is built on one or several software process models.
There are three major process paradigms that are commonly used today in software
engineering practice; the waterfall model, component-based software engineering
and evolutionary development.
The Waterfall Model
The Waterfall Model is recommended for large and complex systems that have a
long life-time2. Some systems which carry these attributes are also critical systems.
This means that if a fault would occur, it may result in:
Economic loss
Environmental damage
4|Page
1. Requirements definition:
All requirements on the system are found by talking to system users. Example
of requirements can be services, constraints and goals, such as “We want a
webpage that color-blind people can enjoy”.
2. System and software design:
In this activity, the overall architecture of the system is established.
3. Implementation and unit testing:
The software is implemented in units which also are tested.
4. Integration and system testing :
The units are merged together into a complete system. Further testing is
required.
5. Operation and maintenance:
The system is delivered to the customer and put into operation.
“Bugs” are almost always found, and therefore the system required bug-
fixing and maintenance.
3. Game Engine
5|Page
2005, it has since been extended to target more than fifteen platforms. It is now
the default software development kit (SDK) for the Wii U.
Unity Pro is available for a fee and Unity Personal has no fee; it is available for any
use to individuals or companies with less than US$100,000 of annual gross
revenue. On March 3, 2015 with the release of Unity 5.0, Unity Technologies made
the complete engine available for free including all features, less source code and
support. Unity is noted for an ability to target games to multiple platforms.
Five versions of Unity have been released. In 2006 at the 2006 WWDC trade
show, Apple, Inc. named Unity as the runner up for its Best Use of Mac OS X
Graphics category.
In this section we will build the first version of a raycast car. A raycast car is a car
which slides over the ground. Its wheels don’t spin as at drives forward; in this
respect it is actually more like a snowmobile than a car. Every frame we apply a force
to move it forward. It doesn’t move sideways because we will use a Physic Material
with anisotropic friction. Anisotropic friction is a necessary part of a game involving
motion because it allows you to have different friction values for forward or
sideways motion. When moving sideways we will use a much higher friction value
than forward. This will make the car tend to slide forward instead of sideways and
follow the front wheels when they are rotated. We’ll use a simple, three-step process
to build the first version of a raycast car for the player to control. First, we want to
create colliders for the car: add a box collider to the car body of Player Car, then add
raycast colliders to each of the four wheels. These are added to an object by selecting
the object in the Scene view or the Hierarchy panel, and then selecting Component
-> Dynamics from the menu bar. A raycast collider simply uses a ray for collision
detection instead of a volume shape; i.e., a sphere. Also attach a RigidBody with a
mass of 10 to the Player Car. Second, create a Physic Material and set it up as shown
in the following screenshot. Rename it WheelMaterial and move it to the 4 Physics
directory. Assign this new material to all the 4 wheels using drag and drop.
6|Page
3.4. Advanced Car Physics:
In this section we’re going to improve the raycast car. The main change we’ll make
is that we will now rotate the wheels instead of applying a torque to the entire car to
make it rotate. Start by opening up the Basic Setup scene, and adding a box collider,
raycast colliders, and a RigidBody to the various Player Car parts as we did on page
12 in the previous section. Save as... the scene now in the 5 More Physics directory
naming it simply Physics. Now create and save two new Physic Materials – one for
the back wheel named BackWheel, and one for the front wheel named FrontWheel.
These will give us more control over the car handling, because we can tweak and
fiddle with the friction values for the front and back wheels as separate entities in
the Inspector. Set these up using the values as shown in the smaller Physic Materials
setting screen shot in the left sidebar on page 12. Notice how we refined the values
we’ve assigned the Physic Materials by adding a springy contact to the wheel’s
physics material to make it soft. This is done by enabling the use Spring flag, and
setting spring to 25 and damper to 5. Feel free to play around with these values to
get the dampers in your car right. We can now Run this scene and watch the
improved motion of our car. Now let’s tackle the script associated with this scene:
PlayerCar.js. There’s two things in this script that will give the car better physics in
this section. 1) In the script we will now tweak the center of mass and inertia tensor
so that the car has a lower center of mass (to prevent it from flipping over too easily).
2) We remove the torque from the car because we’ll modify the rotation of the
wheels based on the input horizontal axis instead of torque. When we attach this
script to the player car, the four declared variables will have to be connected in the
Inspector so that the script knows which variable is associated with which wheel
(shown at top left).
7|Page
4. The Game Camera:
The goal of this shorter section is to create and manage a camera to follow the
player’s car as it races around the track. In a racing game, one of the most common
camera views is from a third-person perspective; that is, behind and slightly above
the player. This project will show you how to create one of these cameras and then
to move it along in a fluid manner with the player car. In more advanced games
you might wish to set up numerous cameras to capture the action from different
angles. This more complex camera work is done by enabling and disabling various
cameras based on user input.
8|Page
smoothly to the car’s movement. What’s now happening is that this camera script
smoothes out rotation around the y-axis and height, while still maintaining a static
horizontal distance. This method gives you a lot of control over how the camera
behaves because you can tweak lots of the variables. For every of those smoothed
values we calculate a wanted value and the current value. Then we smooth it using
the Lerp function.
9|Page
5. The Other Cars and AI:
This section is where the fun begins. Up until this point we’ve been focusing on
getting a car under the control of the player and also to set up a simple camera that
will smoothly follow the car along a race track. But this is a "racing" game – we
certainly need some other cars on the track that will race around the course trying
to beat us. It will be the most difficult to date as the scripts in this section are more
advanced than anything we’ve looked at so far, mainly because we need to create a
method for opponent cars to drive themselves around the track. To begin the
section we’ll start by creating a car that drives itself around the race track. This car
will be duplicated in the scene to create multiple opponent cars.
Many different types of pathfinding problems exist. Unfortunately, no one
solution is appropriate to every type of pathfinding problem. The solution depends
on the specifics of the pathfinding requirements for any given game. For most racing
game, the artificial intelligence (AI) for opponent characters is needed to find there
path . In our paper, we focus on the car racing game, which can be seen as a kind of
pathfinding problems.
In a car racing game, pathfinding is one of the most important problems. Poor
pathfinding can make game characters seem very headless and artificial. Handling
the problem of pathfinding effectively can go a long way toward making a game
more enjoyable and immersive for the player. The A* algorithm provides an effective
solution to the problem of pathfinding and it also be one of the most popular
algorithm used for the game’s development . Assuming a path exists between the
starting point and the ending point; then the A* algorithm guarantees to find the
best path. Although the A* algorithm is efficient, it still can consume considerable
CPU cycles, especially if you want to simulate pathfinding for a large number of
game characters. The chief shortcoming of the A* algorithm in a racing game is that
it can not solve the problem of random dynamics obstacles avoidance.
In this project, we will first study the A* algorithm in a car racing game, and then
proposes two modified A* algorithm to do pathfinding. After that, we propose a
more general dynamic pathfinding algorithm to solve the problem of random
dynamics obstacles avoidance. All the three algorithms are able to find the path for
a car racing game and can save the most import resource in game, CPU cycles.
10 | P a g e
due to human factors. In order to overcome these problems, we propose two
modified A* algorithms to solve them. Finally, a more general dynamic pathfinding
algorithm which can solve the random obstacles avoidance problem in a racing
game is also proposed. In our paper, we will use the A* algorithm, to find the
shortest path while avoiding the obstacles. The A* algorithm uses path scoring to
determine the best path from the starting node to the destination node. To actually
score each node, A* basically adds together two components. First, it looks at the
cost to move from the starting node to any given node. Next, it looks at the cost to
move from the given node to the destination node.
Equation (1) shows the equation used for scoring any given node. This equation
computes each node's score by adding the cost of getting there from the starting
location to the heuristic value, which is an estimate of the cost of getting from the
given node to the final destination.
where g(n) is the total distance; it has taken to get from the starting position to the
current location. h(n) is the estimated distance from the current position to the goal
destination. A heuristic function is used to create this estimate on how far away it
will take to reach the goal state. f(n) is the sum of g(n) and h(n). This is the current
estimated shortest path. The pseudo code of A* algorithm is shown as Fig. 1
11 | P a g e
6.1. Implementing the A* algorithm
Because the first step in pathfinding is to define the search area, we need some way
to represent the game world in a manner that allows the search algorithm to search
for and find the best path. In our game, we use the trick of color collision to do the
collision detection. Using this trick you first need to make a collision detection map,
as shown in Fig. This can be done easily by using any image processing software
(e.g., Photoshop), and then changes the track to the color which users want to set it
as the collision detection color (e.g., block color). Everything else in the collision
detection map, where the cars are not allowed to drive, you just need to paint them
to white (or any color just do not use the track color black). Ultimately, the game
world is simplified by placing 1280*782 nodes, throughout the game environment.
White color nodes represent obstacles and other colors nodes represent the nodes
which can be passed. After that, we have divided our search area into a 1280*782
square grid. This particular method reduces our search area to a simple two
dimensional array. Each item in the array represents one of the squares on the grid,
and its status is recorded as passable or un-passable. The path is found by figuring
out which squares we should take to get from node A to node B. Once the path is
found, the game-controlled car moves from the center of one square to the center of
the next until the target is reached.
In the implementation of our A* algorithm, each time step only four adjacent
nodes (up, down, right and left) will be checked, as shown in Fig. 2. In Fig. 2 the
blue node represents the current node and the green nodes are the adjacent nodes.
In addition, the image size of car is 18*12 pixels and moving speed is two pixels per
time frame. The racing game uses the default frame rate setting in XNA (60 frame /
sec). Therefore, the maximum linear velocity of the car is equal to 120 pixels per
second.
12 | P a g e
6.2. The first modified A* algorithm: reducing waypoints by a line-of-
sight algorithm
As you known, the more nodes placed in the game world the slower the
pathfinding process. If we simplify the search area by using fewer nodes, the
pathfinding work will save many CPU cycles. In our study, we first used the
original A* pathfinding algorithm to find the best path between the start waypoint
and the end waypoint.
13 | P a g e
Fig. 4. Collision detection points of car
First we need to get hold of some blueprints of the car that we want to model. We
14 | P a g e
tend to use www.the-blueprints.com.
Once selected we pressed Ctrl+C to copy the selection then Ctrl+N to open a new
document. Then pasted the selection into that new document.
15 | P a g e
After doing that we moved onto the next view, which was
going to be the side view. To do that we simply moved the
existing selection box to the bottom of the wheels, and then
right clicked (RMB) and choose the option “Transform
Selection Tool”. Then we moved the top of the box down so
that it was just above the top of the car then we pressed
enter to confirm the change. We copied the selection and
pasted it to the same document as the top view we did.
Using that method, we did the same for the Front and Rear
views also.
Then we had all four views in a single document as individual layers we saved them
as Individual JPG files. To do this hide the side, front and rear views so that all we
saw the top view. We pressed Ctrl+Shift+S to open the saved document. Before
saving we made sure that we had changed the file type to JPEG and
called it something like “Top” or “Top View”.
We did that
for all four
views to make
sure that we
could only see
one image at a
time.
16 | P a g e
Then we opened
3Ds Max.
We started by creating the planes. In the top viewport we created a plane of any
size. In the modify panel, we changed the size of the plane to match the size (In
pixels) of the top view for the car. Our image size was 2662x1386. (Note: in 3ds
Max the length value is the second number we would see in the explorer window.
In our case length is 1386 and our width value is 2662)
17 | P a g e
Now we had our first plane we needed to create 3 more. There was more than one
way of doing this but we found this way to be the quickest. We pressed the snap
rotation button (Circled in the image below) then pressed the “select and rotate”
button (Shortcut E).
Holding Shift we rotated the plane on the X-axis (the red one) we needed to rotate
90 degrees.
18 | P a g e
Continue to do this until you have 4 planes that look similar to the
image below.
Then we had the 4 planes set up, we wanted to add the blueprints to
them. We opened the Materials window (Shortcut M), then clicked
the small box next to diffuse (right) which opened a new window
(below). We double clicked on “Bitmap” to “Open file” window. Then
we navigated through our file and found our blueprints then double
clicked on one of them.
19 | P a g e
Then we had our blueprints in 3ds Max
changed the name of the material (for the
front image we called the material “Front” or
“Front View” and changed the Self-
Illumination to 100 (see left). We repeated
this for each of the views.
20 | P a g e
We did this for all four planes. After this was done we selected all four planes and
right clicked, then we choose “Object Properties” to open a new window. Then we
unchecked “Show Frozen in Gray” and “Renderable”. Next we checked “Backface
Cull” (this made the back of the planes invisible).
21 | P a g e
Then we converted all four planes to editable polygon.
22 | P a g e
Then we changed to sub-object mode and selected Edge (box with a picture of a
triangle). On the side view of the car we selected the top (or bottom) edge and moved
it down (or up) until no white remained. We were careful not to cut off the top of the
car. Then repeated the process for the other views, getting rid of any white parts.
Once our planes had no white borders it was time to move them into position. Using
the “Select and Move” tool we moved the side view back to the edge of the top view.
The front and back views went to either end of the top view. (Note: Front view
should be positioned at the rear end of the car and the rear view at the front end).
Then we moved the top view down to the bottom of the side view (See below).
23 | P a g e
Then we selected all planes, right clicked and selected “Freeze Selection”.
24 | P a g e
8. Creating Terrain
A. Coordinate Space
Three axes X, Y and Z – based on the Cartesian coordinate system
(René Descartes, 1637)
B. User Interface
File > New Project
We don’t have to import any of the packages at this point, but do specify
the save to location in the dialog window. We kept all our project related
assets in this location to avoid missing files and broken links later in the
game development process.
25 | P a g e
User Interface Components (see screenshot on previous page):
1. Scene: This is where you will place any visual assets in your Unity
environment. It will update in real-time when you are previewing the game.
Note the manipulator on the top right; this allows you to switch between a
number of standard views. We are currently in the perspective view (toggle
between isometric (2D) and perspective (3D)). Although this doesn't matter
too much, it allows us to view our scene with a vanishing point, which is the
standard way Unity games will display.
2. Game: When you're not actively running the game, it will show a rendering
of how the game will look, ignoring graphical effects that need to be computed
at run-time, from the point of view of the main camera. When you're
previewing the game, you'll be playing through this window. Since our scene
is currently empty, all this window is showing is the background color.
3. Hierarchy: This lists all the objects in the currently loaded scene, and any
children they may have. Children are objects that can be thought of as
subordinate to the parent object; wherever the top object moves, they'll
follow, keeping the current offset they have to this object. This is an
important concept for Unity beginners to understand; we'll cover it more in
detail later and in the workshops.
4. Project/Assets view: This is a list of all custom assets for our game,
including graphical assets, sound, scripts (more on these later), prefabs
(pre- assembled game objects), and much more. Our current game is
currently using only one empty scene (titled “myFirstScene”).
5. Inspector: Since we currently don't have any objects selected in the
Hierarchy or the Project/Assets view, it's completely blank. The inspector
allows us to look at and tweak individual settings of various game objects and
assets, as well as adjust some global settings. The Inspector is content-
sensitive and changes its parameters based on which game object/asset is
selected. This is also a place to show you your project settings and
preferences by choosing them from the Edit menu.
6. Graphical icons for moving the scene and its contents. The hand
allows us to pan around the scene; when combined with other scene camera
controls, Unity becomes very easy to navigate (see below). The icon on its
right, which looks like four arrows, allows you to move a selected object
around. We call this transforming the object. The next icon allows for rotation
of the object, and the final one allows for uniform scaling of the object.
26 | P a g e
7. Playback bar. This allows us to play, pause, and stop running our game in
the Unity editor. This is the quickest and easiest way to test and tweak the
game.
The scene view is what allows us to look around and move the visual assets we
import into Unity. It's how you'll assemble your levels and place important things
like lighting, trigger zones, audio, and much more. Being able to control the
camera is important if we want to do anything at all with it.
Hand Tool (shortcut Q): drag around in the scene to pan our view.
Holding down alt+drag will rotate the view, Ctrl.+drag will allow you to
zoom. It is important to remember that this doesn't move anything in the
scene, just your point of view.
Translate Tool (shortcut X): active selection tool, enables to drag an
object’s axis handles in order to reposition it.
Rotate Tool (shortcut E): using handles to allow us to rotate an object
around either of its axes.
Scale Tool (shortcut R): works the same as the previous two tools, allows
scaling of an object.
Now that we can look around the scene, let's learn a few ways we can place things
in it. First we'll take a look at the basic game objects Unity can create without
importing external assets. Unity 3 has geometric primitives (cubes, spheres,
planes, capsule, etc.), lights, particle systems, cameras, and more that it can
create without needing external assets. To access these, go to the top menu bar,
select Game Object ->Create Other and make a choice. To begin with, try making
a simple scene with a cube (functioning as a floor), a sphere, and a light. There's
three different types of light - for now, a directional should work just fine, as light
travels in rays with the direction of the arrows of the light, a good way to simulate
the sun in Unity.
Now we just need to move our camera a little back and point it downward to see
the newly created box (it looks more like a plane now, see screenshot on the
following page – we changed the view in the Scene window to left-isometric)
E. Basic lights
See: http://docs.unity3d.com/Documentation/Components/class-Light.html
28 | P a g e
one side of a rectangular section of a plane.
We create a directional light source to illuminate the box in the Game window:
Game Object > Create Other > Directional Light
We should also move the light source a little back, up and tilt it downward to
see its effect on the box object:
Position: X: 0, Y: 10, Z: 20; Rotation: X: 30, Y: 180, Z: 0;
See the change in how the light affects the visual appearance of the
box by experimenting with different angles and directions of your
light source: For example:
Position: X: 0, Y: 10, Z: -20; Rotation: X: 30, Y: 0, Z: 0;
29 | P a g e
F. Basic Physics and Materials
Position: X: 0, Y: 2, Z: 0; Scale: X: 4, Y: 4, Z: 4
Since there is a main camera that comes with every scene, you could hit the play
button now and view your scene. Unfortunately, it will be entirely static. You
can't control the movement of the camera and none of the scene is moving itself.
It would be nice if the sphere would behave as we expect it to from our
observations in the real world – it would fall down and bounce (to a certain
extend) when hitting the ground plane. We can simulate this behavior thanks to
Unity3D’s built-in physics engine.
The first thing we need to do is to give the sphere a rigid body component.
Select the sphere and go to: Component > Physics > Rigid Body.
Hit the play button and you see how the sphere is falling, but not bouncing.
In the next step we create a physic material, which will provide the material
properties to make the game object bouncy:
Asset > Create > Physics Material
30 | P a g e
Then drag the newly created physics material from the Asset window onto the
“Sphere” game object in the Hierarchy window (or directly onto the sphere in the
Scene window).
We started experimenting with different heights from which the ball is falling as
well as different angles of the box to see what response they create in the
behavior of the sphere.
G. Creating Materials:
Assets->Create->Material
We will see the new material in you Project/Assets window and its properties in
the Inspector window. In order to change its color double click the color swatch
next to Main color and choose a different color. We apply the material to a game
object by simply dragging it from the Project window onto the game object in
31 | P a g e
the Hierarchy window (like you did when you applied the physics material
above). We can then start tweaking the material’s properties by experimenting
with different shaders from the shader drop-down menu in the Inspector
window.
32 | P a g e
charming interactive artwork by automatically generating a terrain from
audience member’s fingerprint scans. Visitors were then able to navigate
through their own fingerprint terrain in a first person perspective, see
http://www.futurefarmers.com/survey/fingerprint2.php
First create a new Scene and save it. Then create a terrain:
GameObject > Create Other > Create Terrain.
I also moved the camera up and over a little, this helps you seeing the original
plane for the terrain a little better: Position: X: 500, Y: 100, Z: 0
I changed the view in the Scene window to top view by clicking on the view
manipulator icon in the Scene window’s top right corner (top-isometric).
33 | P a g e
Now, using the Raise/Lower Terrain tool in the
Inspector window (make sure the Terrain is selected
in the Hierarchy window), I can simply “draw” on
the top view of the ground plane in the Scene
window to create certain terrain features.
34 | P a g e
Experiment also with some of the other terrain paint tools, such as “lower terrain
height”, “set terrain height” and “smooth terrain height.”
To see a larger version of your terrain for working on it select the Scene window
and press the “space” bar – this will maximize the window (hitting the space bar
again allows you to return to the regular 2 by 3 layout).
9. Track Design
35 | P a g e
In the property Inspector you will
see the EasyRoads3D toolbar:
Add road markers by activating the Add Markers toolbar tab. Move the mouse to
the position where you want the road to start and click the left mouse button
while holding the [shift] key.
Continue adding markers according the shape of the desired road. We will see
that the road system will create surfaces representing the road and the affected
surrounding which are configurable in General Settings.
Insert road markers works similar as adding road markers but instead of adding
the marker at the end of the road, it will insert the marker between the 2 closest
markers to the mouse position. Make sure you are in Insert Markers mode by
activating the Insert Markers toolbar tab!
When two markers are selected you will see the below buttons in the Inspector:
36 | P a g e
Align XYZ: This will align all markers
between the two selected markers on a
straight line
Average Heights: This will average the heights of all markers between the two
selected markers.
For procedural objects we defined the shape of the object in the Procedural
Object Editor Window. This window will open when we click the button "Edit
Geometry" on the right of the Object Type combo box. This button will become
visible when "Procedural Mesh Object" is selected.
37 | P a g e
The editor window gives a 2D representation of the shape of the procedural
geometry. We can define any shape we want:
1. Add new vertical positions by double clicking on the stage there where we
want to position the new point. Points will be connected to give a clear idea of
the shape.
2. Move points by selecting them (the point turns red) and dragging it while
keeping the mouse down.
3. Delete points with the "Backspace" or "Delete" key.
1. Selected Index: When we select a point the associated index value will be
displayed in the ComboBox. The purpose of this is become explained in the
NOTE here below.
2. Close Geometry: When checked, the first and last point will connect.
3. Trace Object: if we added a Start or / and End object to the associated slots
in the Object Manager this object will appear here. It can be used to
analyze the geometry and automatically define the shape of the procedural
geometry accordingly. Make sure that those vertices used to connect the start
and end assets with the procedural with each other are at position 0 on,
depending on our modeling application, the y-axis or z-axis.
4. Trace On: Depending on the rotation of the asset we may have to switch
between x-axis, y-axis and z-axis until we clearly see the shape that the
procedural geometry should have. By default objects are traced on the z-axis
when opening the editor window and no points are stored yet for this side
object.
5. Auto Connect: Below the situation is described where we can clearly see
that the dots are positioned correctly but they do not connect in the right
order. Auto Connect will be enabled when we select the first point, from this it
38 | P a g e
will connect all points according the closest neighbor. Depending on the
geometry structure it may simplify reordering of point indexes.
6. Mirror Horizontally: This mirrors the shape horizontally and is useful
when correcting the shape of a duplicated side object or when it turns out that
tracing the geometry of the start or end asset results in a flipped shape.
7. Mirror Vertically: This mirrors the shape vertically.
8. Flip Faces: It may happen that the normal point in the wrong direction, we
will notice this when rendering the side object. This button will flip the faces
so it will appear correctly. This feature is also available in the Side Object
Inspector.
10. Coding
10.1. AI Script:
39 | P a g e
var topSpeed : float = 150;
function Start () {
rigidbody.centerOfMass = centerOfMass;
GetPath();
if (path_obj != pathGroup)
function Update () {
GetSteer();
Move();
function GetSteer(){
40 | P a g e
var steerVector : Vector3 =
transform.InverseTransformPoint(Vector3(path[currentPathObj].position.x,tran
sform.position.y,path[currentPathObj].position.z));
wheelFL.steerAngle = newSteer;
wheelFR.steerAngle = newSteer;
currentPathObj++;
currentPathObj = 0;
wheelRL.motorTorque = maxTorque;
wheelRR.motorTorque = maxTorque;
wheelRL.brakeTorque = 0;
wheelRR.brakeTorque = 0;
41 | P a g e
}
else {
wheelRL.motorTorque = 0;
wheelRR.motorTorque = 0;
wheelRL.brakeTorque = decellarationSpeed;
wheelRR.brakeTorque = decellarationSpeed;
var path:Array;
var rayColor:Color=Color.red;
function OnDrawGizmos()
Gizmos.color=rayColor;
var path_objs:Array=transform.GetComponentsInChildren(Transform);
path=new Array();
if(path_obj!=transform)
42 | P a g e
path[path.length]=path_obj;
for(var i:int=0;i<path.length;i++)
var pos:Vector3=path[i].position;
if(i>0)
var prv=path[i-1].position;
Gizmos.DrawLine(prv,pos);
Gizmos.DrawWireSphere(pos,0.3);
#pragma strict
43 | P a g e
var wheelFLTrans:Transform;
var wheelFRTrans:Transform;
var wheelRLTrans:Transform;
var wheelRRTrans:Transform;
var lowestSteerAtSpeed:float=50;
var lowSpeedSteerAngle:float=10;
var highSpeedSteerAngle:float=1;
var deccelarationSpeed:float=20;
var currentSpeed:float;
var maxReverseSpeed:float=50;
var topSpeed:float=200;
var backLightsObject:GameObject;
var idleLightMaterial:Material;
var breakLightMaterial:Material;
var reverseLightMaterial:Material;
var maxTorque:float=250;
var braked:boolean=false;
var maxBrakeTorque:float=100;
44 | P a g e
private var myForwardFriction:float;
function Start () {
rigidbody.centerOfMass.y=0.0;
//rigidbody.centerOfMass.x=0.4;
//rigidbody.centerOfMass.z=0.4;
SetValues();
function FixedUpdate () {
Controle();
handBraked();
function SetValues(){
mySidewayFriction=WheelRR.forwardFriction.stiffness;
myForwardFriction=WheelRR.forwardFriction.stiffness;
slipForwardFriction=0.4;
slipSidewayFriction=0.8;
45 | P a g e
function Update () {
wheelFLTrans.Rotate(WheelFL.rpm/60*360*Time.deltaTime,0,0);
wheelFRTrans.Rotate(WheelFR.rpm/60*360*Time.deltaTime,0,0);
wheelRLTrans.Rotate(WheelRL.rpm/60*360*Time.deltaTime,0,0);
wheelRRTrans.Rotate(WheelRR.rpm/60*360*Time.deltaTime,0,0);
wheelFLTrans.localEulerAngles.y=WheelFL.steerAngle-
wheelFLTrans.localEulerAngles.z;
wheelFRTrans.localEulerAngles.y=WheelFR.steerAngle-
wheelFRTrans.localEulerAngles.z;
backLights();
WheelPosition();
EngineSound();
function Controle(){
currentSpeed=2*22/7*WheelRL.radius*WheelRL.rpm*60/1000;
currentSpeed=Mathf.Round(currentSpeed);
WheelRR.motorTorque=maxTorque*Input.GetAxis("Vertical");
WheelRL.motorTorque=maxTorque*Input.GetAxis("Vertical");
46 | P a g e
else{
WheelRR.motorTorque=0;
WheelRL.motorTorque=0;
if(Input.GetButtonUp("Vertical")==false){
WheelRR.brakeTorque=deccelarationSpeed;
WheelRL.brakeTorque=deccelarationSpeed;
else{
WheelRR.brakeTorque=0;
WheelRL.brakeTorque=0;
var speedFactor=rigidbody.velocity.magnitude/lowestSteerAtSpeed;
var
currentSteerAngle=Mathf.Lerp(lowSpeedSteerAngle,highSpeedSteerAngle,speed
Factor);
currentSteerAngle*=Input.GetAxis("Horizontal");
WheelFL.steerAngle=currentSteerAngle;
WheelFR.steerAngle=currentSteerAngle;
//WheelFL.steerAngle=10*Input.GetAxis("Horizontal");
47 | P a g e
//WheelFR.steerAngle=10*Input.GetAxis("Horizontal");
function backLights(){
backLightsObject.renderer.material=breakLightMaterial;
backLightsObject.renderer.material=breakLightMaterial;
backLightsObject.renderer.material=reverseLightMaterial;
else if(!braked){
backLightsObject.renderer.material=idleLightMaterial;
function WheelPosition()
var hit:RaycastHit;
48 | P a g e
var WheelPos:Vector3;
if(Physics.Raycast(WheelFL.transform.position,-
WheelFL.transform.up,hit,WheelFL.radius+WheelFL.suspensionDistance)){
WheelPos=hit.point+WheelFL.transform.up*WheelFL.radius;
else
WheelPos=WheelFL.transform.position-
WheelFL.transform.up*WheelFL.suspensionDistance;
wheelFLTrans.position=WheelPos;
if(Physics.Raycast(WheelFR.transform.position,-
WheelFR.transform.up,hit,WheelFR.radius+WheelFR.suspensionDistance)){
WheelPos=hit.point+WheelFR.transform.up*WheelFR.radius;
else
WheelPos=WheelFR.transform.position-
WheelFR.transform.up*WheelFR.suspensionDistance;
wheelFRTrans.position=WheelPos;
49 | P a g e
if(Physics.Raycast(WheelRL.transform.position,-
WheelRL.transform.up,hit,WheelRL.radius+WheelRL.suspensionDistance)){
WheelPos=hit.point+WheelRL.transform.up*WheelRL.radius;
else
WheelPos=WheelRL.transform.position-
WheelRL.transform.up*WheelRL.suspensionDistance;
wheelRLTrans.position=WheelPos;
if(Physics.Raycast(WheelRR.transform.position,-
WheelRR.transform.up,hit,WheelRR.radius+WheelRR.suspensionDistance)){
WheelPos=hit.point+WheelRR.transform.up*WheelRR.radius;
else
WheelPos=WheelRR.transform.position-
WheelRR.transform.up*WheelRR.suspensionDistance;
wheelRRTrans.position=WheelPos;
50 | P a g e
function EngineSound()
audio.pitch=currentSpeed/topSpeed+1;
function handBraked(){
if(Input.GetButton("Jump")){
braked=true;
else{
braked=false;
if(braked){
WheelRL.brakeTorque=maxBrakeTorque;
WheelRR.brakeTorque=maxBrakeTorque;
WheelRL.brakeTorque=0;
WheelRR.brakeTorque=0;
SetSlip(slipForwardFriction,slipSidewayFriction);
backLightsObject.renderer.material=idleLightMaterial;
51 | P a g e
}
else{
backLightsObject.renderer.material=idleLightMaterial;
if(rigidbody.velocity.magnitude>1){
SetSlip(slipForwardFriction,slipSidewayFriction);
else{
SetSlip(1,1);
function SetSlip(currentForwardFriction:float,currentSidewayFriction:float)
WheelRR.forwardFriction.stiffness=currentForwardFriction;
WheelRL.forwardFriction.stiffness=currentForwardFriction;
WheelFL.forwardFriction.stiffness=currentForwardFriction;
52 | P a g e
WheelFR.forwardFriction.stiffness=currentForwardFriction;
WheelRR.sidewaysFriction.stiffness=currentSidewayFriction;
WheelRL.sidewaysFriction.stiffness=currentSidewayFriction;
WheelFL.sidewaysFriction.stiffness=currentSidewayFriction;
WheelFR.sidewaysFriction.stiffness=currentSidewayFriction;
#pragma strict
var distance:float=6.4;
var height:float=7.4;
var rotationDamping:float=3.0;
var heightDamping:float=2.0;
var zoomRacio:float=0.5;
var DefaultFOV:float=60;
function Start () {
53 | P a g e
function LateUpdate () {
var wantedAngle=rotationVector.y;
var wantedHeight=car.position.y+height;
var myAngle=transform.eulerAngles.y;
var myHeight=transform.position.y;
myAngle=Mathf.LerpAngle(myAngle,wantedAngle,rotationDamping*Time.delta
Time);
myHeight=Mathf.Lerp(myHeight,wantedHeight,heightDamping*Time.deltaTim
e);
var currentRotation=Quaternion.Euler(0,myAngle,0);
transform.position=car.position;
transform.position-=currentRotation*Vector3.forward*distance;
transform.position.y=myHeight;
transform.LookAt(car);
function FixedUpdate () {
var localVilocity=car.InverseTransformDirection(car.rigidbody.velocity);
if(localVilocity.z<-0.5){
rotationVector.y=car.eulerAngles.y+180;
54 | P a g e
else{
rotationVector.y=car.eulerAngles.y;
var acc=car.rigidbody.velocity.magnitude;
camera.fieldOfView=DefaultFOV+acc*zoomRacio;
#pragma strict
// Arrow object
// Car object
// Initialization
function Start() {
car = GameObject.Find("barun1");
55 | P a g e
var goArrowTransform:Transform = this.transform.FindChild("Arrow");
if (goArrowTransform) {
m_arrow =
goArrowTransform.gameObject.GetComponent(blindGUITexturedContainer);
var goArrowShadowTransform:Transform =
this.transform.FindChild("ArrowShadow");
if (goArrowShadowTransform) {
m_arrowShadow =
goArrowShadowTransform.gameObject.GetComponent(blindGUITexturedConta
iner);
// At every frame
function Update () {
if (car != null) {
56 | P a g e
var relativeVelocity:Vector3 =
car.transform.InverseTransformDirection(carRigidBody.velocity);
speed = relativeVelocity.z;
speed = -135.0f+(Mathf.Abs(speed)/47.0f)*270.0f;
//m_arrow.speed = speed;
//m_arrowShadow.speed = speed;
m_arrow.m_angle = speed;
m_arrowShadow.m_angle = speed;
57 | P a g e
11. References
We have gone through certain books, done some research work using
internet, understanding the technologies being used in our project work.
http://vimeo.com/album/150503
http://www.futurefarmers.com/survey/fingerprint2.php
http://unity3d .com/support/documentation/Components/class-
Texture2D.html
http://unity3d .com/learn/tutorials/modules
http://unity3d .com/learn
http://catlikecoding.com>Catlike Coding>Unity
http://unity3dstudent.com/
http://cgcookie.com/unity
58 | P a g e
12. Conclusion:
59 | P a g e