0% found this document useful (0 votes)
92 views23 pages

Parent and Child Game Objects in Unity

This document discusses parent-child relationships between game objects in Unity. It explains that child objects will move and rotate relative to their parent object. It provides an example where a character shoots fireballs from an invisible child object located at its hand, rather than directly from the character. This allows the fireballs to spawn from the desired location while keeping the shooting logic separate from the character's movement logic. The document also discusses using tags to identify different types of game objects and detect collisions between them using the OnCollisionEnter method.
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)
92 views23 pages

Parent and Child Game Objects in Unity

This document discusses parent-child relationships between game objects in Unity. It explains that child objects will move and rotate relative to their parent object. It provides an example where a character shoots fireballs from an invisible child object located at its hand, rather than directly from the character. This allows the fireballs to spawn from the desired location while keeping the shooting logic separate from the character's movement logic. The document also discusses using tags to identify different types of game objects and detect collisions between them using the OnCollisionEnter method.
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/ 23

Parent and Child Game Objects in

Unity

It’s time to put your baby toys and milk bottle down, we are not taking care of tiny little
gameObject babies anymore. Instead, we're gonna learn how to create child gameObjects of main
gameObjects in the Hierarchy, a technique that proves to be quite useful when used with
the Instantiate() method, that we have just learned about.

If you have directly arrived on this tutorial, we recommend you to check our last tutorial for
understanding the ongoing example.

If you pay close attention to the character we've created in the previous tutorial, you will notice
that the fireballs just spawn out of the middle of our main game character, not from where you
would expect (Like in this case, the outstretched hand).

Page 1 of 23
Now, what if instead of the character, there was an invisible gameObject that shot the fireballs?
After all, a user (game player) wouldn't really be able to see who exactly shot the fireball. So let's
do that. First of all, create a new empty gameObject.

You see, gameObjects in general have their location relative to the game world.

But for certain objects, like a gun or a car's horn, you might need it to be relative to another
gameObject instead. Instead of saying This gameObject is 2 units away from the dead center of
the game, we can make gameObjects say This gameObject is 2 units away from another
gameObject, no matter where it is.

Let's try it out in our game, to see how it really works. To make a gameObject a child,
simply drag and drop the intended child onto the intended parent gameObject. In our case, we'll
drag our empty gameObject onto our character object (Shooting Savi).

Page 2 of 23
You'll notice that the new gameObject now comes in a dropdown list under our main character, and has
a small indentation added to its name in the Hierarchy. This means that the gameObject is now a child of
our character. If you try to move the character now, you'll notice that the empty gameObject also moves
with it, but remains at the same relative distance.

But the empty gameObject is floating near our character's head, and not near his hand! To fix that,
simply adjust the position of the empty gameObject using the position values in
the Transform view, until the empty gameObject gets to where you need it to be.

Once again, a child gameObject will have its position relative to its parent, not the game world.
Meaning if you set the position to (0, 0, 0), a child gameObject will get positioned in the dead
center of the parent gameObject, not the screen.
In our case, if you remember from the last tutorial, we added the code the instantiate a new fireball
everytime the spacebar is hit, in the script attached to Shooting Savi game object. And the same
script also holds the code for enabling the Shooting Savi game object to move.
So we will have to remove the fireball prefab creation code from the update() method of
the Shooter class.
Let's create a new class ShootingBehaviour and add the code to the update() method of this
class and attach this script to the new Invisible child game object of the Shooting Savi game
object.

Page 3 of 23
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class ShootingBehaviour : MonoBehaviour

public GameObject fireball;

void update()

// When spacebar is hit

if(Input.GetKeyDown(KeyCode.Space))

// instantiate the fireball object

Instantiate(fireball,

new Vector3(gameObject.transform.position.x,
gameObject.transform.position.y, 0),

new Quaternion(0, 0, 0, 0));

And the Shooter class which is making the Shooting Savi move will look like,
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Shooter : MonoBehaviour

Page 4 of 23
{

public RigidBody2D body;

public float speed;

void update()

body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed,


Input.GetAxisRaw("Vertical")*speed);

Now that we've attached the shooting script to the empty gameObject and made it a child of our
character's gameObject, let's test our game now.

Page 5 of 23
It works! So, what have we learned in this lesson? We've learned how gameObject
parenting works and how we can use it to our advantage, and we didn't have to change a single
dirty diaper (we don't have to do much work).

Unity: Detecting Collisions with


onCollisionEnter
In this tutorial, we'll learn how to detect collisions between two gameObjects using a simple C#
script, and how to execute some code when the objects collide.
We'll also learn how to work with game tags and why they're important, and we'll also learn how
to use Unity's console to output customized messages that can come handy to us as developers
and testers.
To get started, let's open up the project we've been working on so far:

Everything seems to be in order. Now, let's add a new 2D Box Collider to our bullet(fireball) so
it can detect collisions (Remember, the Collider is what actually defines a collision, not
a Rigidbody).
Want to see how to add a Collider to a game object? You will find it here.
Here's a quick question: If we want all generated bullets (fireballs) to have a box collider, what
do we modify? The prefab of course. Attach a 2D box collider to the prefab, and that's about it for
the bullet.

Page 6 of 23
Now, let's give our main character something to shoot at. How about a target? We have one around
here somewhere.

There we go. Let's import this target into our game project and into our scene (You should be fairly
comfortable with adding new sprites to the scene by now).

Now, let's add a 2D circle collider to our target (Since it is, a circle, after all) as well as
a Rigidbody2D.

Page 7 of 23
Now, let's go ahead and write some script to detect a collision between the bullet(fireball) and the
target. Once again, copy down the below code, and we will explain what's going on in detail.
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TargetBehaviour : MonoBehaviour

void onCollisionEnter2D(Collision2D col)

// When target is hit

if(col.gameObject.tag == "Bullet")

Debug.Log("Target was Hit!");

Remember, we said that the MonoBehaviour class provides a lot of other default methods
alongside start() and update()? Well, OnCollisionEnter2D() (with
parameter Collision2D) is one such method. It's a method that is fired (called) by Unity
whenever it detects a collision between the object to which this script is attached to, and any
another gameObject.
Note the Collision2D col parameter we provided. (Using the variable name as col or coll is
quite popular amongst developers, when using this method). We haven't set or even instantiated
any Collision2D object/variable, how are we using it?
Collision2D is a set of data about the collision that is generated during a collision, by Unity. It
includes stuff like the gameObject that hit, the point where it hit (stored as a Point variable which
is, in fact, a Vector3) and so on. col is simply the name we gave to this set of data for the
collision.

Page 8 of 23
Hence this method will be called upon whenever a collision is detected, and Unity will make sure
that the argument col (instance of Collision2D) has all the required values stored in it. We just
have to use them and operate on them.
Next, have a look at the condition in the if statement.
(col.gameObject.tag == "Bullet")

What does this line mean? It simply means that the gameObject included in the col data variable,
that is, the gameObject that collided, should have a tag named Bullet in order for the if statement
to fire. Tags? What? Don't worry about tags just yet, we'll be getting to that very shortly.

What is Debug.Log for?


The next line is quite important, since it's our magic line. The Debug class is a class that contains
tools which are very useful while you're developing your game, and even more when you're testing
the code or any other components.
One of the methods included in Debug class is the Log(string parameter) method, which
we are using in the above code. It simply prints a new message defined by the parameter to
the console, whenever you call the method. Save this script, and attach it to the target. Remember
to set the Gravity Scale to 0 in the editor, and additionally, you should freeze
the X and Y coordinates in the constraints menu to prevent your target from flying off.

What are Game Tags?


Before running the game, let's work on tags. Tags are basically a way of identifying and grouping
gameObjects together, for you and Unity. By default, gameObjects are untagged, that is, they have
no tag on them. We can set tags and create our own, by clicking on the Tag option in the top of the
gameObject (or prefab) Inspector:

Page 9 of 23
Page 10 of 23
Unity gives us a bunch of tags to use by default, and we can even add our own by clicking on Add
Tag. Clicking on Add Tag takes us to this menu in the Inspector:

Click on the + button, and you will get an input field for a new tag's name. Since we wrote our
collision script to detect a collision with an object having the tag bullet, we'll give this new tag the
name Bullet. Once you do that, simply open up your prefab and give it the Bullet tag which will
now appear in your list.

Page 11 of 23
If you run the game now, try firing at the target, and you should see something like this:

Have a look at the bottom left corner of Unity's window. You should see your message whenever
your bullet hits the target. Of course, the way we have programmed the bullet to move, it will just
touch the target and keep on moving forever. We'll fix that up ahead, so for now, we'll focus on
what's really going on here.

1. Our main character launches a bullet with the tag Bullet


2. Once Unity detects a collision with the bullet with the tag name as Bullet,
the if statement turns true and the code it has, is executed.
3. The code asks Unity to print Target was hit! to the console.

NOTE: This repeats every time you shoot the target.


If you want to see the full Console window, where you can also see scripting errors and warnings
if Unity detects them, you can easily find it by clicking on the Console tab right above
the Assets section.

Page 12 of 23
Practice Exercise

• Try to make multiple targets, which print different messages when hit, to the Console.
For example, Target 1 was hit!, Target 2 was hit! and so on. Feel free to explore more
functions and components, although try to do these in a separate, fresh project so you
know what's changing what in the game, as you explore.

Page 13 of 23
How to Destroy Game Objects in
Unity 3D
As important instantiating and modifying gameObjects is in a game, it's equally important
to destroy them when they are not required.
Main reasons for destroying gameObjects include managing memory, getting rid of
not-needed gameObjects (Like those that go beyond the camera and don't return), or
even game-related events (Getting hit by a bullet).
Destroy(gameObject): That's the code which is used to destroy a gameObject. Fairly
simple, isn't it? Let's rewind and have a slightly more deeper look at what's going on. If
you try to explore the Destroy method in your IDE, you will see that the Destroy method
has 2 variants(overloaded forms).
The first overload form simply Destroys the gameObject that's input as a parameter, and
nothing else.
While, the second overload form, involves another parameter time, t as
a float variable. This will wait for the time specified in seconds before destroying
the gameObject. This variant of the Destroy method comes very handy when you want
the gameObject to finish up some other stuff/task/calculation before destroying itself. For
example, playing a dying animation or adding a score.
Till our last tutorial, we've successfully added a target that outputs a message to the
console when hit by a bullet. Now let's make the target vanish, once its hit, shall we? How
do we do that? We simply add the following lines to our already existing target's script:
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TargetBehaviour : MonoBehaviour

void onCollisionEnter2D(Collision2D col)

// When target is hit

if(col.gameObject.tag == "Bullet")

Page 14 of 23
Debug.Log("Target was Hit!");

// object which collided

Destroy(col.gameObject());

// object with which it collided

Destroy(gameObject);

What's going on here? We're telling the script to destroy the gameObject included in col's
data. In simpler terms, it means we're telling the script to destroy the bullet(fireball), since
we don't want our bullet to keep going after it destroys our target.

In the second Destroy statement (our magic line), the gameObject destroys itself.
Remember that simply using the term gameObject references that gameObject which
the script is attached to, in our case, the target. Save up the script, and fire up the
game!

INFO: In editing mode.

Page 15 of 23
INFO: In Play mode, after the target is hit
Once we hit the target, the bullet and the target disappear! Have a look at the Hierarchy,
and you'll notice that the target and bullet's clone gameObjects both are missing. They
have simply vanished out of existence once they get destroyed in-game. Since we placed
the target in the scene while building it, it will always come back whenever we re-enter
the scene, that is, whenever we enter Play mode.
So there you have it! Destroying gameObjects in itself is a very easy concept, since it
involves only one line of code, but the real magic happens when you call the method
along with other statements to make the object's destruction look and feel real and right.
We have done quite a lot this time. We gave our character the ability to shoot bullets, and
we've learned the concepts of prefabs and instantiation. Next, we gave our character a
target to shoot, thus understanding collision detection, and finally, we made the targets
destroy themselves once they got hit, finishing things off with object destruction.

Practice Exercise
1. Try to give your target a Health value, meaning you have to shoot it multiple
times to break it. This will test not only your logic in making games, but your
ability to reason in basic programming logic as well.

HINT: A simple integer variable and an if statement can go a long way.

Page 16 of 23
2. Try to create an end-region for bullets out of the camera coverage area. If a
bullet goes out of the camera region and touches this end region, it gets
destroyed, instead of aimlessly going off into dead space. This is an efficient way
of managing memory when you get into bigger, more complex games.

Unity: Using
RigidBody AddForce() method to
move Game Object
There are mainly two ways of moving a gameObject in Unity:

• Changing Position Coordintes: By directly changing the position of a


gameObject without much consideration to its physics or other such components.
This is what we've been doing so far, by simply adding a value to the
object's X position every frame.
• Rigidbody Physics: When dealing with objects that follows physics rules, it
makes more sense to apply forces on objects or change their velocity instead of a
direct position update. Looks more real.

In this tutorial we will cover an interesting example of using Rigidbody Physics for
movement instead of Position change trick. We've worked with shooting bullets so far,
right? But our bullets have only travelled using the position change regardless of what
they are and how they move in real world.
Which also leads to issues like the one in which our bullet kept going even after it hit the
target(Checkout our previous tutorials for the example).
It simply didn't know that it was supposed to stop, after hitting the target, since we
programmed it to keep going to the right.
Instead of doing that, what if we applied a very strong impulsive force to the bullet, much
like the one in real life? Doing so will make the bullet move because of its momentum,
and not because of a programmed position update.

Page 17 of 23
Let's explore this option, and, we'll understand the AddForce() method provided by the
class Rigidbody. Open up the script that defines our bullet/fireball's behaviour:
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FireballBehaviour : MonoBehaviour

private float fireballXValue;

public float fireballSpeed;

void Start()

// getting the initial position where prefab is created

fireballXValue = gameObject.transform.position.x;

// Update is called once per frame

void Update()

// adding speed value to the X axis position

// value

fireballXValue += fireballSpeed;

// setting new X value to position

gameObject.transform.position = new Vector2(fireballXValue,


gameObject.transform.position.y);

Page 18 of 23
Since pretty much everything we've written in this script deals with movement by
position change, let's clear everything up so we have a
clean Start() and Update() methods again.
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FireballBehaviour : MonoBehaviour

private float fireballXValue;

public float fireballSpeed;

void Start()

// Update is called once per frame

void Update()

Page 19 of 23
Controlling GameObjects using components
Now we know that we can access a gameObject in the script attached to it by using the
reference gameObject.
Also, we can access and Component(like RigidBody, Collider etc) attached to the
gameObject using the GetComponent function.
While earlier, we used to update any component's property using the Inspector view.
Here, we will try to do that from within the script.
First off, we still have to declare the Rigidbody2D variable, but instead of making
it public, let's make it private instead.
private RigidBody2D fireballBody;

Now, in the Start() method, we'll add the following line:


void Start()

fireballBody = GetComponent();

So what does this line do? This line of code is, in a way, an automatic way of detecting
and setting the variable. By calling the GetComponent method, we are simply telling Unity
to go ahead and detect the type of component, specified in the angle brackets <> for our
gameObject. In our case, we want the script to detect a Rigidbody2D component, so we'll
put that within the angle brackets. This method doesn't have any overloads(variant).

Adding Velocity and Force to a RigidBody


component
So now that we have control on our fireball's Rigidbody, what do we do with it? Well, we
can either add a velocity to it, or add a force to it. Note that, both of these components
are a part of the physics behind the gameObject, and not a direct change to the transform
(and hence, its position) itself.
What's the difference? If you add a velocity to your body, you're ignoring any mass that
the body has. It simply sets it going without considering how heavy the body is. If you add
a force however, you're taking the mass of the body into account.

Page 20 of 23
That means adding even a small velocity to something heavy like a big car will make it
move, but adding a small force on the same car will only budge it slightly. As far as we're
concerned, we'll add a velocity to the fireball, since we can consider it to have pretty low
weight in itself.

Adding velocity property


using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FireballBehaviour : MonoBehaviour

private RigidBody2D fireballBody;

public float speed;

void Start()

fireballBody = GetComponent();

// velocity is a property of RigidBody2D

fireballBody.velocity = new Vector2(speed, 0);

// Update is called once per frame

void Update()

Page 21 of 23
Wait a second! You added the fireballBody.velocity code into the Start() method,
not the Update() method. To understand this, let's take an example. Imagine your mom
asks you to change the lightbulb in the kitchen. You say, "sure, I'll do it", and you do it
later on (Or don't, as is the case with most of us). Now imagine your mom asking you to
change the lightbulb, 60 times per second for the rest of your life whether you change the
lightbulb or not. A bit terrifying, isn't it? We are doing quite the same thing here, in Unity.
If we set the velocity in the Start() method, we are simply telling the game to change the
velocity once and then move on.
But If we write that same code in the Update() method, we'd simply be asking Unity to set
the Rigidbody's speed to our defined values again and again. Since our values don't
change for the time being, we're un-necessarily telling the script to assign the value to
something it's already done.

Adding force using AddForce()

Now, let's explore the way of adding a force to the gameObject.

The first parameter for the method AddForce() asks for simply a Vector2 to know in
which direction you want to apply the force in. For example, a force using new
Vector2(4, 5) will apply a force of 4 units horizontally right and 5 units
vertically upwards.
The second parameter is a bit more interesting. You'll see that the additonal second
parameter is an enum named ForceMode2D. ForceMode2D is a pair of modes for
applying a force onto a gameObject. These modes are named Force and Impulse.
Based on what kind of force you want to apply, you either input ForceMode2D.Force (for
applying a constant, consistent force) or ForceMode2D.Impulse(for applying an
instantaneous, striking force.)
For our scenario, we want to apply a sudden, massive force on our fireball so it shoots
forward. Applying a constant force would make it accelerate up from a slow speed, which
would seem kind of odd.
Page 22 of 23
using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FireballBehaviour : MonoBehaviour

private RigidBody2D fireballBody;

public float speed;

void Start()

fireballBody = GetComponent();

// AddForce is a function of RigidBody2D

fireballBody.AddForce(new Vector2(speed, 0), ForceMode2D.Impulse);

// Update is called once per frame

void Update()

If you try out both these methods in Unity, your fireballs should move the same way still,
but this time, without ever modifying its position directly and using physics instead. We
let Unity handle that for us.

Page 23 of 23

You might also like