You are on page 1of 124

TABLE OF CONTENT

ASSET PRODUCTION
1. INTRODUCE BLENDER & BASIC MODELLING ...................... 5
1.1 Interface ........................................................................... 14
1.2 Work With 3D View........................................................... 14
1.3 Basic Modelling ................................................................ 14
2. CHARACTER MODELLING ..................................................... 16
2.1 Character Model Sheet ..................................................... 14
2.1.1 Creating Character Model Sheet ............................... 14
2.2 Character Modelling ......................................................... 16
3. TEXTURING ............................................................................. 29
3.1 Texture ............................................................................. 29
3.2 UV Map ............................................................................ 29
3.3 Texturing Process ............................................................ 33
3.4 Project Texturing .............................................................. 37
4. ANIMATION ............................................................................. 38
4.1 Keyframe .......................................................................... 38
4.2 Bone Deformation Animation ............................................ 42
4.2.1 Rigging Process ......................................................... 43
PROGRAMING PROCESS
5.UNITY VUFORIA, AND GAME DESIGN .................................. 68
6.THE ART OF ASSETS AND PLAYER INTERFACE ................. 75
6.1 Working with Assets ......................................................... 76
6.2 Player Interfaces .............................................................. 78
6.3 Shaping the Assets........................................................... 81
6.4 Unity Animation Workflow ................................................. 84
6.5 Gameplay Interfaces ........................................................ 92
7.BUILDING THE MECHANICS, PROGRAMMING THE GAME 94
7.1 MobData.cs ...................................................................... 95
7.2 HeroData.cs ..................................................................... 95
7.3 Singleton.cs ...................................................................... 95
7.4 SceneHandler.cs .............................................................. 96

i
7.5 PlayerManager.cs ............................................................ 98
7.6 SummonHeroHandler.cs ................................................ 101
7.7 MobHandler.cs ............................................................... 103
7.8 ActiveSceneHandler.cs .................................................. 107
8.FINALIZING PROJECT ........................................................... 120

ii
PART I
Introduce Blender Interface & Basic Modelling

1.1 Interface

This is the default start page when you open Blender. Default means
here is every toolbar / menu box on the right left, up and down the usual
flexibly we change according to our wishes depending on what we need at
the time of editing. The function of this toolbar collection is as a feature that
we can use to create an animation. In each toolbar there is a section in the
left corner which is the menu to choose what kind of toolbar or work area
we will display. This toolbar can also be shifted or added. For more details
see the picture on the next page.
It's good if you try by yourself to reposition a comfortable workplace.
Shifting bars, changing toolbars and more so that you feel familiar using
Blender.

1
Chage window bar

Opening a new bar can be done by click + drag mark in the corner
bar (see picture above). While closing it can be done by click + drag the
mark was to the opposite direction (when opening new bar).

2
In some types of bars it also has an additional menu that serves as
a feature that will be very needed when starting to work with Blender, this
additional menu can be opened by click + drag on the icon (+) next to the
window on the bar (see picture).

3
1.2 Work With 3D View

When you open Blender, Cube, Light and Camera objects will be
available (you can delete them if you want to create animations from other
objects).

Working with 3D objects is actually easy, to be understood is that we


work with X, Y and Z axes. In Blender when we click (left) any object of it, it
will show 3 arrows with different colors. If we make it easier to see from one
perspective, the green arrow as the X-axis (right - left), blue arrow as Z axis
(top - bottom), red arrow as Y axis (front - back).

Then, to make it easier for us to change our perspective of an object,


here are some Hot Key that you can use when starting to work with objects
in Blender:

Mouse Scroll : Zoom in Zoom Out


Mid Click + Drag : Change perspective where the cursor move
Ctrl + Scroll : Move perspective to right-left

4
Shift + Scroll : Move perspective to up-down
Shift + Mid Click + Drag: Move perpective without arounded object
(Z and Y axis)
Ctrl + Mid Click + Drag : Zoom in Zoom Out

[CTRL][2] Menggeser View Objek Ke atas


[CTRL][8] Menggeser View Objek Kebawah
[CTRL][4] Menggeser Objek Kesamping Kanan
[CTRL][6] Menggeser objek kesamping kiri

Number 1 : Fornt View


Number 2 : Rotate below 15 degrees
Number 3 : Right View
Number 4 : Rotate left 15 degrees
Number 5 : Orthogonal view / Perpective View
Number 6 : Rotate right 15 degrees
Number 7 : Top View
Number 8 : Rotate up 15 degrees
Number 0 : Camera Perspektif

1.3 Basic Modelling

Function : To give a thickness or add more objects to a current area

Step : Select a face or edge, or it could be only 1 vertex. Then press


“E” on the keyboard. Drag the selection away from the object. So, the
result obtained are additional objects in an object will stand out visible.

In the Extrude, there are 3 options to extruude, they are:

● Face selection Extrude


● Vertex selection Extrude
● Edge selection Extrude
Some steps below will explain about how for doing extrude in blender:

5
● Face selection Extrude

a. First object in blender


b. Select face section at the bottom of the blender

c. Next, select the face side of the object that is available on your
worksheet. For selecting the object side, do it by right click on
the mouse

6
d. After that, press “E” on the keyboard, left click on the mouse,

and drag the sides of the selected object. So, the thickness of
the object will increase.

e.
● Vertex selection Extrude
a. First object in blender

b. Select vertex section at the bottom of blender

7
c. Next, select the vertex of the object that is available on your
worksheet. for selecting an object angle (vertex), do it by right

click on the mouse.

● Edge selection Extrude


a. First object in the blender

8
b. Select the edge at the bottom on the blender

c. Next, select the edge section in the object that is available on


your worksheet. For selecting the object side, do it by right click

on the mouse.

1. Edge Loop
For adding an edge to an object in the blender, you can do it by using
edge loops feature which can added automatically based on the size
of the cutting edge.

9
a. Still in the same object before. Move to Edit Mode

b. Press CTRL+R on the keyboard, and select the object. It will show a

purple edge line vertically or horizontally


c. For increase the number of edges, it can by using the scroll on the

mouse

10
d. Left click on the mouse for stopping the looping edge. If clicked once,
the loop object can still move anywhere. So, double click on the
mouse to keep the loop object and it will not moving anymore.

2. Scale
For doing scale, it can be do by the shortcuts “S” on the keyboard.
The function of the scale is change the size of an object, either for zoom
in or out.

a. Scale (S) with Z

By pressing S and Z, so the object will be bigger or smaller at the


top or bottom

11
b. Scale with Y

There are many steps for doing scale command. For the steps below will
explain another shortcuts function

3. Rotate
Rotate in the blender is rotate the object that has been selected. So
that is changes angle and facing the direction that we want. The rotate
menu can be found in the shelf tool. If the shle fool is not found, so press
“T” to bring up the shelf tool.

In addition, the rotate command can be done using a shortcut on the


blender by pressing "R".

First object :

12
After rotated :

13
PART II
Character Modelling
2.1 Character Model Sheet

before entering the modeling phase it is recommended to create a


character model sheet first to facilitate the 3D modeling process. In
visual arts, a Character model sheet, also known as a character board,
character sheet, character study or simply a study, is a document used
to help standardize the appearance, poses, and gestures of a character
in arts such as animation, comics, and video games.

IMG 1 Character Model Sheet example

1.3.1 Creating Character Model Sheet

In the process of creating character model Sheet there are


several ways of creating, some use paper as a medium and
some use pen tablets. But in the creating it still uses the same
method. here are some steps that must be done.

1. Prepare the media

Media for creating Character Model Sheets can use paper or


tablet tablets.

14
2. Draw guidelines

This guide line serves as a benchmark for several body parts that
must be parallel, for example the tip of the head, nose, shoulder,
waist and toe.

15
3. Draw objects from several points of view

Images must exist in several points of view, at least 2 angles


from the front and also the side, this is because in 3D modeling there
are 3 axes, namely X, Y and Z, therefore the image must represent
the three angles so that when in the 3D view objects can be seen in
various angles.

2.2 Character Modelling

In this process editing mesh on a 3D object becomes another


desired shape. in blender, the initial form of mesh that is commonly
used for character modeling is Square and Cylinder, the shape will
be formed into the desired object. The steps of character modeling
are as follows.

1. Insert Character Model Sheet Design.

16
A. Insert sheet model by pressing the N key, a new window will
appear on the right, scroll down where images background,
check the checkbox and click open image.

B. Search directory for your character model sheet design image, if


you have found click open image. after that it will look like below.
If the image has not been seen press numpad 1, if it is still not
visible press numpad 5.

17
1. Mesh Modelling
A. Set the camera's perspective to the front view (num 1), move the
square position to the front of the head, adjust it so that the square
midpoint is right in the middle of the face.

B. After the front is right, move to the side press the numpad 3 then
slide the square to the side of the head facing side.

18
2. Face Modelling
A. Enter edit mode (Tab) and return to the front view. To simplify
character modeling, modellers usually use additional features,
namely mirrors to facilitate character processing. With mirror
modifiers, the mesh reflected by the mirror can change to follow the
reflection of the glass according to changes in its reflection. For the
method below.

Add a loopcut (Ctrl+R) at the center of the object that is tangent to


the object's midpoint, and delete the right side of the object.

B. Continue by adding mirror modifiers, in the properties - modifier -


mirror section.

19
IMG 2 Display after adding mirror modifier

C. Continue with the edit mesh, add some of loopcuts(Ctrl + R)


according to the shape of the sheet model. After adding several
loopcuts, edit the front vertex according to the sheet model design.

20
D. Add some additional loopcuts until the mesh shape is the same as
the sheet model's head shape.

E. Continue with the editing process from the right of the object, by
pressing button 3, you will see an object from the right side. Do the
same process as before.

21
F. Just like the front side, do the editing process by shifting the vertex.
Add a number of loops so that the mesh shape is appropriate.

G. If it is formed from the front and side of the head, the mesh will look
like this. Add a few loop cut to make the head arch, so that the head
doesn't look boxed.

22
H. Make a head arch by sliding the most vertex in the corner.

I. Perform the editing process until the mesh shape resembles a


character model sheet..

23
J. If the head is formed, continue with the body editing process. Start
by making the neck first.
3. Body Modelling

A. From the bottom side of the head select a few faces, and extrude
down.

B. Perform the extrude process to the waist, and smooth the vertex.

24
C. Continue by tidying the sides of the body. Add a few loop cut to
smooth the vertex..

D. If you have gone through this process, the mesh will look like this.
Continue by sliding the vertex corner to bend the body.

25
E. The process is continued by making legs, do the same process as
making the neck, which is the extrude face at the base of the foot
down, just like the previous process, trim after extrude until the
results look like below.

F. Continue with the process of making hands.

26
G. When it's finished, the display when we see it in perspective view
will look like this.

27
H. In order for the mesh to look smooth, enter the object mode then
press T and select smooth shading.

I. Add some additional accessories such as adding hair, clothes, pants,


etc. For example, here is an object that has finished the modeling
process.

28
PART III

TEXTURING

3.1 Texture

In computer graphics, textures are the images that we use to


color our models. They can be hand painted in Blender, Photoshop,
or other texturing software, photos from a camera, or a combination
of the two. In this section, I’ll show you how to paint textures directly
onto a model in Blender.

3.2 UV Map

Textures are two dimensional, but our models are three


dimensional. That means we need a way to wrap the images around
our geometry. The most common solution to unwrap our models
(almost like a Christmas present!) and flatten them out. We do this in
what is called UV space. Similar to how X, Y, and Z are our three
dimensions when modeling, U and V are our two dimensions when
texturing. These two separate dimensions allow us to define exactly
how and where we want our textures applied.
In this example, we will unwrap a monkey head so that we can
texture it. Remember how to spit windows from earlier? Just drag
the little triangle lines in the bottom left corner of the 3D View to the
right, and switch the new window to the UV/Image Editor window.

29
If you switch the monkey into Edit Mode, you’ll see a tab in the toolbar
(hotkey T) called Shading/UVs. In the UVs panel is a dropdown list called
Unwrap that will give us different ways to automatically unwrap our model
(hotkey U).

30
For now we’ll just use the first option, which is simply Unwrap. Make sure
everything is selected first (hotkey A), so that Blender will unwrap the whole
object.

On the left you can see that Blender has taken our model and flattened it
out into two dimensions. It has separated the eyes and head into separate
UV islands since they are not actually connected on our model. The
problem now is that the faces which are largest in UV space will have the
most texture detail, but the face, which should have the most detail, is
squished in the middle!
Luckily, we can use seams to tell Blender how we want to lay out our UV’s.
When you hear the word seams, you probably think of shirt or pants
seams. It’s a perfect analogy. The tailor lays out the flat 2D cloth in such
a way that it will wrap into the perfect 3D shape. We’re just doing that
backwards! We separate our 3D shape so that it lays out perfectly in 2D.

To assign seams to a model, select the edges you would like to be separated
and click the Mark Seams button in the toolbar. I selected the edges around
the monkey’s face, so that it will later lay out flat.

31
Once seams are marked, the edges appear as a dashed red line in the 3D
view so that we can see them clearly. I marked a ring around each ear, the
back of the ear, and a line from her forehead to the back of the skull as
well, because those sections do not need to be connected in UV space.
Since textures can sometimes not blend well between seams, it is good
practice to hind them in places that are not easily visible.

32
Now when we press Unwrap, our monkey head lays out much more neatly.
You can see that the edges which were marked as seams have become
unseparated.

Now we can start texturing!

3.3 Texturing process

If you switch from Edit or Object Mode into Texture Paint Mode, you’ll see
that our model is completely pink. That’s because we first need an image to
paint on! When there is a texture missing, Blender displays a bright pink
texture instead, so it is very noticeable. Add a texture by creating a diffuse
color texture slot. Diffuse means the base color of our object.

33
In the popup window that appears, you can rename the texture, set its
resolution, and give it a starting color.

In order to see the new texture on the model, set the 3D viewport shading
to Textured. The lack of shading in Texture Paint mode helps us to see our
textures more accurately, but it does make it hard to see the model clearly.
That’s why I usually enable Ambient Occlusion in the 3D view properties
toolbar (N).

34
Now when we paint, we can see the resulting texture in the UV/Image Editor
to the left.

35
If you’d rather paint on the 2D texture instead of the 3D object, you can do
so by changing the UV/Image Editor to Paint Mode and opening the toolbar
(T) to show the painting tools.

Ready for a challenge? Try to turn Suzanne the monkey into a creepy mime!

36
Once you’ve spent the time making a cool texture, be sure to save it! You
can save it in the UV/Image Editor header under Image -> Save As Image.
To include it within the .blend file itself, choose Image -> Pack Image or Pack
As PNG.

3.4 PROJECT TEXTURING

after understanding the process above, continue with your texturing


project. with the same steps as the above process.

37
PART IV
ANIMATION
Creating 3D objects is fun, but it’s even more awesome to see them move.
Animation is what makes our creations look alive!
4.1 Keyframes
If you’re familiar with traditional hand-drawn animation, you may already
know that animators do not draw every frame in order. They first draw all
of the important or “key” frames first, before filling the in- betweens.

In 3D animation, we only need to set the important frames (called


keyframes), and the software will automatically calculate the in-
betweens. What a time saver!

There are four different ways to set keyframes in Blender, and I’ll show to
how to use each one to animate the default cube.

The first way is to use the hotkey “I” (for Insert keyframe). This will bring
up a list of attributes that can be keyframed.

38
Inserting a location keyframe will only store location data, a rotation
keyframe will only store rotation data, a scaling keyframe will only store
the object’s scale, and so on. You can store all three with the
LocRotScale keyframe.

It’s best to only store the transformations that you need, but more on that
later. For now let’s just insert a location keyframe. Now move to frame 100,
by scrubbing along the timeline or by typing 100 into the frame counter that’s
just left of the playback buttons. You can see that our keyframe is
represented by a yellow tick mark on frame 1.

Now that we’ve told Blender where the cube should be on frame 1, let’s
move the cube to the right on frame 100 and insert another location
keyframe. If you play using the play button or scrub through the timeline,
our cube is now moving!

39
The single arrow play button will play through the animation at normal
speed, the double arrows will jump between keyframes, and the double
arrows hitting the wall will jump to the end or beginning.

We have the cube moving, but let’s add some rotation as well. We’ll do
this by using the keying sets. You can specify which type of data you
would like stored in the keying set dropdown (dropup?). Choose rotation.
Now if you press the key button directly to the right (or press the hotkey
“I”), Blender will add a rotation keyframe. To remove a keyframe, use the
slashed-key button to the right or the hotkey “ALT+I”.
On frame 100, rotate the cube a bit and press “I” again. Since they
keying set is set to rotation only, Blender knows to only insert a
rotation keyframe.

The third way to set a keyframe is again using the “I” hotkey, but on
buttons instead of the 3D view. Almost any setting in Blender can be
animated! If you open the properties toolbar (hotkey “N”), you’ll notice that
the location and rotation transform properties have turned green. This
signifies that they are animated. If they are a bright yellow-green, then
they have a keyframe on the current key.

Let’s animate the cube’s scale with the scale properties. Notice how all
three rotation axes (X,Y, and Z) are animated, even though I only needed

40
it to be rotated on the X. I’ll go back to frame 1. If I press “I” over the scale
properties, it will insert a keyframe for the X, Y, and Z direction. Since I
only want to scale the cube in the Z direction, I’ll right click on the Z scale
and press “Insert Single Keyframes”.

Now increase the Z value to 5 (notice how the transform properties are
local) on frame 100 and insert another single keyframe. The below
images show the change between frame 1 and 100.

41
The last way to insert keyframes is with automatic keying. I don’t
recommend using this all the time because it’s easy to accidentally
override what you already have, but it can be helpful to quickly block out
poses. It will automatically insert any change you make. You can activate
auto-keying by toggling the red record button to the left of the keying
sets. The second key toggle that appears when auto- keying is turned on
will allow you to only auto-key changes that are part of your active keying
set (like rotation, scale, etc…).

With auto-keying on, go to frame 50 and drag the cube upwards.


Blender will automatically add a location keyframe for you! Just
remember to turn auto-keying off when you’re finished so you don’t
accidentally overwrite your animation.

4.2 Bone Deformation Animation


Rigging is a technique used in Bone deformation Animation for
representing a 3D character model using a series of interconnected
digital bones.
Specifically, rigging refers to the process of creating the bone structure of
a 3D model. This bone structure is used to manipulate the 3D model like
a puppet for animation.

42
Pretty much anything can be rigged. A space ship, a soldier, a galaxy, a
door, it doesn’t make any difference what the object is. Adding bones will
allow any object to be animated freely.
Rigging is most common in animated characters for games and movies.
This technique simplifies the animation process and improves production
efficiency. Once rigged with skeletal bones, any 3D object can be
controlled and distorted as needed.
In the entertainment industry rigging is a major step in the standard way
of animating characters. Achieving smooth and complex animations is
entirely dependent on the quality of the rigging phase in the animation
pipeline.
4.2.1 Rigging Process.
Step 1
Open a new file and import your project (File > Import.) You can use any
other biped model as well. Right click and select the model, press Alt+G to
clear its location, so that it is placed at the center. With the model
selected, press Shift+S and then select "Cursor to Selected" to bring the
3D cursor to the origin of the model. Whenever we add a new object, it
appears wherever the cursor is. Don't worry if your model's center point is
at the bottom near the feet unlike in this tutorial.

Step 2
Press Shift+A and add an Armature Object. Press Z and you can view the
object inside.

43
Step 3
To make the armature visible in shaded view mode, click on the Armatures
Tab, in the Display Panel turn on X ray. This will enable us to see
armatures through the model. You can also rename your new armature
object.

44
Step 4
Press 3 on the Numpad to get into the sideview. With the Armature object
selected, press TAB to enter into Edit mode. Just as an object's geometry
is edited with the TAB key, armature object's bones can also be edited
with the TAB key (edit mode.) In edit mode, select the bone by Right
clicking and move it a ways back as shown below.

Rotate it 90 degrees so that the tip of the bone is inside the body. Place
the bone just around the waist line. Remember that we are in edit mode to
do all the editing.

45
Step 5
Now before going further we must understand the direction of rotation for
the bones in human body. All the bones from the lower back to head have
the rotation center (pivot point) at their base (bottom.) Also the top bone is
the child of the lower bone e.g. the head is the child of neck, which is
further a child of the chest and so on.

This means if we rotate or move the lower bone, its child will also be
affected. However if we move or rotate a child bone, the parent bone is not
affected. The direction of flow is downwards from the pelvis to the feet. So
the bone we just created is the parent most bone from which bones for
both direction will be extruded. The image below is just for understanding,
you don't have to recreate this.

46
Step 6
Now we'll get back to our armature. In Edit mode, select the tip of the bone
with Right-click. Press E to extrude
a bone.

Step 7
Extrude again a few times for chest, neck and finally for the head.

47
We have the bones on a little bit of angle in the side view, but in the front
view we can see that they are in a straight line.

Step 8
Select the tip of the first bone again and extrude a bone downwards.

48
Step 9
Now we must rename all the bones. Select a bone (in the edit mode) and
click on the Bone properties and then rename it. Do it for all bones - pelvis,
stomach, chest, neck and head. For the first bone I have named it Base.

Optional: To see the names in the 3D view, open the armature properties
and under the display panel click on Names.

49
Step 10
In the front view click on the origin of leg to place the 3D cursor. Now
press Shift A and automatically a new bone is added. We are still in the
edit mode. Save your file.

Step 11
Select the tip of the new bone and press G to grab it down to the knee.

50
Step 12
Press E again to extrude another bone to the ankle. Make sure the two leg
bones are not in a straight line, rather they should be little bit angled or
bent.

Step 13
Extrude a bone for the foot and another for the toe.

51
Step 14
Now right click on the thigh bone to select it. In the Bone properties
toolbar, rename the bone to thigh.l with a .L extension. This way blender
will recognize the bone as left or right, making it easy for posing and
editing in mirror symmetry later.

Similarly name the rest of the bones with anything you like but with a .L
extension - lowerleg.l, foot.l and finally toe.l.

52
Step 15
Select the thigh.l bone and in the Bone properties toolbar, under the
Relations panel, set Parent to the pelvis bone. Now the thigh bone is a
child of the pelvis bone. Make sure the Connected check box is
unchecked, as we don't want these bones to be connected together, just
follow the parent-child relationship. Alternatively you can parent it with the
Ctrl+P command. Select the thigh bone first and then the pelvis and press
Ctrl+P to make it a parent. Select keep offset when asked.

53
Step 16
Press 1 on the numpad to get into the Front view. Left-click on the left side
of the chest, just below the neck, on a point where you want to start the
collar bone.

54
Press Shift+A to create a bone.

55
Select the tip of the new bone and press G to move it right on the
shoulder.

Step 17
Now extrude out a bone to the elbow, and then again until the palm.

56
Check the alignment in the top view as well.

Step 18
In the Bone properties, rename all the new bones with anything you want,
but with a .L extension. I have named them - collar.l, upperarm.l and
lowerarm.l

57
Step 19
Select the collar.L bone and in the Bone properties set the Chest bone as
its parent. This way it will follow the chest bone.

Step 20
Now extrude out the palm from the lower arm bone.

58
Step 21
Press E again to extrude out the finger bones three times.

Step 22
Now select all the Finger bones while holding Shift and then right clicking
them individually, or by using the B key and drag selecting all of them.
Press Shift+D to duplicate the set and move the mouse to place them on

59
another finger. Adjust the tips to match the finger joints. Duplicate the set
again for the rest of the fingers.

You will notice that the new duplicated sets are already a child of the palm
bone, as the first finger set was the child from which we duplicated the
new ones. Check from the side view also.

Step 23
Rename all the new bones with a .L extension. (Palm.l, f1.l etc...)

60
Step 25
Now we have finished setting up all the basic deforming bones for left
side. We will duplicate and mirror these for the right side. Press TAB to
exit edit mode. With the Armature object selected, press Shift+S and
select 'Cursor to Selected'. This will bring the 3D cursor to the origin point
of the object that is the center of the armature.

61
Step 26
With the Armature object selected, press TAB again to enter into Edit
mode. Select all the left bones (press B to drag select or hold Shift and
then Right click for multiple select.) Make sure you don't select any center
bones or leave out any of the .L bones.

Step 27
Press Shift+D to make a duplicate, Right-click anywhere to confirm the
default position of the new bones. The new bones will be sharing the same
position with the old bones. Also the new bones will be the selected ones
now.

62
Step 28
In the Header of 3D view (at the bottom), change the Pivot point to 3D
cursor. This will make the 3D cursor the center of deformations like
Rotation and Scaling, etc... You can also do this with the keyboard by
pressing the . (period) key.

Step 29
Click on the Armature Menu, go to Mirror and then finally click on X Local.
The duplicated bones will be mirrored with the 3D cursor being the center
point of rotation.

63
Step 30
You will notice that the new bones have a .l.001, .l.002...extension. Press
W and click on Flip Names. This will replace the .l.001 to .r (right). To
toggle view names on or off, check or uncheck 'Names' in the Armature
properties panel.

64
We now have all the deforming bones setup complete.

Press CTRL+TAB to enter into Pose mode (or select Pose mode from the
header bar.) Right-click on any bone and press R to rotate any bone and

65
see some action. You will see that by rotating a parent bone, all the child
bones get affected. Similarly rotating or moving the first bone (base) we
created, will effect the complete structure. Select all the bones with the A
key in the Pose mode, and press Alt+G to reset the bone's position to
default. Press Alt+R to reset the bone's rotation to default.

Step 31
Press TAB to exit Edit mode. If you are in Pose mode, then press Ctrl+TAB
to switch to Object mode (or select the mode in the header.)

66
Step 32

Now Right-click on the model to select it first, and then hold the Shift key
and Right-click on the armature object. Press Ctrl+P to make it (Armature -
the object which is selected last) a parent. Choose the 'With Automatic
Weights' option. This way Blender will automatically assign vertices of the
model to the respective bones according to the bone weight and
placement.

Right-click only on the Armature to selected it, press Ctrl+Tab to enter into
Pose mode. Play around by Rotating the bones, you'll see that the mesh
now deforms along the bones.

67
Part 5
UNITY, VUFORIA AND GAME DESIGN

Game Design is an act of designing game from its title to completed product. Game
design can be done by a single individual or a set of team. Game Design usually
be execute in early phase of game developing. Depending on a person or team
performances, it may resulting a well-designed game. A well designed game can
smooth up the development process and may boost game quality.

Figure 1 Game Development Life Cycle

One of the most central parts of game design is crafting game mechanics; these
are individual actions (or systems of actions) within a game. The mechanics in a
game are often set up by its rules, whereas the challenges in a game generally
come from applying the mechanics to specific situations. For example, walking
around the game is a mechanic, whereas a maze is a kind of challenge based on
that mechanic.

Every game designer or game theorist has their own taxonomy of mechanics, there
is no one Universal Specification, best we can do is find as much as we can then
pull a conclusion based on our research.

Game Mechanics should explain things such as:

● What the entities are there in a game (player character, enemy,


environment, etc.)

68
● What game-relevant state do they have (position, direction, hit point,
status parameter, etc.)
● What actions can they perform and when do they perform said Action
(Enemy will ‘attack’ player at one second interval, player may ‘harm’
enemy using ‘attack’. Attack can be done by tapping the screen.)
● How do these entities interact with each other (if attack connect to
target, the target lose some hit-points.)
● What actions can the player perform to affect the behavior of entities
(by tapping the screen player can command player-character to attack
enemy.)
● What are the win-conditions or lose conditions (When player hit points
reach zero the gameplay ends, when all enemies are removed from
scene, the player wins.)

Points, money, achievement can be part of mechanics if they affect something


(Points used to upgrade certain parts of character, Money used to purchase items,
etc.) However, consider removing them if they do not serve a purpose.

Now let talk about part that may do not belong to game mechanics:

● The controls. The game mechanics explain what commands the player
can give, but not how the player gives said commands. The controls
heavily affect the way the player plays a game, because the player will
usually prefer to give those commands which are easy to give. When
the player can command their character to perform a kick by pressing
B and a super-kick by pressing up-down-left-left-right-B, they will
usually prefer using the normal kick when sufficient because it is simpler
to do. Note that in highly competitive gaming, the controls can actually
bleed into the game mechanics because they put an additional
limitation on how fast certain actions can be performed. At a very high
competition level, some real-time strategy players feel like the entity
they control directly are not actually their units but rather their mouse
cursor.
● The presentation. To be able to interact with the game, the player needs
to be made aware of what is happening. The presentation is what the
player sees on the screen and what they hear over their speakers. The
presentation can also affect how the player plays the game without

69
actually changing the game mechanics. The player will usually pay
most attention to those game events the presentation makes them most
aware of and behave accordingly. For example, when you would still
want the player to use the super-kick more often, have the presentation
acknowledge their success at performing it correctly by accompanying
it with a flashy graphic effect, a satisfying sound effect and when they
do it the first time, give them an achievement "Congratulation! You did
a Super Kick!" presented in big letters in the center of the screen with
fireworks around them.

The next phase after designing game, is team building, where project manager
group up individual with same skill set to perform assigned task. Some group will
perform programming-based task, animation-based task, or asset-creating task.
It’s up to project manager how he/she split the team, As long as it deliver the
desired result.

After the game is designed, and team are assembled, then the developing or
production cycle may be performed. The developing process may be accomplish
on various software, however, for actual game developing, the process usually
performed on Game Engine. For this tutorial, Unity will selected as Game Engine,
since Unity is free, fairly easy to use and quite powerful.

All of asset output (image,


sound, 3D model, etc) will be
handled in game engine to
create the designed game

Figure 2 The Game Engine

70
Figure 3 Unity Interface

1. The Project Window displays library of assets that are available to use
in project. When import assets into the project, they appear here.
2. The Game View is rendered from the Camera(s) in game. It is
representative of final, published game. It is needed to use one or more
Cameras to control what the player actually sees when they are playing
the game.
3. The Hierarchy Window is a hierarchical text representation of every
object in the scene. Each item in the scene has an entry in the
hierarchy, so the two windows are inherently linked. The hierarchy
reveals the structure of how objects are attached to one another.
4. The Scene View allows visually navigate and edit the scene. The scene
view can show a 3D or 2D perspective, depending on the type of project
that currently working on.
5. The Inspector Window allows to view and edit all the properties of the
currently selected object. Because different types of objects have
different sets of properties, the layout and contents of the inspector
window will vary.

71
6. The Toolbar provides access to the most essential working features.
On the left it contains the basic tools for manipulating the scene view
and the objects within it. In the center are the play, pause and step
controls. The buttons to the right give access to Unity Cloud Services
and Unity Account, followed by a layer visibility menu, and finally the
editor layout menu (which provides some alternate layouts for the editor
windows, and allows to save user own custom layouts). The toolbar is
not a window, and is the only part of the Unity interface that can’t
rearrange.

One of the ways to develop an Augmented Reality game in Unity is Using Vuforia
Engine.

Figure 4 Adding vuforia module to Unity Editor

After integrating Vuforia AR Support in Unity, the next step is to get license key to
develop application and create database that store image as marker in Augmented
Reality.

72
Figure 5 Vuforia Quick Tutorial to get License Key

Figure 6 Vuforia's Marker Database

73
After done with Vuforia target, and development key. Then let’s create Unity
Project.

Figure 7 Create Project

74
Part 6
THE ART OF ASSETS AND PLAYER INTERFACES

First, let’s setup the Augmented Reality (AR) Camera. Adding AR Camera will
make Unity to import Vuforia Module to Project.

Figure 8 Integrating Vuforia Engine

Figure 9 Finalizing Integrating

75
6.1. Working With Assets
Asset is a representation of any item that can used in game or Project. An Asset
may come from a file created outside of Unity, such as a 3D Model, an
audio file, an image, or any of the other file types that Unity supports. There
are also some Asset types that created in Unity, such as a ProBuilder Mesh,
an Animator Controller, an Audio Mixer, or a Render Texture.

Figure 10 Asset workflow

There are also another type Asset called Asset Packages. Asset packages
are collections of files and data from Unity Projects, or elements of Projects,
which are compressed and stored in one file, similar to zip files. Like zip
files, an Asset package maintains its original directory structure when it is
unpacked, as well as metadata about Assets (such as import settings and
links to other Assets).

In Unity, the Assets menu option Export Package compresses and stores
the collection, while Import Package unpacks the collection into your
currently open Unity Project.

Adding Asset into Unity can be done by simply drag and drop targeted asset
into project window in Unity.

Now, let’s try import some Asset packages. Find the corresponding Asset
packages in the folder that provided by speaker.

76
Figure 11 Importing Asset Package

Depending on Asset size, importing process may take quite time. After
completing import Asset package, then create a new folder called
Resources, this folder will hold all asset that imported in Unity. Make sure
that new asset goes inside this folder (Except the vuforia folder, do not
touch the vuforia folder, let it be). Drag and drop all folder that created when
import Asset Packages into Resources folder, also drag and drop Scene
folder too. Then let’s create new Scene.

77
Figure 12 Create New Scene

Scenes contain the environments and menus of the game. Think of each
unique Scene file as a unique level. In each Scene, you place your
environments, obstacles, and decorations, essentially designing and
building the game in pieces.

6.2. Player Interface

Now let’s building our Main Menu scene. Double click the Main Menu scene
in scene folder will bring up the corresponding scene. This scene will be
the first to show up (after Splash Screen) when player boot up our game.
To easily building the main menu scene, let us use the UI System in Unity.

78
Figure 13 Adding a Canvas

Figure 14 Adding text GameObject

79
Figure 15 Adding a Button

Figure 16 The Main Menu

80
6.3. Shaping the Assets
Don’t forget to save regularly. After designing the UI now let’s move to next
scene. Open up the ‘SampleScenes’ or the default Scene that created
when first initializing project. Now proceed to create gameplay scene.
First, let add some gameobject as character and the enemy (mob).

Figure 17 Adding Character Game Object

Notice when creating a UI element (Canvas, Button, Text, etc.) they have
different kind of Transform component from normal Gameobject, when
normal GameObject have Transform component, the UI element have
Rect Transform. Both of them serve the same purpose. The Transform
component represent a single point, where Rect Transform represent a
rectangle that a UI element can be placed inside.

At this moment, our character rendered like this:

81
Figure 18 Vanilla Character

However, fret not, we can give him a proper armor fit for a knight.

Figure 19 Adding material textures

82
Figure 20 Add Material to gameobject

Now proceed to adding animation to our lovely knight. For a game project,
a simple character may have animations consist of idle animation, attack
animation, dead animation, spawn animation, damaged animation, and
many more. Depends on the game design, a simple character may consist
more complex animation than mentioned above.

83
6.4. Unity Animation Workflow

Figure 21 Animation Workflow

Unity’s animation system is based on the concept of Animation Clips,


which contain information about how certain objects should change their
position, rotation, or other properties over time. Each clip can be thought of
as a single linear recording. Animation clips from external sources are
created by artists or animators with 3rd party tools such as Autodesk® 3ds
Max® or Autodesk® Maya®, or come from motion capture studios or other
sources.

Animation Clips are then organized into a structured flowchart-like system


called an Animator Controller. The Animator Controller acts as a “State
Machine” which keeps track of which clip should currently be playing, and
when the animations should change or blend together.

A very simple Animator Controller might only contain one or two clips, for
example to control a power-up spinning and bouncing, or to animate a door
opening and closing at the correct time. A more advanced Animator
Controller might contain dozens of humanoid animations for all the main
character’s actions, and might blend between multiple clips at the same
time to provide a fluid motion as the player moves around the scene.

Unity’s Animation system also has numerous special features for handling
humanoid characters which give you the ability to retarget humanoid

84
animation from any source (for example: motion capture; the Asset Store;
or some other third-party animation library) to your own character model,
as well as adjusting muscle definitions. These special features are enabled
by Unity’s Avatar system, where humanoid characters are mapped to a
common internal format.

Each of these pieces - the Animation Clips, the Animator Controller, and
the Avatar, are brought together on a GameObject via the Animator
Component. This component has a reference to an Animator Controller,
and (if required) the Avatar for this model. The Animator Controller, in turn,
contains the references to the Animation Clips it uses.

Now let proceed to create Animator Controller for our knight, adding
Animation Clip on it, and finally assign Animator Controller to knight
Animation Component.

Figure 22 Create and Assign Animator Controller

85
Figure 23 Activate Animator View

86
87
88
Figure 24 Unity Animation Quick Guide

After done with knight Animation, proceed to create a prefab for Knight.
Unity’s Prefab system allows you to create, configure, and store a
GameObject complete with all its components, property values, and child
GameObjects as a reusable Asset. The Prefab Asset acts as a template
from which you can create new Prefab instances in the Scene.

When you want to reuse a GameObject configured in a particular way – like


a non-player character (NPC), prop or piece of scenery – in multiple places
in your Scene, or across multiple Scenes in your Project, you should
convert it to a Prefab. This is better than simply copying and pasting the
GameObject, because the Prefab system allows you to automatically keep
all the copies in sync.

Any edits that you make to a Prefab Asset are automatically reflected in the
instances of that Prefab, allowing you to easily make broad changes across
your whole Project without having to repeatedly make the same edit to
every copy of the Asset.

You can nest Prefabs inside other Prefabs to create complex hierarchies of
objects that are easy to edit at multiple levels. However, this does not mean

89
all Prefab instances have to be identical. You can override settings on
individual prefab instances if you want some instances of a Prefab to differ
from others. You can also create variants of Prefabs which allow you to
group a set of overrides together into a meaningful variation of a Prefab.

You should also use Prefabs when you want to instantiate GameObjects at
runtime that did not exist in your Scene at the start - for example, to make
powerups, special effects, projectiles, or NPCs appear at the right moments
during gameplay.

Some common examples of Prefab use include:

● Environmental Assets - for example a certain type of tree used


multiple times around a level.
● Non-player characters (NPCs) - for example a certain type of robot
may appear in your game multiple times, across multiple levels.
They may differ (using overrides) in the speed they move, or the
sound they make.
● Projectiles - for example a pirate’s cannon might instantiate a
cannonball Prefab each time it is fired.
● The player’s main character - the player prefab might be placed at
the starting point on each level (separate Scenes) of your game.

To create Knight prefab, first create a new GameOject by right click at


hierarchy -> Create Empty, this will spawn a empty GameObject with only
Transform as component, Rename it as “KnightPrefab” or something
related to knight game object. Make sure the “KnightPrefab” gameObject
has position of zero (0,0,0 in position and 0,0,0 in Rotation at Transform
component), then drag the knight gameobject into “KnightPrefab”
gameobject, reset the Transform value of knight gameobject (Position to
0,0,0 and Rotation to 0,0,0). After that, drag the “KnightPrefab” into folder
called Prefab inside Resources folder, if the folder is not present, please
create one. By dragging the “KnightPrefab” into Prefab we successfully
create a Prefab for “KnightPrefab” and ending our simple character
creation. However, we need to create more character serves as Punching
bag Enemy for our Character (Knight). Surely it much easier to create by
oneself when there is blatant explanation exist somewhere within this book,
right?

90
Figure 25 Knight, Dragon, and Wasp

91
6.5. Gameplay Interface
First, please create a new canvas then design the interface like this.

Figure 26 Gameplay UI Design

Figure 27 HP

92
Figure 28 Pause Menu

93
Part 7
BUILDING THE MECHANICS, PROGRAMMING THE GAME

Now let’s talk about our Clicker-Augmented Reality hybrid game mechanics.
● The Player
o The player-character has access to two kind of attack function,
the auto-attack and Tap attack. The auto-attack allow player to
execute attack at given interval, while Tap attack let player
attack when the screen detect an input from player (Tap).
o The player-character has unique behavior when comes to
spawn, player may spawn character when the Augmented
Reality Camera detect the marker. However if character is
present, the spawn will not executed.
o Player has hit points (HP), HP reduced to certain value when
receive attack from enemies. When HP value reach 0 (Zero) the
player cease to exist (dead) and receive a penalty (reduction of
current points/money). You can respawn the character with
spawn function.
o Player gain points/money when successfully slain enemy.
o Player has privilege to increase some of his defining parameter,
like HP, Tap Attack and Auto Attack. However it need certain
value of point/money to be able to access that.
● Enemies
o Enemy comes one by one, so as long as current enemy is not
defeated yet, the next one may wait till his turn.
o Enemy spawn randomly from enemy pool, so expect to defeat
a same enemy at dozen times.
o Like player, enemy has attack function, however, it does not
possess the tap Attack.
o Enemy does not have upgrade function nor receive point when
defeated player.

Below we will presented all code that we programmed and used in this game,
you may write it down in unity, However, it deeply advised to take your time to
digest the code, since there is high probability you aren’t familiar with it, but

94
when it does we glad to hear that. After that let’s will try to breakdown the code
and explain it. Let us begin.

7.1. MobData.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4.
5. [CreateAssetMenu(fileName = "NewMob", menuName = "Data/Mob/Create
New Mob")]
6. public class MobData : ScriptableObject
7. {
8. public string MobName;
9. public string MobModel;
10. public float Hp;
11. public float Attack;
12. public int DropMoneyValue;
13. }

7.2. HeroData.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4.
5. [CreateAssetMenu(fileName ="NewHero", menuName ="Data/Hero/Create
New Hero")]
6. public class HeroData :ScriptableObject
7. {
8. public string HeroName;
9. public string HeroModel;
10. public string ParticleCircleModel;
11. public float Hp;
12. public float Attack;
13. }

7.3. Singleton.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4.
5. public class Singleton<T> : MonoBehaviour where T : MonoBehaviour

6. {
7. // Check to see if we're about to be destroyed.
8. private static bool m_ShuttingDown = false;
9. private static object m_Lock = new object();
10. private static T m_Instance;
11.
12. /// <summary>
13. /// Access singleton instance through this propriety.
14. /// </summary>

95
15. public static T Instance
16. {
17. get
18. {
19. if (m_ShuttingDown)
20. {
21. Debug.LogWarning("[Singleton] Instance '" + typeof
(T) +
22. "' already destroyed. Returning null.");
23. return null;
24. }
25.
26. lock (m_Lock)
27. {
28. if (m_Instance == null)
29. {
30. // Search for existing instance.
31. m_Instance = (T)FindObjectOfType(typeof(T));
32.
33. // Create new instance if one doesn't already
exist.
34. if (m_Instance == null)
35. {
36. // Need to create a new GameObject to atta
ch the singleton to.
37. var singletonObject = new GameObject();
38. m_Instance = singletonObject.AddComponent<
T>();
39. singletonObject.name = typeof(T).ToString(
) + " (Singleton)";
40.
41. // Make instance persistent.
42. DontDestroyOnLoad(singletonObject);
43. }
44. }
45.
46. return m_Instance;
47. }
48. }
49. }
50.
51. private void OnApplicationQuit()
52. {
53. m_ShuttingDown = true;
54. }
55.
56. private void OnDestroy()
57. {
58. m_ShuttingDown = true;
59. }
60. }

7.4. SceneHandler.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4. using UnityEngine.SceneManagement;
5.

96
6. public class SceneHandler : MonoBehaviour
7. {
8. public CanvasGroup MainCanvas;
9. public CanvasGroup PauseCanvas;
10.
11. public void ChangeScene(string name)
12. {
13. if (name.Equals("MainMenu"))
14. {
15. ResetProgress();
16. }
17. Time.timeScale = 1f;
18. SceneManager.LoadSceneAsync(name);
19. }
20.
21. public void ExitGame()
22. {
23. Application.Quit();
24. }
25.
26. public void PauseGame()
27. {
28. Time.timeScale = 0f;
29. CanvasGroupSettings(MainCanvas, 0, false, false);
30. CanvasGroupSettings(PauseCanvas, 1, true, true);
31. }
32.
33. public void ResumeGame()
34. {
35. Time.timeScale = 1f;
36. CanvasGroupSettings(PauseCanvas, 0, false, false);
37. CanvasGroupSettings(MainCanvas, 1, true, true);
38. }
39.
40. void CanvasGroupSettings(CanvasGroup cg, float a, bool interac
t, bool raycast)
41. {
42. cg.alpha = a;
43. cg.interactable = interact;
44. cg.blocksRaycasts = raycast;
45. }
46.
47. void ResetProgress()
48. {
49. PlayerManager.Instance.CurHero = null;
50. PlayerManager.Instance.CurMob = null;
51. PlayerManager.Instance.AtkCost = 10f;
52. PlayerManager.Instance.DpsCost = 10f;
53. PlayerManager.Instance.HpCost = 10f;
54. PlayerManager.Instance.UpAtk = 0;
55. PlayerManager.Instance.UpDps = 0;
56. PlayerManager.Instance.UpHp = 0;
57. PlayerManager.Instance.ReduceMoneyToVal(0);
58. }
59. }

97
7.5. PlayerManager.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4. using UnityEngine.SceneManagement;
5. using System.Linq;
6.
7. public class PlayerManager : Singleton<PlayerManager>
8. {
9. protected List<HeroData> Heroes;
10. protected List<MobData> Mobs;
11.
12. public GameObject CurMob;
13. public GameObject CurHero;
14. protected int _GainMoney;
15. protected int _TotalMoney;
16. protected string _SummonedHeroName;
17.
18. protected float _UpAtk;
19. protected float _UpHp;
20. protected float _UpDps;
21.
22. protected float _AtkCost;
23. protected float _HpCost;
24. protected float _DpsCost;
25.
26. #region Encapsulation
27. public int GetTotalMoney
28. {
29. get
30. {
31. return _TotalMoney;
32. }
33. }
34.
35. public void setTotalMoney(int val)
36. {
37. _TotalMoney += val;
38. }
39.
40. public void ReduceMoneyToVal(int val)
41. {
42. _TotalMoney = val;
43. }
44.
45. public int GainMoney
46. {
47. get
48. {
49. return _GainMoney;
50. }
51.
52. set
53. {
54. _GainMoney = value;
55. }
56. }
57.
58. public string SummonedHeroName

98
59. {
60. get
61. {
62. return _SummonedHeroName;
63. }
64.
65. set
66. {
67. _SummonedHeroName = value;
68. }
69. }
70.
71. public float UpAtk
72. {
73. get
74. {
75. return _UpAtk;
76. }
77.
78. set
79. {
80. _UpAtk = value;
81. }
82. }
83.
84. public float UpHp
85. {
86. get
87. {
88. return _UpHp;
89. }
90.
91. set
92. {
93. _UpHp = value;
94. }
95. }
96.
97. public float UpDps
98. {
99. get
100. {
101. return _UpDps;
102. }
103.
104. set
105. {
106. _UpDps = value;
107. }
108. }
109.
110. public float AtkCost
111. {
112. get
113. {
114. return _AtkCost;
115. }
116. set
117. {
118. _AtkCost = value;
119. }

99
120. }
121.
122. public float HpCost
123. {
124. get
125. {
126. return _HpCost;
127. }
128. set
129. {
130. _HpCost = value;
131. }
132. }
133.
134. public float DpsCost
135. {
136. get
137. {
138. return _DpsCost;
139. }
140. set
141. {
142. _DpsCost = value;
143. }
144. }
145. #endregion
146.
147. public void InitHero()
148. {
149. Heroes = new List<HeroData>();
150. var _heroes = Resources.LoadAll<HeroData>("Data/Hero");
151. foreach (HeroData hero in _heroes)
152. {
153. Heroes.Add(hero);
154. }
155. AtkCost = 10f;
156. DpsCost = 10f;
157. HpCost = 10f;
158. }
159.
160. public void InitMobs()
161. {
162. Mobs = new List<MobData>();
163. var m = Resources.LoadAll<MobData>("Data/Mob");
164. foreach (MobData mob in m)
165. {
166. Mobs.Add(mob);
167. }
168. }
169.
170. public MobData GetMob(string name)
171. {
172. return Mobs.Find(x => x.MobName == name);
173. }
174.
175. public HeroData GetHero(string name)
176. {
177. return Heroes.Find(x => x.HeroName == name);
178. }
179.
180. public MobData GetRandomizedMob()

100
181. {
182. MobData mob = null;
183. int rand = Random.Range(0, Mobs.Count);
184. mob = Mobs[rand];
185. return mob;
186. }
187. }

7.6. SummonHeroHandler.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4. using Vuforia;
5.
6.
7. public class SummonHeroHandler : DefaultTrackableEventHandler
8. {
9. public HeroData SummonedHero;
10. protected GameObject Hero;
11. public Transform HeroSpawnTransform;
12. public Transform HitParticleSpawn;
13. string curNameTracked;
14.
15. //Particle prefab;
16. GameObject MagicRing;
17. GameObject ActiveHitParticles;
18. public GameObject HitPrefab;
19.
20. public delegate void InitParameterHero();
21. public static event InitParameterHero InitHeroParameter;
22.
23. void Awake()
24. {
25. PlayerManager.Instance.InitHero();
26. }
27.
28. protected override void OnDestroy()
29. {
30. Hero = null;
31. StopAllCoroutines();
32. }
33.
34. public GameObject getActiveHero
35. {
36. get
37. {
38. return Hero;
39. }
40. }
41.
42. protected override void OnTrackingFound()
43. {
44. base.OnTrackingFound();
45. curNameTracked = GetTrackableObject.TrackableName;
46. SummonedHero = PlayerManager.Instance.GetHero(curNameTrack
ed);
47. if (Hero == null)
48. {

101
49. SpawnHero();
50. }
51. }
52.
53. #region Hero Behaviour
54. void SpawnHero()
55. {
56. var model = Resources.Load<GameObject>(SummonedHero.HeroMo
del);
57. var tempHero = Instantiate(model);
58. tempHero.transform.localPosition = HeroSpawnTransform.posi
tion;
59. tempHero.transform.localRotation = HeroSpawnTransform.rota
tion;
60. Hero = tempHero;
61. //register our newly spawned hero to player manager script

62. PlayerManager.Instance.CurHero = Hero;


63. PlayerManager.Instance.SummonedHeroName = curNameTracked;

64. //register attack function and animation


65. ActiveStageHandler.OnAttack += DoAttack;
66. //register auto attack (same as normal attack)
67. ActiveStageHandler.OnAutoAttack += DoAttack;
68. //register hero dead function
69. ActiveStageHandler.OnHeroDead += InstantKill;
70. InitHeroParameter?.Invoke();
71. //start particle effect, draw summoning circle
72. StartCoroutine(DrawMagicRing());
73. }
74.
75. IEnumerator DrawMagicRing()
76. {
77. if (MagicRing == null)
78. {
79. var ring = Resources.Load<GameObject>(SummonedHero.Par
ticleCircleModel);
80. MagicRing = Instantiate(ring);
81. MagicRing.transform.localPosition = GameObject.FindGam
eObjectWithTag("CircleSpawn").transform.position;
82. MagicRing.transform.localRotation = GameObject.FindGam
eObjectWithTag("CircleSpawn").transform.rotation;
83. yield return new WaitForSeconds(2f);
84. Destroy(MagicRing);
85. yield break;
86. }
87. }
88.
89. void SpawnParticles()
90. {
91. ActiveHitParticles = Instantiate(HitPrefab);
92. ActiveHitParticles.transform.localScale = Vector3.one * 3f
;
93. Vector3 p = PlayerManager.Instance.CurMob.transform.positi
on;
94. ActiveHitParticles.transform.localPosition = new Vector3(p
.x, p.y + 0.5f, p.z - 0.3f);
95. StartParticles();
96. }
97.
98. void StartParticles()

102
99. {
100. ParticleSystem particle = ActiveHitParticles.GetComponent<
ParticleSystem>();
101. particle.Simulate(0.0f, true, true);
102. particle.Play();
103. }
104.
105. public void DoAttack(float val)
106. {
107. if (PlayerManager.Instance.CurMob == null || Hero == null)
return;
108. Hero.GetComponent<Animator>().SetTrigger("Attack");
109. if (ActiveHitParticles == null)
110. {
111. PlayerManager.Instance.CurMob.GetComponent<MobHandler>
().reduceHealth(val);
112. SpawnParticles();
113. }
114. else
115. {
116. PlayerManager.Instance.CurMob.GetComponent<MobHandler>
().reduceHealth(val);
117. StartParticles();
118. }
119. }
120.
121. public void InstantKill()
122. {
123. ActiveStageHandler.OnAttack -= DoAttack;
124. ActiveStageHandler.OnAutoAttack -= DoAttack;
125. ActiveStageHandler.OnHeroDead -= InstantKill;
126. Destroy(Hero, 0.2f);
127. PlayerManager.Instance.CurHero = null;
128. SummonedHero = null;
129. }
130.
131. #endregion
132. }

7.7. MobHandler.cs

1. using System.Collections;
2. using UnityEngine;
3. using UnityEngine.UI;
4. public class MobHandler : MonoBehaviour
5. {
6. protected float Health;
7. protected float MaxHealth;
8. protected int _DropMoney;
9. protected float _Attack;
10. public Animator anim;
11. public Image hpBar;
12. public delegate void DeadMob();
13. public delegate void DealDamage(float val);
14. public static event DeadMob OnDead;
15. public static event DealDamage OnDealDamage;
16.
17. void Start()
18. {

103
19. RegisterHpBar();
20. StartCoroutine(Source());
21. StartCoroutine(DetectHealth());
22. }
23.
24. void Update()
25. {
26. TimeToDie();
27. }
28.
29. void OnDestroy()
30. {
31. Health = 0f;
32. setAttack = 0f;
33. StopAllCoroutines();
34. }
35.
36. public void RegisterHpBar()
37. {
38. var g = GameObject.FindGameObjectWithTag("InnerBarHp");
39. hpBar = g.GetComponent<Image>();
40. }
41.
42. float Conversion(float minBar, float maxBar, float minVal, flo
at maxVal, float CurVal)
43. {
44. return ((CurVal - minVal) * (maxBar - minBar) / (maxVal -
minVal) + minVal);
45. }
46.
47. #region Encapsulation
48. public float getHealth
49. {
50. get
51. {
52. return Health;
53. }
54. }
55.
56. public float setHealth
57. {
58. set
59. {
60. Health = value;
61. }
62. }
63.
64. public int DropMoney
65. {
66. get
67. {
68. return _DropMoney;
69. }
70.
71. set
72. {
73. _DropMoney = value;
74. }
75. }
76.
77. public float getAttack

104
78. {
79. get
80. {
81. return _Attack;
82. }
83. }
84.
85. public float setAttack
86. {
87. set
88. {
89. _Attack = value;
90. }
91.
92. }
93.
94. public float getMaxHealth
95. {
96. get
97. {
98. return MaxHealth;
99. }
100. set
101. {
102. MaxHealth = value;
103. }
104. }
105. #endregion
106.
107. #region Animation
108.
109. public void doAttackAnim()
110. {
111. anim.SetTrigger("Attack");
112. }
113.
114. public void doDamagedAnim()
115. {
116. anim.SetTrigger("Damaged");
117. }
118.
119. public void DoDeadAnim()
120. {
121. anim.SetBool("Dead", true);
122. }
123.
124. #endregion
125.
126. #region Enumerator
127.
128. IEnumerator Source()
129. {
130.
131. while (true)
132. {
133. if (gameObject == null) yield break;
134. if (Health > 0)
135. {
136. yield return new WaitUntil(() => PlayerManager.Ins
tance.CurHero != null);
137. yield return new WaitForSeconds(1f);

105
138. doAttack();
139. }
140. yield return new WaitForSeconds(0.02f);
141. }
142. }
143.
144.
145. IEnumerator DetectHealth()
146. {
147. while (true)
148. {
149. if (gameObject == null) yield break;
150. float temp = getHealth;
151. float cVal = Conversion(0, 1, 0, MaxHealth, temp);
152. if (hpBar.fillAmount != cVal)
153. {
154. doDamagedAnim();
155. hpBar.fillAmount = cVal;
156. Health = temp;
157. }
158. yield return new WaitForSeconds(0.01f);
159. }
160. }
161.
162. #endregion
163.
164. #region Mob Behaviour
165. public void doAttack()
166. {
167. if (gameObject == null) return;
168. //play enemy attack animation
169. doAttackAnim();
170. //ACTUALLY deal damage to hero
171. OnDealDamage?.Invoke(getAttack);
172. }
173.
174. public void reduceHealth(float val)
175. {
176. if (Health - val > 0)
177. {
178. float temp = Health - val;
179. setHealth = temp;
180. }
181. else
182. {
183. setHealth = 0;
184. }
185. }
186.
187. void DropMoneyToHero()
188. {
189. PlayerManager.Instance.GainMoney = DropMoney;
190. PlayerManager.Instance.setTotalMoney(DropMoney);
191. }
192.
193. void TimeToDie()
194. {
195. if (Health <= 0)
196. {
197. DropMoneyToHero();
198. DoDeadAnim();

106
199. OnDead?.Invoke();
200. }
201. }
202. #endregion
203. }

7.8. ActiveSceneHandler.cs

1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4. using UnityEngine.UI;
5. using UnityEngine.EventSystems;
6. using System;
7.
8. public class ActiveStageHandler : MonoBehaviour
9. {
10. [Header("General Handler")]
11. public Canvas mainCanvas;
12. public Transform MobSpawnPos;
13. public GameObject MobObject;
14. public GameObject ARCam;
15. public GameObject NormalCam;
16. protected MobData curMob;
17.
18. public delegate void AutoAttackFunc(float val);
19. public delegate void AttackFunc(float val);
20. public delegate void DeadFunc();
21. public static event AttackFunc OnAttack;
22. public static event AutoAttackFunc OnAutoAttack;
23. public static event DeadFunc OnHeroDead;
24.
25. [Header("Money Handler")]
26. public Text MoneyText;
27.
28. [Header("Hero Parameter Handler")]
29. public Image hpBar;
30. public Text AtkUpCost;
31. public Text DpsUpCost;
32. public Text HpUpCost;
33. public Text curAtk;
34. public Text curDps;
35. public Text curHp;
36.
37. protected float _HeroHealth;
38. protected float _HeroMaxHealth;
39. protected float _HeroAttack;
40. protected float _HeroDpsAttack;
41.
42. // Start is called before the first frame update
43. void Start()
44. {
45. SummonHeroHandler.InitHeroParameter += InitParameter;
46. PlayerManager.Instance.InitMobs();
47. StartCoroutine(SpawnMob());
48. StartCoroutine(AutoAttack());
49. StartCoroutine(MoneyChangeDetect());
50. StartCoroutine(DetectHealth());
51. }

107
52.
53. void Update()
54. {
55. //handling cost text in GUI, and update Hero parameter aft
er upgrading stats
56. UpdateParameter();
57.
58. // handling clicking / tap attack
59. if (DetectClick())
60. {
61. OnAttack?.Invoke(HeroAttack);
62. }
63. }
64.
65. void OnDestroy()
66. {
67. StopAllCoroutines();
68. }
69.
70. bool DetectClick()
71. {
72. if (!DetectUIElement()) return false;
73.
74. if (Input.GetMouseButtonDown(0))
75. {
76. return true;
77. }
78. else
79. return false;
80. }
81.
82. bool DetectUIElement()
83. {
84. //detect GUI element, this function behave to
85. //make sure hero does not deal damage to enemy when clicki
ng GUI button
86. GraphicRaycaster gr = mainCanvas.GetComponent<GraphicRayca
ster>();
87. EventSystem es = GetComponent<EventSystem>();
88. PointerEventData p = new PointerEventData(es)
89. {
90. position = Input.mousePosition
91. };
92.
93. List<RaycastResult> _res = new List<RaycastResult>();
94.
95. gr.Raycast(p, _res);
96.
97. foreach (RaycastResult r in _res)
98. {
99. if (r.gameObject)
100. {
101. return false;
102. }
103. }
104. return true;
105. }
106.
107. float Conversion(float minBar, float maxBar, float minVal, flo
at maxVal, float CurVal)
108. {

108
109. return ((CurVal - minVal) * (maxBar - minBar) / (maxVal -
minVal) + minVal);
110. }
111.
112. public void SwapCamera()
113. {
114. if (ARCam.activeInHierarchy)
115. {
116. ARCam.SetActive(false);
117. NormalCam.SetActive(true);
118. }
119. else if (!ARCam.activeInHierarchy)
120. {
121. ARCam.SetActive(true);
122. NormalCam.SetActive(false);
123. }
124. }
125.
126. #region Encapsulation
127.
128. public float HeroHealth
129. {
130. get
131. {
132. return _HeroHealth;
133. }
134.
135. set
136. {
137. _HeroHealth = value;
138. }
139. }
140.
141. public float HeroMaxHealth
142. {
143. get
144. {
145. return _HeroMaxHealth;
146. }
147.
148. set
149. {
150. _HeroMaxHealth = value;
151. }
152. }
153.
154. public float HeroAttack
155. {
156. get
157. {
158. return _HeroAttack;
159. }
160.
161. set
162. {
163. _HeroAttack = value;
164. }
165. }
166.
167. public float HeroDps
168. {

109
169. get
170. {
171. return _HeroDpsAttack;
172. }
173.
174. set
175. {
176. _HeroDpsAttack = value;
177. }
178. }
179. #endregion
180.
181. #region Enumerator
182. IEnumerator MoneyChangeDetect()
183. {
184. while (true)
185. {
186. int temp = PlayerManager.Instance.GetTotalMoney;
187. if (int.Parse(MoneyText.text) != temp)
188. {
189. int t = int.Parse(MoneyText.text);
190. if (t > temp)
191. {
192. //we spent our / loss money
193. t -= 1;
194. MoneyText.text = t.ToString();
195. }
196. if (t < temp)
197. {
198. //we gain money
199. t += 1;
200. MoneyText.text = t.ToString();
201. }
202. }
203. yield return new WaitForSeconds(0.0012f);
204. }
205. }
206.
207. IEnumerator DetectHealth()
208. {
209. while (true)
210. {
211. yield return new WaitUntil(() => PlayerManager.Instanc
e.CurHero != null);
212. float temp = HeroHealth;
213. float cVal = Conversion(0, 1, 0, HeroMaxHealth, temp);

214. if (hpBar.fillAmount != cVal)


215. {
216. hpBar.fillAmount = cVal;
217. HeroHealth = temp;
218. }
219. if (temp <= 0)
220. {
221. OnDead();
222. }
223.
224. yield return new WaitForSeconds(0.01f);
225. }
226. }
227.

110
228. IEnumerator SpawnMob()
229. {
230. //function below will execute once. since we will execute
code within looping :>
231. ActualSpawnMob();
232. while (true)
233. {
234. var m = MobObject.GetComponent<MobHandler>();
235. yield return new WaitUntil(() => m.getHealth < 0 || Mo
bObject == null);
236. yield return new WaitForSeconds(0.8f);
237. ActualSpawnMob();
238. }
239. }
240.
241. IEnumerator AutoAttack()
242. {
243. while (true)
244. {
245. OnAutoAttack?.Invoke(HeroDps);
246. yield return new WaitForSeconds(1f);
247. }
248. }
249. #endregion
250.
251. #region Hero Behaviour
252. void InitParameter()
253. {
254. HeroData data = PlayerManager.Instance.GetHero(PlayerManag
er.Instance.SummonedHeroName);
255. HeroDps = data.Attack + PlayerManager.Instance.UpDps;
256. HeroAttack = data.Attack + PlayerManager.Instance.UpAtk;
257. HeroMaxHealth = PlayerManager.Instance.UpHp > 0 ? PlayerMa
nager.Instance.UpHp : data.Hp;
258. HeroHealth = HeroMaxHealth;
259. }
260.
261. void UpdateParameter()
262. {
263. if (PlayerManager.Instance.CurHero == null) return;
264. HeroData data = PlayerManager.Instance.GetHero(PlayerManag
er.Instance.SummonedHeroName);
265. AtkUpCost.text = PlayerManager.Instance.AtkCost.ToString()
;
266. HpUpCost.text = PlayerManager.Instance.HpCost.ToString();

267. DpsUpCost.text = PlayerManager.Instance.DpsCost.ToString()


;
268. curAtk.text = (data.Attack + PlayerManager.Instance.UpAtk)
.ToString();
269. curDps.text = (data.Attack + PlayerManager.Instance.UpDps)
.ToString();
270. curHp.text = HeroMaxHealth.ToString();
271. }
272.
273. public void ReduceHealth(float val)
274. {
275. if (HeroHealth - val > 0)
276. {
277. HeroHealth -= val;
278. }

111
279. else if (HeroHealth - val <= 0)
280. {
281. HeroHealth = 0;
282. }
283. }
284.
285. public void OnReceieveDamage(float val)
286. {
287. ReduceHealth(val);
288. }
289.
290. void DeadPenalty()
291. {
292. int temp = PlayerManager.Instance.GetTotalMoney;
293. int count = (temp * 25 / 100);
294. if (temp - count > 0)
295. {
296. PlayerManager.Instance.setTotalMoney(-count);
297. }
298. else if (temp - count <= 0)
299. {
300. PlayerManager.Instance.setTotalMoney(-temp);
301. }
302. }
303.
304. void OnDead()
305. {
306. HeroAttack = 0;
307. HeroDps = 0;
308. HeroMaxHealth = 0;
309. DeadPenalty();
310. OnHeroDead?.Invoke();
311. }
312. #endregion
313.
314. #region Mob Behaviour
315. void ActualSpawnMob()
316. {
317. if (curMob != null) return;
318. curMob = PlayerManager.Instance.GetRandomizedMob();
319. var t = Resources.Load<GameObject>(curMob.MobModel);
320. GameObject g = Instantiate(t);
321. g.transform.localRotation = MobSpawnPos.rotation;
322. g.transform.localPosition = new Vector3(MobSpawnPos.positi
on.x, MobSpawnPos.position.y - 0.5f, MobSpawnPos.position.z);
323. g.GetComponent<MobHandler>().setHealth = curMob.Hp;
324. g.GetComponent<MobHandler>().getMaxHealth = curMob.Hp;
325. g.GetComponent<MobHandler>().DropMoney = curMob.DropMoneyV
alue;
326. g.GetComponent<MobHandler>().setAttack = curMob.Attack;
327. MobObject = g;
328. PlayerManager.Instance.CurMob = MobObject;
329. MobHandler.OnDead += OnDeadMob;
330. MobHandler.OnDealDamage += OnReceieveDamage;
331. }
332.
333. public void OnDeadMob()
334. {
335. MobHandler.OnDealDamage -= OnReceieveDamage;
336. Destroy(PlayerManager.Instance.CurMob);
337. MobObject = null;

112
338. PlayerManager.Instance.CurMob = null;
339. curMob = null;
340. }
341. #endregion
342. #region Upgrade Parameter
343. public void UpgradeAttack()
344. {
345. if (PlayerManager.Instance.CurHero == null) return;
346.
347. float temp = PlayerManager.Instance.UpAtk;
348. float _cost = PlayerManager.Instance.AtkCost;
349. if (PlayerManager.Instance.GetTotalMoney - _cost >= 0)
350. {
351. temp += 1;
352. PlayerManager.Instance.setTotalMoney(Mathf.FloorToInt(
-_cost));
353. _cost += Mathf.FloorToInt(5 + (_cost * 5f / 100));
354. PlayerManager.Instance.UpAtk = temp;
355. HeroAttack = PlayerManager.Instance.UpAtk;
356. PlayerManager.Instance.AtkCost = _cost;
357. }
358. }
359. public void UpgradeDps()
360. {
361. if (PlayerManager.Instance.CurHero == null) return;
362. float temp = PlayerManager.Instance.UpDps;
363. float _cost = PlayerManager.Instance.DpsCost;
364. if (PlayerManager.Instance.GetTotalMoney - _cost >= 0)
365. {
366. temp += 1;
367. PlayerManager.Instance.setTotalMoney(Mathf.FloorToInt(
-_cost));
368. _cost += Mathf.FloorToInt(50 + (_cost * 35f / 100));
369. PlayerManager.Instance.UpDps = temp;
370. HeroDps = PlayerManager.Instance.UpDps;
371. PlayerManager.Instance.DpsCost = _cost;
372. }
373. }
374. public void UpgrageHp()
375. {
376. //Fully heals hp to maximum and increase max hp by given v
alue
377. if (PlayerManager.Instance.CurHero == null) return;
378. float temp = PlayerManager.Instance.UpHp;
379. float _cost = PlayerManager.Instance.HpCost;
380. if (PlayerManager.Instance.GetTotalMoney - _cost >= 0)
381. {
382. temp = HeroMaxHealth + 10;
383. PlayerManager.Instance.setTotalMoney(Mathf.FloorToInt(
-_cost));
384. _cost += Mathf.FloorToInt(40 + (_cost * 50f / 100));
385. PlayerManager.Instance.UpHp = temp;
386. HeroMaxHealth = PlayerManager.Instance.UpHp;
387. HeroHealth = HeroMaxHealth;
388. PlayerManager.Instance.HpCost = _cost;
389. }
390. }
391. #endregion
392. }

113
Now let’s start the explanation.

● Scriptable Object and Resource Loading


The HeroData.cs and MobData.cs implement Unity’s data container that you can
use to save large amounts of data, independent of class instances. One of
the main use cases for ScriptableObjects is to reduce your Project’s
memory usage by avoiding copies of values. This is useful if your Project
has a Prefab that stores unchanging data in attached MonoBehaviour
scripts. Every time you instantiate that Prefab, it will get its own copy of that
data. Instead of using the method, and storing duplicated data, you can use
a ScriptableObject to store the data and then access it by reference from
all of the Prefabs. This means that there is one copy of the data in memory.

Just like MonoBehaviours, ScriptableObjects derive from the base Unity Object
but, unlike MonoBehaviours, you cannot attach a ScriptableObject to a
GameObject. Instead, you save them as Assets in your Project.

When using the Editor, you can save data to ScriptableObjects while editing and
at run time because ScriptableObjects use the Editor namespace and
Editor scripting. In a deployed build, however, you can’t use
ScriptableObjects to save data, but you can use the saved data from the
ScriptableObject Assets that you set up during development. Data that you
save from Editor Tools to ScriptableObjects as an asset is written to disk
and is therefore persistent between sessions.
HeroData.cs and MobData.cs contain a player-character (hero) parameter
information (hit-points, attack, etc.) and Enemy parameter information. Also
within the code there is a variable that used to store character or enemy
prefabs location inside the resources folder (HeroModel & MobModel).
This variable will become a parameter to Unity Resources.Load function.
The Resources.Load<>() function will allow us to load a file within given
path, and we already store the prefabs of our character in Variable
HeroModel & MobModel. Please note, that we will often use
Resources.Load or Resources.LoadAll in our script when we gonna load
gameobject or file to the scene. The syntax CreateAssetMenu in
HeroData.cs and MobData.cs allow us to create a new scriptableObject file
when right click on project windows.

114
Figure 29 Sciptable Object

● Singleton Pattern of Player Manager


The singleton pattern is a way to ensure a class has only a single globally
accessible instance available at all times. Behaving much like a regular
static class but with some advantages. This is very useful for making global
manager type classes that hold global variables and functions that many
other classes need to access. However, the convenience of the pattern can
easily lead to misuse and abuse and this has made it somewhat
controversial with many critics considered it an anti-pattern that should be
avoided. But like any design pattern, singletons can be very useful in certain
situations and it's ultimately up to the developer to decide if it's right for
them.

Advantages
o Globally accessible. No need to search for or maintain a reference
to the class.
o Persistent data. Can be used to maintain data across scenes.
o Supports interfaces. Static classes cannot implement interfaces.
o Supports inheritance. Static classes cannot inherent for another
class.

115
The advantage of using singletons in Unity, rather than static parameters and
methods, is that static classes are lazy-loaded when they are first
referenced, but must have an empty static constructor (or one is generated
for you). This means it's easier to mess up and break code if you're not
careful and know what you're doing. As for using the Singleton Pattern, you
automatically already do lots of neat stuff, such as creating them with a
static initialization method and making them immutable.

Disadvantages
o Must use the Instance keyword (e.g. <ClassName>.Instance) to
access the singleton class.
o There can only ever be one instance of the class active at a time.
o Tight connections. Modifying the singleton can easily break all other
code that depends on it. Requiring a lot of refactoring.
o No polymorphism.
o Not very testable.

The Singleton.cs script are example of implementing the singleton pattern


to Unity programming. We use singleton pattern at PlayerManager.cs, the
PlayerManager.cs will manage our global variable and function that may
needed by other script. For example let’s take a look to InitHero() and
InitMob() in PlayerManager.cs. These two function will populate our list of
heroes (List<HeroData> Heroes) and mob (List<MobData> Mobs). We
need these two function to easily accessed by other function. The same
principle can be applied to GetMob() and GetHero().

● Scene Transition
The SceneHandler.cs handle all scene transition in our game. The
ChangeScene(string name) is function that allow us to load scene by given
name. and the SceneManager are Unity function to load a scene, there are
two types of load scene, the LoadScene and LoadSceneAsync. The
LoadScene are standard procedure of loading a scene, the
LoadSceneAsync allow us to monitor the progress of the loaded scene and
load the scene Asynchronously.

116
The reset progress function behave to reset our progress when loading the
MainMenu, since our progress within singleton class won’t reset itself (the
singleton will not destroyed when load a new scene).
● Hero Summon and Active Stage Handler
The SummonHeroHandler class derived from Vuforia AR class that handler object
when scanned. To put it simply, we create a extended version class from
vuforia default tracker. The vuforia parent class has two important function
called OnTrackingFound() and OnTrackingLost(). These two function
handle when object are matches from marker in database and when object
disappear from camera. In SummonHeroHandler class we override that two
functions and added our own function. When camera detect object similar
to database, it will register the object to spawn to PlayerManager class,
after that Spawn the hero object.
● Mob Behaviour
This class control every behavior of our spawned mob, from do attack animation
to deal damage, then dead.

Now proceed to setup everything to make game works. First download your
vuforia database in vuforia web. Make sure you have at least one marker,
download and select the Unity Editor, it will download the database with
unitypackage format. To import it into unity, select Assets -> Import Package
and select the database. Now get the key for development the vuforia in
License Manager. Copy and paste it in vuforia configuration in unity.

117
Figure 30 Setup your Database and Key

Figure 31 ActiveStageHandler.cs

118
Figure 32 SummonHeroHandler.cs

119
PART 8
Finalizing Project

To build the game, open the build settings menu from file->Build Settings, make
sure all needed scene are present at ‘Scene In Build’. Switch Platform to Android,
then click the Player Settings, make sure Company Name and Product Name are
filled with needed information, and in Other Settings, make sure the Package Name
are changed. After that if you have your phone connected to PC, click the Build
and Run, otherwise click Build.

Figure 33 Main Menu

120
Figure 34 Summoning Hero

Figure 35 Fight

121
Figure 36 Pause

122

You might also like