Working With GC Variables

Sorting by A-Z? No problem.

The documentation has moved to: https://mitschmr-studios.io/documentation/api-guides/workingwithgcvariables.html

This version will no longer be updated and maintained.

Sooner or later you may get into a situation where you need to have something sorted according to certain rules, like name (A-Z) or size descending. Another case may be that you need to only select variables where certain rules apply, like the name consists of this and that character.

This tutorial focuses exactly on this topic, introducing you to LINQ and Lambda to help you.

Prerequisites

  • Install Unity

  • Install IDE (I use Visual Studio 2022)

  • Import Game Creator

Recap

I have covered GC variables in my own words in a previous tutorial, there is also the official documentation. Thus I will not go much further into the details regarding this topic.

LINQ

You may ask yourselves what LINQ is. The letters stand for Language Integrated Query and the feature is meant to provide a way to get data from a data source. The data source can heavily vary for each use case, but in terms of using it within Unity, we most likely only work with lists or arrays of objects. LINQ requires the data source to inherit from the IEnumerable<T> interface, may that be directly or indirectly (from a class that inherits from it is also valid). This tutorial focuses on working with lists, because they implement this interface and are therefore ready to work with.

Here is an example of a small LINQ statement:

using System.Linq;

// Specify the data source.
List<int> numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

// Define the query expression.
var numQuery =
    from num in numbers
    where (num % 2) == 0
    select num;

// Execute the query.
foreach (int num in numQuery)
{
    Debug.Log(num);
}

// Output.
// 0, 2, 4, 6

What this does is, from the specified list, it selects the numbers that when divided by two don't have a rest and then prints them to the Unity console.

The query expression is not executed until the variable it is written to is used or an operation is executed on the query, like with a Lambda expression and the ToList() method (we will see an example later).

You may notice that the second part, the query, looks pretty similar to an SQL (for those who have worked with it). I personally don't like SQL that much, so let's go on to the second topic.

Note: If you want to learn more about LINQ, please visit the official documentation. A list of all LINQ methods can be found here.

Lambda

Lambda expressions are anonymous functions that are mostly used to create small functions without writing an actual method with the whole syntax. For this tutorial, we will use the so called expression lambda, which we will use inside a method to pass the requiremements for the result we seek.

The expression lambda looks like this:

(input-parameters) => expression

This means that it takes something as an input and then works with that. Combining the LINQ statement from above with lambda, the statement can be rewritten to the following code:

using System.Linq;

List<int> numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

var numQuery2 = numbers.Where(num => num % 2 == 0);

foreach (int num in numQuery2)
{
    Debug.Log(num);
}

// Output.
// 0, 2, 4, 6

The Where() method is part of the System.Linq namespace and accepts a lambda expression that returns a boolean value. In our case, for each number in the list, we want to check if the number divided by two has zero rest. If that is true, the Where() method returns this number and adds it to the numQuery2, which will then be printed to the console.

Examples

Now that we have learned the basics of LINQ and Lambda, let's see some real world examples.

Sorting numbers

Imagine that you have a list variable with float values in there and you want them sorted (ascending) by size:

The code used here can easily be converted to an action. We require a reference to this list variables component and then sort the variables (which are a list of a certain type and thus queryable). In this case we order them by the value of the number variable and pack it back to a list (because it would return something else than a list, so we have to convert it back).

public ListVariables sourceNumbers;

void Start()
{
    sourceNumbers.variables = sourceNumbers.variables.OrderBy(num => num.Get<float>()).ToList();
}

Selecting gameobjects with a certain letter in the name

Let's take again a list variable, but this time of type gameobject. We now want to only have the gameobjects that have the letter 1 in the name.

The code to use:

public ListVariables sourceGameObjects;
public string letterToSearchFor = "1";

void Start()
{
    sourceGameObjects.variables = sourceGameObjects.variables.Where(g => g.Get<GameObject>().name.Contains(letterToSearchFor)).ToList();
}

Ordering local variables from gameobjects in list variable

We can even get a component on one of the gameobjects in the list variable and look for a value in there to compare. This example sorts a list variable according to the value of the local number variable with the name "float" in descending order.

The list variable:

One of the local variables:

The code:

public ListVariables sourceGameObjects;

void Start()
{
    sourceGameObjects.variables = sourceGameObjects.variables.OrderByDescending(g => (float)((GameObject)g.Get()).GetComponent<LocalVariables>().Get("float").Get()).ToList();
}

Last updated