Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Day 1 of 100 Days of VR: Going Through the Unity Ball Tutorial

DZone's Guide to

Day 1 of 100 Days of VR: Going Through the Unity Ball Tutorial

This walkthrough takes you through the basics of learning to use the popular Unity game engine for mobile game development.

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

The first step to learning VR is learning how to use one of the game engines that support them. In the current market, we have two options: Unity and Unreal Engine.

I was told that Unity was more beginners friendly, so I decided to pick that up. I installed the latest version of Unity along with Visual Studio 2017 Community Edition that came bundled along with Unity.

Great! Now that we have our toolkit installed, what’s next?

The first thing I did was that I started to go through the Unity’s Roll-a-ball tutorial.

Here’s a summary of what I learned in the tutorial:

Setting Up the Game

Scene

The scene tab gives you a 3D view of the world that you can move around in. In this tab, you can directly drag and drop the positioning of the objects that you inserted into Unity.

Hierarchy

The hierarchy is used to display the Unity objects that you create and added into your scene.

Positioning

Since we’re working in a 3D environment, Unity has a  3D coordinate system: (x,y,z), if we were to select the sphere that was created in the tutorial, if you look at the inspector on the right, you can see that we can change some of the transform properties such as position, rotation, and scale.

It appears that if we imagine something lying flat on a surface:

  • X = Horizontal movement
  • Y = Height movement
  • Z = Vertical movement

Material

If you want to change the colors of your object, we have to create a material for our Mesh Renderer component that you can see from the picture above.

If you were to select the sphere,  in the inspector under the Mesh Renderer component, you can select a material to apply on our object.

In the tutorial, we created a new material in the project pane and made its color red. Then we applied it to our sphere to get the red sphere that you see above.

Roll a Ball

After the first video showed us how to setup the environment and use some of the tools available for the roll a ball tutorial, the next thing we learned is how to actually move the ball.

Rigid Body

The first thing we need to do is to add a RigidBody component to our ball object. What this does is that it makes the ball take part in Unity’s physics engine so that it’ll be affected by things such as gravity and when it collides with other properties

Looking at the code for this part of the video, we can learn a lot of information:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

    public float speed;

    private Rigidbody rb;

    void Start ()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate ()
    {
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);

        rb.AddForce (movement * speed);
    }
}

The way scripts in Unity works is that they are attached to unity game objects that are in and we can grab any component information that’s attached to the game.

A great example is given in the example code you see above when we’re using the rigid component:

rb = GetComponent<Rigidbody>();

for when we want to access information from our RigidBody component.

Public Variables

Before looking at the rest of the function, I want to point out that if you were to make a variable public in Unity script, that means you can set their value outside of the code under that script’s component in the Unity Editor.

Using the component system we can easily change the text and settings on the fly when you’re playtesting your game!

Learning About Start and Update

So we have 2 functions that are being used in the code Start() and FixedUpdate(). Both of these are functions we’re inheriting from the MonoBehaviour object that controls how the game works.

Here are the more common methods I found

  • Start() – this is run only once when your GameObject gets created in Unity. It’s used for initializing your variables and creating the state of your GameObject when it is first created

The next parts are the updates method. Depending on what you might have worked on, the update function might take some time to wrap your mind around.

An update method is called once every time Unity renders a frame. You might have heard the term, frames per second? If we have 60 frames per second, which means our update function gets called 60 times every second.

So what’s a frame? If you have some knowledge of animation, you’ll know that an image is made of multiple images that are being replaced one after another. An image to illustrate my point is this gif:

This gif is actually made up of multiple images from a sprite map that are being looped through per scene.

From my basic understanding, this is extremely important for VR; if we want to avoid causing motion sickness, we have to make a game that achieves 90 fps.

But anyways, that’s a problem for the future, I don’t even know how to work with Unity! Going back to the update methods, we have:

  • Update() – this methods Is called every frame that the game runs in. I did my own investigation by inserting the code snippet Debug.Log("update: " + Time.deltaTime); to print out how much time has passed since the last update call and found that the time per frame isn’t consistent.
  • FixedUpdate() – Similar to update, but this code runs at fixed times, which is good for physics calculations which we see in the code above. Printing the deltaTime, it appears that the FixedUpdate method is called every 0.02 seconds. Forcing 50 fps.

Inputs and Vectors

Finally the last part of the code is the movement code. Unity comes with a handy set of api’s that make it easy to detect when the user is hitting on the keyboard.

We used Input.GetAxis, to get the movement when we hit the arrow keys to get the direction that is being hit and store those values in a vector.

If you remember a bit of physics from High school, you might remember that a vector is just a direction. So in our code, when we say we create a vector (x,y, and z location) it means that we’re creating a force that’s going in that x,y, and z direction that we specified…

…which is exactly what you see here:

rb.AddForce (movement * speed);

Moving the Camera

So that was a lot to learn about Unity already and we’re only in 3rd video of the series! So continuing on, after learning about moving the ball around, we now see that the game tab that we run doesn’t really move or follow the ball when we roll it around.

This was resolved by using a camera object, the view that you’re seeing in the game tab is from the camera.

So a nifty way to follow the ball is to make the ball a child of our ball, by dragging our Main Camera object on the hierarchy into the Sphere we made.

By doing this, we made our camera relative to our ball’s position. Unfortunately, when we move the ball around the camera follows.

To fix this we added the provided CameraController script to our camera:

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {

    public GameObject player;

    private Vector3 offset;

    void Start ()
    {
        offset = transform.position - player.transform.position;
    }

    void LateUpdate ()
    {
        transform.position = player.transform.position + offset;
    }
}

What was done was that we created the distance from the camera to the player in the Start() function and update our camera so that it is always that distance away in LateUpdate()

LateUpdate() acts the same way as the other update() however the difference is that it is the method that’s called when rendering a frame.

Setting Up the Play Area

There wasn’t too much in this section, just learning how to set up our environment by moving objects around.

Creating Collectable Objects

There also wasn’t too much here, we created collectible items that the player can roll the ball over, we created a script to make the ball rotate which we do by grabbing our GameObject’s transform component and modifying the rotation.

transform.Rotate (new Vector3 (15, 30, 45) * Time.deltaTime);

Note: Time.deltaTime is the time that elapsed since the last time we called Update()

Prefabs

However, one interesting thing to note is that after we make the object we want, we can drag it from the hierarchy into the project pane on the bottom to create a prefab.

A prefab is a template or a clone of the object that you made. With this, we can create multiple instances of that same object.

The benefits of using prefab is that if you ever decide to change the components of the GameObject, instead of changing them one by one, just by changing the prefab, you can change all instance in one go.

Collecting the Pick-Up Objects

Now things are finally getting more interesting. In this section, we learned a variety of subjects involving colliders and how objects in the game interact with other objects.

From the previous video, we created these cube objects (which have their own rigid body) that we can collect, however, if we were to roll our spheres into the cube, we would bounce back.

This problem will be addressed in this video.

Collider Intro

Whenever a GameObject that has a Collider component touches another GameObject with a Collider component, we call that a collision.

Unity provides many collider components that you can attach to your GameObject. These colliders all come in different shapes and sizes. The goal is to pick a collider that matches the shape of your GameObject.

When we were to use a different collider- let’s say a square, for example- the collision won’t actually occur at when something else touches the material (the red sphere); instead, the collision will start when they touch the edge of the square.

From my understanding, we can use a mesh collider to try and hug our object as close as possible, however the more fine grain control we need on our GameObject for collision, the more calculations will need to be done, resulting in worse performance.

The TLDR of this: only use complex colliders if you absolutely have to, otherwise we should try and use more basic shape colliders.

Using Colliders

Now back to what was taught, how do we use them?

In our PlayerController.cs we just inherit the OnTriggerEnter() function!

void OnTriggerEnter(Collider other) 
{
    if (other.gameObject.CompareTag ("Pick Up"))
    {
        other.gameObject.SetActive (false);
    }
}

This method gets called every time our sphere bumps into another collider, we get passed a Collider object that has access to the GameObject that we collided against.

Notice how we have something called Tag? That’s how we can identify what we hit in Unity. In each GameObject in the hierarchy, you can create and attach a Tag to them. As you can tell from the code above, we can use Tags to help identify which GameObject we collided against.

After we found the object with the tag we want, we can do whatever we want with it!

Performance Optimizations

While probably not important to know this early on, something that was briefly mentioned is that there are two types of colliders, static and dynamic colliders.

Static colliders, as you expect, are objects that don’t move and dynamic are objects that do move. The important thing to remember here is that static colliders are cached by Unity so that we can get performance benefits, however, if you plan to change and move a static game object, this will cause Unity to constantly cache the object, which now becomes a performance problem!

To make a GameObject be a dynamic collider is to make it impacted by Unity’s physics engine, ie adding a RigidBody component to it.

Dynamic Collider = RigidBody Component + Collider Component

Static Collider = Collider Component

Displaying the Score and Text

The game is “technically” done, but the user will never know it. In the last video of the series, we learn a bit about using Unity’s UI system.

UI

You can create a UI element like text the same way you create a GameObject in Unity by right-clicking in the hierarchy pane, however, one big difference is that all UI elements are made children of a Canvas GameObject.

And another thing is that the Canvas is actually directly on the screen when you’re in the Game tab and is not part of the Scene Tab… well actually it is, but it’s on a completely different scale!

The canvas covers the whole Game tab screen and for our UI GameObject, instead of Transform, we have something called Rect Transform.

In a way it’s very similar to a normal GameObject where you can still drag the object around, however, a nifty trick that helps position the text is to click on the square button on the top left corner of our Rect Transform component and you'll get this:

If you hold alt and click one of the squares, your text will be automatically moved into one of the 9 spaces! Nifty!

How to Use Our UI Components

Looking at the code that was created in the video:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PlayerController : MonoBehaviour {

    public float speed;
    public Text countText;
    public Text winText;

    private Rigidbody rb;
    private int count;

    void Start ()
    {
        rb = GetComponent<Rigidbody>();
        count = 0;
        SetCountText ();
        winText.text = "";
    }

    void FixedUpdate ()
    {
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);

        rb.AddForce (movement * speed);
    }

    void OnTriggerEnter(Collider other) 
    {
        if (other.gameObject.CompareTag ( "Pick Up"))
        {
            other.gameObject.SetActive (false);
            count = count + 1;
            SetCountText ();
        }
    }

    void SetCountText ()
    {
        countText.text = "Count: " + count.ToString ();
        if (count >= 12)
        {
            winText.text = "You Win!";
        }
    }
}

 We created a public variable of type Text, you can assign the value by dragging and dropping the Text object in our hierarchy into the variable slot in the script’s component.

One very important thing to remember when you’re using UI gameobjects is to include:

using UnityEngine.UI;

Otherwise, Unity won’t know any of the UI objects that you’re trying to reference.

The only new important part is the function SetCountText() which is where we see how we interact with a UI object:

void SetCountText ()
{
    countText.text = "Count: " + count.ToString ();
    if (count >= 12)
    {
        winText.text = "You Win!";
    }
}

It looks pretty straightforward, right? You get the UI object, and you set its text to be whatever you want it to be. Easy!

Conclusion

Phew, doing this write-up summary might actually be harder than the actual learning of Unity… and it’s only day 1!

But that’s okay. We’re just starting to learn about Unity, I’m sure as we progress along we’ll start seeing things like colliders, rigid bodies, and UI again and I don’t have to do this again. I really hope so. I really do…

Anyways, that’s the end of day 1! I hope you learned something valuable from this!

100 Days of VR | Day 2

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:
unity 3d ,game dev ,vr ,mobile ,mobile app development

Published at DZone with permission of Josh Chang, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}