Bite Sized Tech is a participant in Unity Affiliate Program, Liquid Web Affiliate Program, Hostinger Affiliate Program, Namecheap Affiliate Program, Envato Elements Affiliate Program, Adobe Affiliate Program and SteelSeries Affiliate Program under which we might earn commission when visitors use our Affiliate Links and makes qualifying purchases.


Methods in C# | Part 4 – In, Ref & Out Keywords | Unity Game Development Tutorial | How To Make A Game


In C#, when defining a Method with Parameters, you can tell the compiler about how you would like to access these said parameters, i.e

  • do you just want to create a copy of the passed arguments or
  • do you just want the memory address of the passed argument or
  • whether you only want read access to the data stored within the passed argument or
  • do you want both read and write access to the data or
  • maybe do you only want write access to the passed argument

Knowing how you are accessing the passed arguments for the defined parameters of a method is really important

and to do this in C#, we use the in, ref and out Keywords.

Now, if you don’t know anything about methods, then i suggest that you start from the first article

I’ve divided my explanation of Methods in 4 different articles as otherwise the articles would be too long.

List Of All Articles To Master Methods In C#

In this article, I’ll will be talking about in, ref and out Keywords and will be covering

  • The concept of Passing Arguments By Value and By Reference and the Difference between these two approaches.
  • Then we will go over the in, ref and out Keywords and understand what they are and the differences between them.
  • While going over them, we will also code and see how to use the in, ref and out keywords in your C# scrpits in Unity.

So, without further ado, let’s dive directly into it!


This Post is Part of : How To Make A Game Series where I’ll be showing you how to become a game developer and will be going over the basics of Game Development, Step by Step, using the Unity Game Engine and C# Scripting Language to script the Game Logic.

If you are new to Game Development or Programming in general you should definitely go through this Unity Tutorials article series as it will set give you a kick-start towards becoming an exceptional Unity 2D or 3D Video Game Developer.

Game Development is one of those professions that needs a couple of different professions to work in conjunction to be done right.

If you are someone completely new to Game Development and don’t know much about it,

then you might be interested in the these articles on Intro To Game Development and Game Development Softwares (Game Engines, 2D Art, 3D Art, Code Editor, DAW)

in which i have talked about the Art of Game Development, Various Roles in Game Dev, Softwares you will need based on the different categories of Game Development

and about the Recipe of Success that will help you in having the right mindset as you get into Game Dev.


Methods - Part - 4 - Unity C# Game Development Tutorial - How To Make A Game - Featured Image


What we have Covered So Far About Methods inn C#

In the last three articles we have talked about

  • What methods are and how we can define a method
  • How you can create methods with Multiple, Required and Optional Parameters and pass arguments using Named Arguments
  • and lastly we also talked about the topic of Method Overloading

Now, i know that all these technical stuff can be really boring

but i want to make sure that i tell you about the major differences between these concepts

so that you have strong fundamentals

which will stop you from making mistakes that will make you redo a huge part of your code.

and maybe even if you made those mistakes in the future because you know everyone’s human

at least you would understand why your game is behaving the way it is, if you know these concepts.

So beware, this is going to get a bit technical :p


Passing Arguments By Value Or By Reference | Unity C# Game Development Tutorial

let’s move forward and talk about the concept of Passing Arguments by Value or by Reference.

Now, without going into too much detail,

when you pass an argument by Value

what you are doing is, you are making a copy of the variable or value that you passed in as the argument.

This is what we have been doing so far.

while when you pass an argument by Reference

instead of making a new copy,

you are pointing towards the memory location where the data of the passed argument is stored.

Now, by default any argument that you pass in the method call will be by value even if the variable is a Reference Type.

When you pass arguments by value

any operations that you do on the copy of the passed argument

will not affect the data inside the variable that you passed as the argument.

They are two completely different set of data,

so don’t confuse that.

Now when you pass by reference

you only have a single copy of data

that is being referenced by n number of variables.

So, if a change is made to this single copy of data through any one of the variables

this change in data, like a domino effect

will be seen in all the variables


Difference Between Value Types Or Reference Types And Passing Arguments By Value Or By Reference in C#

There is another concept in C# and that is the concept of Value Types and Reference Types

Now with the wordings being so similar

i.e. The Concept of Passing by Value or by Reference

and The Concept of Value Types or Reference Types

it is not weird that so many people start getting confused

and start mixing these two completely different concepts with each other

so let me stop you from doing that before you even start

When you see any place that’s talking about Value Types and Reference types

what they are talking about are the main categories that the Types in C# are divided into

while when you see any place talking about Passing by Value or Passing by Reference

they are talking about, how the arguments are being passed in a method call.

A lot of beginners have a misconception that

Reference Types when used as arguments are by default Passed by Reference, which is not true

as i have said before, everything that you pass in an argument by default is by Value

We can go into more detail about Value Types and Reference Types

and talk about how all that works but i think it will be relatively complex for beginners

so let’s talk about that in another article series.



in Keyword | Unity C# Game Development Tutorial

Now moving forward, as i said in the introduction

In C#, to pass an argument by Reference,

we can use the in, ref or out Keywords

Now let’s look at this 3 keywords one by one

When you use the in keyword to pass the argument

this passed argument will be Read-Only

and you will not be able to modify it’s content inside the method’s code block.

To show this, let’s first declare a method named modifyEnemies

and define an int parameter named numberOfEnemies in it, with the in keyword before it

Now let’s try to modify this variable inside the method’s code block, like this

// Everything below is inside a Class.

private void modifyEnemies(in int numberOfEnemies)
{
  numberOfEnemies = 5;
}
in keyword - VS Code Error Hover Box - Unity C# Game Development Tutorial-min

As you can see in the image above, we get a Compile Time Error as shown by the Red Underline

and this is because we are trying to modify a Read Only variable.

So, let’s remove it.

Next, when you want to use the in keyword to pass an argument,

the Variable or Value that is being passed as argument

has to be declared and initialized before the method call.

So, let’s initialize a variable named enemyCount and set it to 10

and log it’s value in the Unity Console, like this

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
}

private void modifyEnemies(in int numberOfEnemies)
{

}

Unlike ref and out keywords when using the in keyword

you can choose to not explicitly type the in keyword before the passed argument in the method call

But i would suggest that you don’t do this.

As explicitly typing the in keyword will make your code much more readable

and also make sure that you know what type of argument you are sending,

just by looking at your method call without having to go and look at the method definition

So, now let’s make the method call with the enemyCount variable as argument using the in keyword

and inside the method’s code block, log it’s value like this.

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(in enemyCount);
}

private void modifyEnemies(in int numberOfEnemies)
{
  Debug.Log("Number Of Enemies: " + numberOfEnemies);
}

With this we would be able to see if the argument is being passed correctly or not

Now let’s go to unity and check the logs.


Unity Log | in keyword | Unity C# Game Development Tutorial

in keyword - Unity Log - Unity C# Game Development Tutorial-min

As you can see both the logs show the same value

which means everything is working correctly.


ref keyword | Unity C# Game Development Tutorial

Back to the code, now let’s move forward to the ref keyword.

The ref keyword will let you read and modify the value of the argument

that you have passed by Reference inside the method call

just like the in keyword the argument that is to be passed

needs to be declared and initialized before the method call.

unlike the in keyword, it is mandatory to explicitly type ref in both the places

i.e. Before the Parameter in the Method Definition and also Before the Argument in the Method Call

So let’s modify the code we wrote previously and change the in keyword to ref as shown below

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(ref enemyCount);
}

private void modifyEnemies(ref int numberOfEnemies)
{
  Debug.Log("Number Of Enemies: " + numberOfEnemies);
}

also let’s suppose that the argument you are passing i.e. enemyCount is Referencing Memory Location x of your memory.

Now this memory location stores an integer value 10.

So when we are using the ref keyword,

if we make any changes to numberOfEnemies

we won’t see any errors

like what we saw with the in keyword

and this change that we did, will be done to Memory Location x

as the numberOfEnemies parameter is referencing that memory location

just like the enemyCount variable that we passed as argument.

So, if we were passing by value instead

numberOfEnemies and enemyCount variables would not be referencing the same memory location

and there would be 2 copies of the integer with value 10 in our memory at different memory locations

with each of these variables referencing one of these memory location

but by using the ref keyword,

we are not making another copy and both the variables are referencing the same memory location

Now let’s modify numberOfEnemies like this.

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(ref enemyCount);
}

private void modifyEnemies(ref int numberOfEnemies)
{
  Debug.Log("Number Of Enemies: " + numberOfEnemies);
  numberOfEnemies = 5;
}

When we modify the value of numberOfEnemies in the method’s code block

any other variable that is also referencing memory location x

will also have their values changed

as all these variables including enemyCount and numberofEnemies variables are all referencing a single copy of data that is located at memory location x

and you just changed that single copy of data.

Now, let’s write some Debug.Logs that will show you that

we are truly referencing the same copy of data in both these variables.

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(ref enemyCount);
  Debug.Log("Modified Enemy Count: " + enemyCount);
}

private void modifyEnemies(ref int numberOfEnemies)
{
  Debug.Log("Number Of Enemies: " + numberOfEnemies);
  numberOfEnemies = 5;
  Debug.Log("Modified Number Of Enemies: " + numberOfEnemies);
}

Now let’s execute this piece of code in Unity and check the logs



Unity Log | ref keyword | Unity C# Game Development Tutorial

ref keyword - Unity Log - Unity Game C# Development Tutorial

As you can see in the image above,

the first log in which we are logging enemyCount’s default value shows 10

then the second log inside the method’s code block where we are logging numberOfEnemies show 10

then the third log is after we modified numberOfEnemies and it show 5

and then we have the fourth log in which we are logging enemyCount variable after the method call and it is also showing 5.

This clearly shows that both these variables are referencing the same memory location

because if they did not then enemyCount would still be 10 in the fourth log.


out keyword | Unity C# Game Development Tutorial

Now let’s move forward to the out keyword.

A normal method uses the return keyword to send back a value or variable of the defined return type to the line from which we called the said method.

But the limitation here is that, you can only send back a single value or variable.

The out keyword can be used when you want to return more than one value or variable from the method.

what you need to know is that, the out keyword only allows you to set a value to the passed argument.

Before setting the value to this passed argument inside the method’s code block

you won’t be able to read the data inside the passed argument.

to show this In the Start Method

let’s modify the method call again and change the ref keyword to out

and then in the method definition do the same

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(out enemyCount);
  Debug.Log("Modified Enemy Count: " + enemyCount);
}

private void modifyEnemies(out int numberOfEnemies)
{
  Debug.Log("Number Of Enemies: " + numberOfEnemies);
  numberOfEnemies = 5;
  Debug.Log("Modified Number Of Enemies: " + numberOfEnemies);
}
out keyword - VS Code Error Hover Box - Unity C# Game Development Tutorial

and as you can see in the image above,

if we try to do this we will get a Compile Time Error in the first log

but we don’t get this error in the second log

because the second Debug.Log is done after setting the value for the out parameter i.e. numberOfEnemies.

So let’s remove the first log.

// Everything below is inside a Class.

void Start()
{
  int enemyCount = 10;
  Debug.Log("Enemy Count: " + enemyCount);
  modifyEnemies(out enemyCount);
  Debug.Log("Modified Enemy Count: " + enemyCount);
}

private void modifyEnemies(out int numberOfEnemies)
{
  numberOfEnemies = 5;
  Debug.Log("Modified Number Of Enemies: " + numberOfEnemies);
}

Next, when we are using the out keyword

it is okay to not initialize the argument’s value.

so to test that let’s remove the initialization of 10 from enemyCount and remove the log below it

like this.

// Everything below is inside a Class.

void Start()
{
  int enemyCount;
  modifyEnemies(out enemyCount);
  Debug.Log("Modified Enemy Count: " + enemyCount);
}

private void modifyEnemies(out int numberOfEnemies)
{
  numberOfEnemies = 5;
  Debug.Log("Modified Number Of Enemies: " + numberOfEnemies);
}
out keyword - Final Code - Unity C# Game Development Tutorial

and as you can see in the image above, we didn’t get any compile time errors

So until now, what we have done is

we have declared enemyCount variable but we did not initialize it.

Then we used it as the out parameter when calling the method.

Now when the method’s code block is executed

it will set value to numberOfEnemy out parameters

And as numberOfEnemy parameter is actually being passed reference of enemyCount variable

that is not local to the method

the values inside enemyCount variable will persist even after we leave this method.

Hence allowing us to return more than one value or variable, if we declare more than one out parameter.

With that done, another thing is that

you need to assign values to all the out parameters before leaving the method

otherwise you will get a compile time error, saying that

“out parameter x needs to be assigned before control leaves the current method.”

Now, let’s go to unity and check the logs.


Unity Log | out keyword | Unity C# Game Development Tutorial

out keyword - Unity Log - Unity C# Game Development Tutorial

As you can see the both the logs show value of 5

which means that the out keyword is working as intended.



Limitations When Using in, ref and Out keywords | Unity C# Game Development Tutorial

Now there are Limitations on how you can use these 3 keywords.

First is that, you can’t use them in Async methods,

which you define by using the async modifier.

Second, you can’t use them in Iterator methods,

which include a yield return or yield break statement.

and Third, there are some limitations regarding their use in extension method

but for now skip that as extension method is not a beginner concept.

Now, i know that this would not make much sense right now as i have not covered these topics yet

but i wanted to pass this information here so you at least know that these limitations do exist

when it comes to in, ref and out keywords.

With that i think i have covered everything that can be considered as beginner level in respect to methods

and we can finally move on to other topics from the next article.


List Of All Articles To Master Methods In C#


Conclusion

Well folks, that does it for this article.

i hope that this information will be helpful to you.

Share this post and follow us on Social Media platforms if you think our content is great, so that you never lose the source of something you love.

If you like the content do go through the various articles in How To Make A Game Series that this post is a part of and also go through the other series we have on Bite Sized Tech.

Also we have a YouTube Channel : Bite Sized Tech where we upload Informational Videos and Tutorials like this regularly. So, if you are interested do subscribe and go through our Uploads and Playlists.


Follow Us On Social Media


Goodbye for now,
This is your host VP
Signing off.