Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Gamasutra: The Art & Business of Making Gamesspacer
arrowPress Releases







If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Unity C#: Improved Out Parameters (C# 7.0)

by Ruben Torres Bonet on 03/30/20 10:31:00 am   Expert Blogs   Featured Blogs

4 comments Share on Twitter    RSS

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

Today I'm starting a new series of short posts about neat C# features that many Unity game developers are missing on. In this post, you will learn about the improved Unity C# out Parameters feature that is available since C# 7.0.

When programming your game, you'll often run into the need of returning multiple values within from a function.

Traditionally speaking, you have several ways to return multiple values.

In C++ is very common to use pointers/references as a way to return modified or even new variables. This often comes with requiring strong naming conventions to make it clear the function will modify these variables, e.g:

int Raycast(const Vector3& Direction, const Vector3& Position, HitResult** OutHitResult);

Another approach is to create aggregating structures that contain all the data you want to return. This method is verbose, but having named variables increases code clarity, e.g:

struct RaycastHitResult
{
  int NumberTotalHits;
  Collider FirstTargetHit;
}
RaycastHitResult Raycast(const Vector3& Direction, const Vector3& Position);

On top of this, some languages offer tuples. C# has great support for tuples as we'll see in an upcoming post.

But as of today, I'll show you a neat variation C# offers you to return multiple values: Unity C# out parameters.

Quick Navigation

What Are Unity C# Out Parameters?

How Did C# 7.0 Improve C# Out Parameters?

Examples

1. Unity Raycasting

2. C# Data Parsing

3. C# Dictionaries

What's Next?

What Are Unity C# Out Parameters?

C# lets you use the out keyword in function parameters to make the programmer aware those variables will be initialized and set within that function.

In other words: you pass the function a variable that the function will set for you.

You can have as many out parameters as you want, which makes them useful to return multiple parameters within a function.

They existed for a long time, but it turns out C# 7.0 improved the way you and I work with these Unity C# out parameters.

Let's see how.

How Did C# 7.0 Improve C# Out Parameters?

Till C# 7.0, you had to declare your variables before passing them to the function you're invoking.

This often required an extra line per out variable you want to pass, such as:

ChatMessageType type;
ServerGameLoop.ClientInfo target;

var text = ParseMessage(from, message, out type, out target);

if (type == ChatMessageType.Whisper)
{
  // ...
}

This specific Unity C# out parameter improvement allows us, game developers, to declare these out variables inline along the function invocation.

The scope of the inline-declared variables is exactly the same as it used to be when declaring them before the function call.

And you can declare these inline out parameters with an explicit type or by using automatic type inference (var).

This way, you can turn the previous example into:

Either this:

var text = ParseMessage(from, message, out var type, out var target);
if (type == ChatMessageType.Whisper)
{
  // ...
}

Or this:

var text = ParseMessage(from, message, out ChatMessageType type, out ServerGameLoop.ClientInfo target);
if (type == ChatMessageType.Whisper)
{
  // ...
}

Even though the Unity API barely uses C# out parameters, I certainly see many Unity projects using those in their code base. That's why this post is relevant for many of you, Unity game developers.

Let's see some examples.

Examples

1. Unity Raycasting

Raycasting has many applications, such as for AI to detect line of sight.

In Unity, you cast rays through the Physics API.

Here's the C# 7.0 transformation:

From:

RaycastHit raycastHit;
if (Physics.Raycast(cosmicRay, out raycastHit))
{
  Debug.Log("Hit ya " + raycastHit.collider.name);
}

To:

if (Physics.Raycast(cosmicRay, out RaycastHit raycastHit))
{
  Debug.Log("Hit ya " + raycastHit.collider.name);
}

* Avoid using Physics.Raycast, as this version allocates memory and is detrimental to performance. Use Physics.RaycastNonAllocinstead.

2. C# Data Parsing

Sometimes you have to do conversions from string to other types, such as when reading from a configuration file or user input.

C# makes this easy with TryParse, which uses an out parameter to give you what you wanted. here, we can profit from the improved Unity C# out parameters:

From:

int hitpoints;
if (int.TryParse(hitpointsString, out hitpoints))
{
  Debug.Log($"You're {hitpoints} hitpoints away from table flipping");
}

To:

if (int.TryParse(hitpointsString, out int hitpoints))
{
  Debug.Log($"You're {hitpoints} hitpoints away from table flipping");
}

The pattern same applies to floatdoublelong, etc..

3. C# Dictionaries

I love dictionaries.

C# dictionaries have the famous TryGetValue method, which can become quite verbose after using it so many times.

It gets old very quickly.

Suppose we have a dictionary that maps inventory slots to game objects representing items (I don't say this is a good idea, eh):

int slotId = 1;
var inventory = new Dictionary<int, GameObject>();

We can then improve our coding style...

From:

GameObject item;
if (inventory.TryGetValue(slotId, out item))
{
  Debug.Log($"Looted {item.name}");
}

To:

if (inventory.TryGetValue(slotId, out GameObject item))
{
  Debug.Log($"Looted {item.name}");
}

What's Next?

This improved version of C# out parameters is a neat little addition to remove verbosity from your code.

Some people will like it, some won't.

And that's fine. Just choose one style and stick to it.

In the next post in the C# series, I'll show you an additional way of returning multiple values with C# 7.0.

Till then, why don't you have a look at how Unity Addressables will save you from development pain?

~Ruben


Related Jobs

Question
Question — Remote, California, United States
[05.30.20]

Senior Gameplay Engineer (Unreal Engine, Work from Home)
Question
Question — Remote, California, United States
[05.30.20]

Senior Network Engineer (Unreal Engine, Work from Home)
Remedy Entertainment
Remedy Entertainment — Espoo, Finland
[05.29.20]

Senior Programmer
Remedy Entertainment
Remedy Entertainment — Espoo, Finland
[05.29.20]

Senior Rigging Artist





Loading Comments

loader image