Skip to content

What's Next?

You should now understand how to work with scenes, objects, and scripts in Unity, as well as using the standard assets for basic first-person navigation.

Since we don't have the capacity to work on actual VR this time, we will have to make do with simulating it. Using what you have learned here, you should be able to recreate the remaining tutorials that can be found in the following link:

unity-vr-et-workshop/2-vr-interaction/

The point of these exercises is to familiarize yourself with the concepts that will be presented there — Runtime, Coroutines, and Input/Output. The interactions in these tutorials can be fully replaced with the clicking interactions you've just learned before, and you can disregard the VR-specific parts for this seminar, such as the gaze tracking.

Easier Object Interaction

While you're free to use the interactions from the Starter Assets in the previous step, you should also try to use a more direct and precise method for interacting with objects: simply clicking on them.

For this we can reuse the scene we've built during the introduction (the blue cube above the plane) and add one additional script to the MainCamera game object. This script will be responsible for raycasting from the camera to the mouse cursor, and checking if it hits any objects. We can then perform various actions depending on which objects are hit.

Clean Up

First, let's clean up the existing SwitchSize.cs script by taking the code that we've put in the Update () function and making a dedicated function for cycling the size. Let's call it CycleSize ():

SwitchSize.cs
public void CycleSize ()
{
    // Get the current scale of the object
    Vector3 currentScale = transform.localScale;

    // Check if the object is small
    if (currentScale.x < 1)
    {
        // Make the object big
        transform.localScale = new Vector3 (2, 2, 2);
        // Debug.Log ("Cube got bigger");
    }
    else
    {
        // Make the object small
        transform.localScale = transform.localScale / 2;
        Debug.Log ("Cube got smaller");
    }
}

You can put this function anywhere inside the SwitchSize.cs script, as long as it's not inside the existing other functions, but still inside the brackets of the SwitchSize class definition.

We can now clean up our Update () function by calling this new function instead of putting the code directly inside:

SwitchSize.cs
void Update ()
{
    // Check if the space bar is presseda
    if (Input.GetKeyDown (KeyCode.Space))
    {
        CycleSize ();
    }
}

Save and run: it should work just as before.

But now that we've declared the CycleSize () function as public, we can access it from anywhere else in our Unity project, so let's do just that.

Raycasting

First, let's add a new script to the MainCamera game object. Call it MouseCaster. We will use this script to check if the mouse cursor is pointing at any objects in the scene, and perform actions depending on which objects are hit.

As above, create a new function outside of Update () or Start () and call it void ClickFunction (). This function should cast a ray from the camera to where the mouse cursor is pointing, and check if it intersects, or hits any objects that are in the scene. This will only work for objects with Collider component attached to them! Depending on which object the cast ray collides with, we will make it do different actions.

MouseCaster.cs
void ClickFunction ()
{
    // Create a ray from the camera to the mouse position
    Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    // Create a RaycastHit object to store information about the raycast
    RaycastHit hit;

    // Check if the raycast hit something
    if (Physics.Raycast (ray, out hit))
    {
        // Check if the object hit is an object named "Cube"
        if (hit.collider.gameObject.name == "Cube")
        {
            // If it's not a cube, do nothing
            Debug.Log ("You've hit a cube");
        }
        else
        {
            // Return the name of the object that was hit
            Debug.Log ("You've hit " + hit.collider.gameObject.name);
            // Change that object's color to a random new color
            hit.collider.gameObject.GetComponent<Renderer> ().material.color = new Color (Random.value, Random.value, Random.value);
        }

        // check if the hit object contains a SwitchSize component
        if (hit.collider.gameObject.GetComponent<SwitchSize> () != null)
        {
            // If it does, call the SizeCycle function
            hit.collider.gameObject.GetComponent<SwitchSize> ().CycleSize ();
        }
    }
}

As you can see, it first creates a ray from the camera to the mouse cursor, and then checks if it hits anything. If it does, it checks if the object is named "Cube", and if it is, it just tells us that we've hit a cube. Otherwise it outputs the name of the object that was hit, and then changes its color to a random new color by accessing its Renderer component, which itself contains a Material component that defines the color of the object.

In a second if clause, it checks if the object that was hit contains a SwitchSize component, and if it does, it calls the CycleSize () function that we've created earlier.

Now we just need to update the Update () function to call our new ClickFunction () whenever the mouse has been clicked:

MouseCaster.cs
void Update ()
{
    // Check if the mouse button has been clicked
    if (Input.GetMouseButtonDown (0))
    {
        // execute the ClickFunction
        ClickFunction ();
    }
}

Save it, and try it out! You can now click on any object in the scene to change its color, or if it's a cube, change its size by calling its own function for that.

This is a more direct interaction method which you can use if you don't need to change the camera position or rotation, i.e. when you plan all visible and interactive objects to be within the camera's field of view. It's up to you now to decide which method makes more sense for your projects.

Good Luck!

You should now be ready to tackle the remaining tutorials from a previous workshop that was specifically addressing VR in Unity:

unity-vr-et-workshop/3-runtime/

Please try to complete them as best you can, as each one teaches you a fundamental block of what's necessary to build an experiment in Unity, VR or not.

Don't be discouraged if something seems hard — the whole point of this seminar is to try things out yourself, and ask for assistance if you can't proceed. You will need many of the components taught on these two websites to build a good experiment during the next two days, so it's important to get a good grasp of them.

Good luck!

Help with conversion simulated VR

The next page on this site (4•Coroutines) will show you a non-VR version of the Coroutines tutorial from the other site. You can use this as a reference for how to convert the other tutorials to non-VR by carefully noticing the differences between the two versions.