Return in Unity

How to use Return in Unity

In Scripting Basics by John FrenchPublished Updated 2 Comments

When you call a function in Unity, usually all of its contents will be executed from start to finish.

Meaning that everything in the body of the function, which is all of the code between the two brackets, will run line by line until the end of the function’s scope is reached.

Like this:

void MyFunction()
{
    // This happens first,
    // then this...
    // by this point, the function is finished.
}

However, you might not always want everything that’s in your function to run every time it’s called.

Sometimes, you might want to do one thing, but not another.

Or maybe you need to check that something exists, before trying to do something with it.

It’s possible to include or exclude different parts of your functions by using If Statements, which are conditional checks that execute blocks of code depending on whether something is true or false.

Like this:

void MyFunction(bool doTheThing)
{
    // Start here
    if (doTheThing == true)
    {
        // Maybe do this
    }
    // Then finish with this
}

Which can be useful if you only want to execute part of a function conditionally, allowing the rest of it to carry on regardless.

But, what if you don’t just want to include or exclude part of your function based on a conditional check?

What if, instead, you want to completely exit out of a function early when reaching a certain point?

To do that, you’ll need to use the Return statement.

How to use Return to stop a function in Unity

The Return statement exits out of a function as soon as it’s called.

Technically, this is referred to as returning control back to the caller, meaning that everything in the function that takes place after the statement doesn’t get executed.

void MyFunction()
{
    // This line is read,
    return;
    // This line is unreachable.
}

This can be useful for stopping a function if continuing under certain circumstances would cause an error, such as if your entire function depends on a reference that must be set before you can run it.

Like this:

GameObject otherObject;

void MyFunction()
{
    if (otherObject == null)
    {
        return;
    }

    // The function only gets this far if the object reference is not null.
}

But since, in this case, you have to put return inside of an if statement anyway, why not just place your entire function inside of an if condition?

In this example, you could do that, and you’d get the exact same result as using return.

However, the difference between using an if condition and return is that, while if statements can be used to conditionally run part of a function, which might be all of it, Return can be used to exit out a function before it would have otherwise finished.

Which can be useful if you want the option of ending your function at multiple different points which would, otherwise, require nested if statements to do the same thing. 

Like this:

void MyFunction()
{
    // Do something

    if (a == true)
    {
        // stop here
        return;
    }

    // Do something else

    if (b == false)
    {
        // stop here
        return;
    }
}

Which can sometimes be easier to read and easier to follow than trying to encapsulate your code in conditional checks.

But, return isn’t only used for stopping a function.

It’s also used to pass data back to the script that called it in the first place.

How to use Return in Unity to return data

When you first start writing functions in Unity they’ll probably have a void return type.

Like this:

void MyFunction()
{
    // Do something
}

Which means that the function doesn’t return any data, it just happens when it’s called.

However, it’s possible for a function to return information by changing its return type to the type of value or object that you’d like the method to give back to you.

For example, a function can return a true or false boolean value.

Like this:

bool MyFunction()
{
    int number = Random.Range(0, 10);

    if (number <= 5)
    {
        return true;
    }

    return false;
}

Or it can be used to return a number,

Like this:

int MyFunction()
{
    int number = Random.Range(0, 10);
    return number;
}

Or you can use a function to return another type of object, such as a script or a struct.

Like this:

MyStruct MyFunction()
{
    return new MyStruct();
}

Just like when returning nothing, using the return statement with a data type ends the function on that line, meaning that, if it’s called, nothing below the return statement will be executed.

While, on the other end, the caller, which is the code that called the function in the first place, can use the returned data directly, such as to set a boolean, a number or a reference to an object.

Like this:

void Start()
{
    bool numberWasUnderFive = MyFunction();
}

bool MyFunction()
{
    int number = Random.Range(0, 10);

    if (number <= 5)
    {
        return true;
    }

    return false;
}

This can be useful for creating a basic success or failure callback, where other functions might return true or false depending on if they were able to complete their task successfully.

This would allow a controlling function to exit early if it failed at a particular point, such as if an object that the player was trying to put down couldn’t be placed in a particular position.

Like this:

void TryPutDownObject()
{
    if(CheckIfCanPlace() == false)
    {   
        // Object was not clear.
        return;
    }

    if(WasPutDown() == false)
    {
        // Object was not put down
        return;
    }

    // Object was put down successfully
}

public bool CheckIfCanPlace()
{
    // Check if the area is clear
    if(positionIsClear)
    {
        return true;
    }
    return false;
}

public bool WasPutDown()
{
    // Try to put the object down
    if(wasPutDown)
    {
        return true;
    }
    return false;
}

How to return multiple values from a function

Normally, a function can only return one type of value, which is defined by its return type.

However, there may be times when you want to pass additional data back when a function is called.

This can be done by using the out keyword which, basically, reverses a function’s parameter, which would normally pass data into the method, so that it passes data back out instead.

Like this:

void Start()
{
    bool numberWasUnderFive = MyFunction(out int result);
    Debug.Log(result);
}

bool MyFunction(out int result)
{
    int number = Random.Range(0, 10);

    if (number <= 5)
    {
        result = number;
        return true;
    }

    result = number;
    return false;
}

You’ll find examples of this in some of Unity’s own functions, such as Raycast, which returns a Boolean value, which is what allows you to use it in an if statement, but also passes back Raycast Hit information using the out keyword.

Return can be extremely useful for stopping an entire function once you’re done with it.

But, you might not always want to stop the whole function, you might only want to break out of part of it, such as an iteration in a loop.

How to break out of a loop in Unity

While Return exits out of an entire function, sometimes you may only want to exit out of an iteration of a loop instead.

There are two ways to do this, either by using the Continue statement or the Break statement.

Return vs Break

The Break statement can be used to terminate an iteration statement which, put simply, is any kind of loop, such as a for, foreach, or a while loop.

This can be useful when, for example, the function of your loop is to search through a list of objects and stop when it finds the one that it’s looking for.

Unlike when calling Return, which exits out of the entire function, any code that exists after the loop that you’re breaking out of will still be run.

Like this:

[SerializeField] GameObject[] gameObjects = new GameObject[10];

void Start()
{
    FindFirstObjectInArray(gameObjects);
}

void FindFirstObjectInArray(GameObject[] arrayOfObjects)
{
    GameObject foundObject = null;

    for (int i = 0; i < arrayOfObjects.Length; i++)
    {
        Debug.Log("Searched entry number: " + i);
        if (arrayOfObjects[i] != null)
        {
            foundObject = arrayOfObjects[i];
            break;
        }
    }

    if (foundObject == null)
    {
        Debug.Log("No object was found.");
        return;
    }

    Debug.Log("Found object: " + foundObject);
}

Break can be useful for exiting out of a loop once it’s already done what it’s supposed to do.

However, sometimes, you might not want to stop a loop at a specific entry, sometimes you might want to skip over it instead.

For that, you’ll need the Continue statement

Break vs Continue

Continue can be used to stop executing a particular iteration of a loop and move on to the next one.

Basically, it skips the current iteration at the point it’s called.

This is different to Break, which simply cuts the entire loop short, stopping all remaining iterations in the process.

So when are you likely to use continue?

While break can be useful for stopping a loop because you’ve already found what you’re looking for, continue can be useful for checking every element in an array or list, but skipping particular ones if they don’t meet the right conditions.

An example of this might be to count all of the elements in an array that are empty, by checking each iteration to see if it’s null and, if it is, using the continue statement to skip to the next iteration before the counter is incremented.

Like this:

[SerializeField] GameObject[] gameObjects = new GameObject[10];

void Start()
{
    CountEmptyEntries(gameObjects);
}

void CountEmptyEntries(GameObject[] arrayOfObjects)
{
    int numEmpty = 0;

    for (int i = 0; i < arrayOfObjects.Length; i++)
    {
        Debug.Log("Searched entry number: " + i);
        if (arrayOfObjects[i] != null)
        {
            continue;
        }

        numEmpty++;
    }

    Debug.Log(numEmpty + " of the entries are empty");
}

While, in this basic example, it is possible to create the same effect by simply placing your code inside of the if condition, such as only counting up if the object is null, having the option to return, continue or break by writing a single word can make your code easier to write and easier to read.

Which, as your project gets more and more complex, can be extremely useful for keeping things simple.

Now it’s your turn

Now I want to hear from you.

How are you using return in your project?

Have you been using continue and break in your loops, or are they completely new to you?

And what have you learned about controlling the flow of logic in your game that you know someone else would find useful?

Whatever it is, let me know by leaving a comment.

John French profile picture

by John French

Game audio professional and a keen amateur developer.

Get Game Development Tips, Straight to Your inbox

Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

Image attribution

Comments

Leave a Comment