0% found this document useful (0 votes)
121 views30 pages

p2 - Shooter Part 1

This document discusses adding background elements and creating a player character for a 2D shooter game in Unity. It describes importing a background image as a sprite, adding platform sprites extracted from a single image file, and organizing sprites into layers. It also covers creating a player sprite, adding a box collider component to represent its hitbox, and positioning it in the scene. Prefabs are created to reuse platform sprites. Overall, the document provides steps to set up basic visual elements and the player character for a 2D game.

Uploaded by

Arya Weda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views30 pages

p2 - Shooter Part 1

This document discusses adding background elements and creating a player character for a 2D shooter game in Unity. It describes importing a background image as a sprite, adding platform sprites extracted from a single image file, and organizing sprites into layers. It also covers creating a player sprite, adding a box collider component to represent its hitbox, and positioning it in the scene. Prefabs are created to reuse platform sprites. Overall, the document provides steps to set up basic visual elements and the player character for a 2D game.

Uploaded by

Arya Weda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

PERTEMUAN 2 GAME DEVELOPMENT (2D SHOOTER)

Padma nyoman crisnapati

Adding and displaying a background


Using the empty project we created in the previous
part, we will now learn how to add a background and
some fancy clouds.

Adding a background
Your first background will be static. We will use the
following image:
(Right click to save the image)

Import the image in the “sprites” folder. Simply copy


the file in it, or drag and drop it from the explorer.

Do not worry about the import settings for now.

In Unity, create a new Sprite game object in the scene.

 
What is a sprite?

In general, we call “sprite” a 2D image displayed in a


video game. Here, it’s a Unity specific object made for
2D games.

Add the texture to the sprite

We will now select the actual sprite to display. Make


sure that “New Sprite” is selected and look at the
inspector. Set the Sprite property to the “background”
image:

(You have to click on the small round icon at the right


of the input box to show the “Select Sprite” inspector)
You can see that some other sprites are there. Those
are the default images used by uGUI (the Unity UI
system).
“My sprite doesn’t show up in the dialog?”: first, make sure you are
in the “Assets” tab of the “Select Sprite” dialog.

Some readers have reported that, in their project, this dialog was empty.
The reason is that for some Unity installations, even with a fresh new 2D
project, images are imported as “Texture” and not “Sprite”.

To fix this, you need to select the image in the “Project” pane, and in the
“Inspector”, change the “Texture Type” property to “Sprite”:

We don’t know why everybody doesn’t seem to have the same behavior.

Well, we have set a simple sprite displaying a cloudy


sky background. You can think it was a bit complicated
just for that. In fact, we could have dragged the sprite
from the “Project” tab directly right into the “Scene”.

Let’s reorganize the scene.

In the “Hierarchy” pane, select the New Sprite. Rename it


in Background1 or something you will easily remember.
Then move the object to where it belongs: Level ->
Background. Change its position to (0, 0, 0).

A quick exercise: duplicate the background and place it


at (20, 0, 0). It should fit perfectly with the first part.
Tip: you can duplicate an objet with the cmd + D (OS X) or ctrl +
D (Windows) shortcuts.
Sprite layers
The next statement will seem pretty obvious, but it has
some consequences: we are displaying a 2D world.

This means that all images are at the same depth, ie. 0.
And you (as well as the graphics engine) don’t really
know who’s going to be displayed first.

Sprite layers allow us to tell Unity what is in the front


and what is in the back.

In Unity, we can change the “Z” of our elements, and


this will allow us to have layers. This is actually what
we were doing in this tutorial before the Unity 5
update.

But we thought that it was a good idea to use Sprite


Layers.

On your “Sprite Renderer” component, you have a field


named… “Sprite Layer”, currently set to Default.

If you click on it, a short list will show:

Let’s add some layers to fit our needs (use the “+”
button):
Apply the Background layer to our background sprite:

Tip: the settings “Order in Layer” is a way to limit sub-layers. Sprites


with lower numbers are rendered before sprites with greater numbers.
Note: the “Default” layer cannot be removed, because this is the layer
used by 3D elements. You can have 3D objects in your 2D game. Particles
are considered as 3D objects by Unity, so they will be rendered on this
layer.
Adding background elements
Also known as props. These elements aren’t used to
improve the gameplay but to visually enhance the
scene.

Here are some simple flying platform sprites:

(Right click to save the image)

As you can see, we got two platforms in one file. This is


a good way to learn how to crop sprites with the Unity
tools.
Getting two sprites from one image

1.  Import the image in your “sprites” folder


2.  Select the “platforms” sprite and go to the
inspector
3.  Change “Sprite Mode” to “Multiple”
4.  Click on “Sprite Editor”
In the new window (“Sprite Editor”), you can draw
rectangles around each platform to slice the texture
into smaller parts:

Call the platforms “platform1” and “platform2”.


Tip: the top-left button “Slice” allows you to quickly and automatically
make this tedious task.

Unity will find the objects inside the image and will slice them
automatically. You can specify the default pivot point, or set a minimum
size for a slice. For a simple image without artifacts, it’s really efficient.
However, if you use this tool, be careful and check the result to be sure to
get what you want.

Now, under the image file, you should see the two
sprites separately:
Adding them to the scene

We will proceed like for the background sprite: create a


new Sprite and select the “platform1” sprite (or drag
them one by one from the “Project” to the “Scene”
tab). Repeat for “platform2”.

Set their “Sprite Layer” to “Platforms”.

Place them in the Middleground object.


And… it’s working! I’m still amazed how simple it is
now (to be honest, it was a bit tricky without the 2D
tools, involving quad and image tiling).

Prefabs

Save those platforms as prefabs. Just drag’n’drop them


inside the “Prefabs” folder of the “Project” pane from
the “Hierarchy”:

By doing so, you will create a Prefab based exactly on


the original game object. You can notice that the game
object that you have converted to a Prefabpresents a
new row of buttons just under its name:

Note on the “Prefab” buttons: if you modify the game object later, you
can “Apply” its changes to the Prefab or “Revert” it to
the Prefab properties (canceling any change you’ve made on the game
object). The “Select” button move your selection directly to
the Prefab asset in the “Project” view (it will be highlighted).
Creating prefabs with the platform objects will make
them easier to reuse later. Simply drag the Prefab into
the scene to add a copy. Try to add another platform
that way.

You are now able to add more platforms, change their


positions, scales and planes.

You can put some in background or foreground too.


Remember that the “Background”, “Middleground” and
“Foreground” objects are just folders. So you need to
set the right “Sprite Layer” (Platforms) and change the
“Order in Layer”.

Use -10 for far platforms, and increase this number as


you reach the foreground. An example:

It’s not very fancy but in two chapters we will add a


parallax scrolling and it will suddenly bring the scene to
life.
CREATE  A  PLAYER  AND  ITS  ENEMIES  
Create a player and its enemies
In the previous chapter, we have added a background and some props to
our scene. It is time to add some useful game elements, like the player!

Creating the player


Creating a player controllable entity needs some elements : a sprite, a
way to control it and a way to let it interact with the world.

We will explore this process step by step.

Let’s begin with the sprite.

Add a sprite

Here is the image that we will use:

(Right click to save the image)


1.   Copy the player image to the “Textures” folder.
2.   Create a new Sprite. Name it “Player”.
3.   Select the sprite to display in the “Sprite” property of the “Sprite
Renderer” component.

If you have any trouble, refer to the previous part. We did exactly the
same procedure for the background and props.

1.   Select the “Player” sprite layer.


2.   Place the player in the “Foreground” object.
3.   Change its scale. (0.2, 0.2, 1) should be fine.

A word about components

We have just talked about a “Sprite Renderer” component. If you haven’t


remarked, a game object is composed of a few components, visibles in
the “Inspector” pane.

By default, an empty game object looks like:

This object has only one component: a “Transform”. This component is


required and cannot be disabled or removed from an object.

You can add as many components as you want on an object. A script is


added as a component, for example. Most of the components can be
enabled or disabled during the lifetime of the object.
(You can click on the checkbox to disabled it. You can
right-click on a component to reset it, remove it, etc.)
Note: components can interact with other components. If an object has a
component that requires another component of an object to work with,
you can just drag the whole object inside this component and it will find
the correct one in the object.

A “Sprite Renderer” is a component that is able to


display a sprite texture.

Now that we have learned about the concept of


component, let’s add one to the player!

Add a Box Collider

Click on the “Add Component” button of the player


object. Choose a “Box Collider 2D”.

This will represent the player hitbox.

You can see the collider in the editor “Scene” view and
tweak its size in the “Inspector” with the “Size”
property.
Tip: There is another way to edit a box collider. Select a game object
with a box collider and enable the “Edit Collider” toggle in the component.
You can observe that the box collider (the green rectangle) is now
showing four small handles onto. Drag one of them to change the shape
of the box.

Be careful, the blue rectangle represents the Transform component of your


game object, not the collider.

We will set the size of the collider to (10, 10) .

It’s way too large for a real shmup but it’s still smaller
than the sprite:

For the time being, it will be enough.


Tip: if you plan to make a shmup, spend a lot of time tweaking your
hitboxes. In general, it should fit perfectly a small element inside the
player sprite. What about the ship window here? You could also change
the collider shape — with a “Circle Collider 2D” for example. It changes
nothing to the behavior thanks to Unity, but it will slightly improve the
gameplay.

Save the player game object to a prefab. You now have


a basic player entity!
Polygon Collider 2D

If you want a super precise and custom shaped hitbox,


Unity offers a “Polygon Collider 2D” component. It’s
less efficient but allows you to set the shape exactly
like you want.

The Rigidbody magic

There is one last component to add on our player: a


“Rigidbody 2D”.

This will tell to the physics engine how to handle the


game object. Furthermore, it will also allow collision
events to be raised in scripts.

1.  Select your Player game object in the “Hierarchy”.


2.  Add a “Rigidbody 2D” component.

Now, hit play and observe:


The ship is falling!

Say hello to our beloved gravity. :)

As new scenes come with a default gravity and


rigidbodies add a mass to an object, the ship is now
attracted to the bottom.
The default gravity of Unity is 9.81, i.e. the earth gravity.

Gravity can be used in some kind of games, but we


don’t want to have to handle it here. Fortunately, it is
simple to disable gravity on a rigidbody. Just set
“Gravity Scale” to 0. That’s it, the ship is flying again.

You may also want to tick the “Fixed Angles” property


as we don’t want our ship to rotate because of the
physics.

The complete settings:


Moving the player

Time for some scripting! So far, we didn’t code


anything. That’s the power of (love) Unity.

Inside Unity, create a new C# script in your “Scripts”


folder. Call it “PlayerScript”.
Remark: you can do it in JavaScript too. As we said before, code
snippets will be in C#, but it is quite easy to translate the code from a
language to another.
Open your favorite editor or use the “Sync” submenu
(Click on “Assets” in the menubar, then on “Sync
MonoDevelop Project”) to edit the script.
“Sync MonoDevelop Project”: this submenu is a bit weird. First, the
name does not change, even if you have set up another editor.

We also recommend to use this menu the first time you have to script,
because Unity will create the solutions and link the Unity libraries in them
(for Visual Studio, Xamarin Studio or MonoDevelop).

If you simply open the script instead, the compiler of your IDE will likely
catch some errors because it won’t know Unity.

It doesn’t matter because you will never compile directly with it, but it is
nice to have the autocompletion on the Unity objects and a first pass on
errors.

If you come from XNA, you won’t be lost.

You can define some methods (called “Message” as we


are not using C# inheritance system) that Unity will
recognize and execute when needed.

Default scripts come with


the Start and Update methods. Here is a short list of
the most used “Message” functions:

o   Awake() is called once when the object is created.


See it as replacement of a classic constructor
method.
o   Start() is executed after Awake(). The difference is that
the Start()method is not called if the script is not
enabled (remember the checkbox on a component
in the “Inspector”).
o   Update() is executed for each frame in the main
game loop.
o   FixedUpdate() is called at every fixed framerate frame.
You should use this method over Update() when
dealing with physics (“RigidBody” and forces).
o   Destroy() is invoked when the object is destroyed.
It’s your last chance to clean or execute some
code.

You also have some functions for the collisions :

o   OnCollisionEnter2D(CollisionInfo2D info) is invoked when


another collider is touching this object collider.
o   OnCollisionExit2D(CollisionInfo2D info) is invoked when
another collider is not touching this object collider
anymore.
o   OnTriggerEnter2D(Collider2D otherCollider) is invoked when
another collider marked as a “Trigger” is touching
this object collider.
o   OnTriggerExit2D(Collider2D otherCollider) is invoked when
another collider marked as a “Trigger” is not
touching this object collider anymore.

Fiou… This explanation was a bit boring, but


unavoidable. Sorry for that.
Note about the 2D suffix: you should have observed now that almost
anything we talked about was suffixed with “2D”. A “Box Collider 2D”, a
“Rigidbody 2D”, the “OnCollisionEnter2D” or “OnTriggerEnter2D”
methods, etc. These new components or methods have appeared with
Unity 4.3.

By using them, you are adopting the new physics engine integrated in
Unity 4.3 for 2D games (based on Box2D) instead of the one for 3D
games (PhysX). The two engines are sharing similar concepts and
objects, but they don’t work exactly the same. If you start to work with
one (favor Box2D for 2D games), stick to it. This is why we use all the
objects or methods with a “2D” suffix.

We will get back on some of them in details when we


will be using them.

For our player script, we will add some simple controls:


the arrow keys will move the ship.
using UnityEngine;
/// <summary>
/// Player controller and behavior
/// </summary>
public class PlayerScript : MonoBehaviour
{
/// <summary>
/// 1 - The speed of the ship
/// </summary>
public Vector2 speed = new Vector2(50, 50);

// 2 - Store the movement and the component


private Vector2 movement;
private Rigidbody2D rigidbodyComponent;

void Update()
{
// 3 - Retrieve axis information
float inputX = Input.GetAxis("Horizontal");
float inputY = Input.GetAxis("Vertical");

// 4 - Movement per direction


movement = new Vector2(
speed.x * inputX,
speed.y * inputY);

void FixedUpdate()
{
// 5 - Get the component and store the reference
if (rigidbodyComponent == null) rigidbodyComponent =
GetComponent<Rigidbody2D>();

// 6 - Move the game object


rigidbodyComponent.velocity = movement;
}
}

(The numbers in the comments refer to the


explanations below)
Note about C# conventions: look at the speed member visibility: it’s
public. In C#, a member variable should be private in order to keep the
internal representation of the class private.

But exposing it as a public variable allows you to modify it in Unity


through the “Inspector” pane, even during the game execution. This is
a powerful feature of Unity, letting you tweaks the gameplay without
coding.

Remember that we are doing scripting here, not classic C# programming.


This implies to break some rules and conventions.
Explanations

1.  We first define a public variable that will appear in


the “Inspector” view of Unity. This is the speed
applied to the ship.
2.  The fields we need.
3.  We use the default axis that can be redefined
in “Edit” -> “Project Settings” -> “Input”. This will
return a value between [-1, 1], 0 being the idle
state, 1 the right, -1 the left.
4.  We multiply the direction by the speed.
5.  We need to access the rigidbody component, but
we can avoid to do it every frame by storing a
reference.
6.  We change the rigidbody velocity. This will tell the
physic engine to move the game object. We do
that in FixedUpdate() as it is recommended to do
everything that is physics-related in there.
Tutorial update: if you have read this tutorial before, you may
remember that we were using transform.Translate directly. This was
working because translations were slow, but it is not recommended since
it can mess up the physics (for the physic engine, a translation is like a
teleportation, so there is no collision).

Thanks to your feedback, we updated the scripts to help people learn the
good practices of game object movement.

Now, attach the script to the game object.


Tip: you can attach a script to a game object by dragging the script from
the “Project” view on the game object in the “Hierarchy”. You can also
click on “Add Component” and find it manually.

Hit the “Play” button in top of the editor. The ship is


moving and your game is running! Congratulations,
you have just made the equivalent of a “Hello,
World!” for a game :)
Try to tweak the speed: click on the player, modify the
speed values in the “Inspector” and look at the
consequences.

Be careful: modifications when the game is executed (or played) are lost
when you stop it! It’s a great tool for tweaking the gameplay, but
remember what you are doing if you want to keep the changes.

However, this effect is also handy: you can destroy your game completely
during the execution to test something new, without being afraid of
breaking your real project.

This was the first sign of life in our game! Let’s add
more!

The first enemy


A shmup is nothing without tons of enemies to blow up.

Let’s use an innocent octopus, named “Poulpi”:


(Right click to save the image)

Sprite

Time to create a new sprite! Again:

1.  Copy the image to the “sprites” folder.


2.  Create a new Sprite using this image.
3.  Set the sprite layer to “Enemies”
4.  Change the “Scale” property of the Transform to (0.3,
0.3, 1).
5.  Add a “Box Collider 2D” with a size of (4, 4).
6.  Add a “Rigidbody 2D” with a “Gravity Scale”
of 0 and “Fixed Angles” ticked.

Save the prefab… and that’s it!


Script

We will script a simple behavior: the Poulpi will just


move in a direction.

Create a new script “MoveScript”.

We could call it “EnemyScript” but we plan to reuse it


later in another context.
Note: the modularity provided by Unity’s component-based system offers
a great way to separate scripts with different features. Of course, you can
still have one giant script doing everything with a lot of parameters. It’s
your choice, but we highly recommend against doing that.

We will copy some parts of what we have already


written in the “PlayerScript” for movement. We will add
another designer (a public member you can alter in the
“Inspector”) variable for the direction:
using UnityEngine;

/// <summary>
/// Simply moves the current game object
/// </summary>
public class MoveScript : MonoBehaviour
{
// 1 - Designer variables
/// <summary>
/// Object speed
/// </summary>
public Vector2 speed = new Vector2(10, 10);

/// <summary>
/// Moving direction
/// </summary>
public Vector2 direction = new Vector2(-1, 0);

private Vector2 movement;


private Rigidbody2D rigidbodyComponent;

void Update()
{
// 2 - Movement
movement = new Vector2(
speed.x * direction.x,
speed.y * direction.y);
}

void FixedUpdate()
{
if (rigidbodyComponent == null) rigidbodyComponent =
GetComponent<Rigidbody2D>();

// Apply movement to the rigidbody


rigidbodyComponent.velocity = movement;
}
}

Attach the script to the Poulpi. Hit “Play”: it should


move just like below.
If you move the player in front of the enemy, the two
sprites will collide. They will just block each other as we
didn’t define the collision behavior yet.

You might also like