# Converting To GC Variables

{% hint style="danger" %}
The documentation has moved to: <https://mitschmr-studios.io/documentation/api-guides/convertingtogcvariables.html>

This version will no longer be updated and maintained.&#x20;
{% endhint %}

In this tutorial I want to show you how you can convert normal C# variables to Game Creator variables so you can use the scripts in a more versatile way.&#x20;

### Prerequisites

* Install Unity
* Install IDE (I use Visual Studio 2019)
* Import Game Creator
* Import the scripts you want to change

### Game Creator Variables

#### Overview

Game Creator has a powerful variable system which I won't explain in details, you can read more about it on the [offical site](https://docs.gamecreator.io/game-creator/game-creator/variables).&#x20;

The variable system has 9 different types (each linked with a reference what it is):&#x20;

* [Bool](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool)
* [Color](https://docs.unity3d.com/ScriptReference/Color.html)
* [Number](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types) (float)
* [GameObject](https://docs.unity3d.com/ScriptReference/GameObject.html)
* [Sprite](https://docs.unity3d.com/ScriptReference/Sprite.html)
* [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
* [Texture2D](https://docs.unity3d.com/ScriptReference/Texture2D.html)
* [Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html)
* [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html)

This means we can convert variables of the these types to their GC variables counterpart.&#x20;

#### Code Perspective

From the code perspective, there are two different things we need to take in view. One is the general variables selection, where you can **only** select a variable and optionally add a filter of which variable types are allowed. The second one is where you specify a fix variable type and allow the option of adding a value of this type as well (not only GC variables). Let's take a look at the first one:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    public VariableProperty variable = new VariableProperty();
}
```

This little script gives us this result:&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MatX8UoyqLdk_L0D1Z6%2F-MatZ5KP4xr5yEDsKqNX%2Fimage.png?alt=media\&token=1edf0cea-3460-4cd6-a5bb-01787b2c1325)

Let's take a look at the code:&#x20;

* When working with the Game Creator variable system, you need to add the `GameCreator.Variables` namespace at the top
* The class `VariableProperty` is a generic variable class that allows you to select any variable of any type, may that be a global, local or list one

As I have written before, you can apply a filter to this type of variable. For this, you need to add this code: `[VariableFilter(Variable.DataType.<VariableType>)]`, where \<VariableType> is one of the types mentioned in the overview. Your scripting solution (IDE) should suggest them to you if you don't know them anymore. Let's say, we want to add a filter to only include GameObject variables, the code looks like this:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    [VariableFilter(Variable.DataType.GameObject)]
    public VariableProperty variable = new VariableProperty();
}
```

With the selection now looking like this:&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MatX8UoyqLdk_L0D1Z6%2F-Mata8no0OcQ_xB2cq54%2Fimage.png?alt=media\&token=4bdb8604-59c5-423d-a2f3-9ec42e65f188)

We only have one GameObject variable in our global variables, so that's correct.&#x20;

Now for the second part (which is most likely the more interesting one for you), for each variable type mentioned in the overview, Game Creator has a type that let's you specify a value of this type or a global, local or list variable value. Here you can see what I mean:&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MatX8UoyqLdk_L0D1Z6%2F-MatbCw-zVysQonWudVc%2Fimage.png?alt=media\&token=d71eda92-8392-4688-a0f2-b36a4d5bf200)

In the dropdown, additional to the usual **Use Global/Local/List Variable** you have the entry **Value**, which is what I am talking about. The code is this one:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    public GameObjectProperty goVariable = new GameObjectProperty();
}
```

I have replaced `VariableProperty` with `GameObjectProperty`. There are the following classes you can use:&#x20;

* BoolProperty
* ColorProperty
* NumberProperty
* GameObjectProperty
* SpriteProperty
* StringProperty
* Texture2DProperty
* Vector2Property
* Vector3Property

When you select the dropdown value for selecting a variable and not the **Value** entry, Game Creator already filters for exactly this type of variable so you can not choose anything else that does not fit.&#x20;

#### Variables Access

Even though there is already a page on the [official documentation](https://docs.gamecreator.io/game-creator/systems/game-creator-api/variables-access) about this topic, it does not cover everything that I am talking about in this guide. That's why there is additional information following.&#x20;

Getting back to the first type of variables, if you need to access a `VariableProperty`, you need to call the method `Get(invoker)`, where the optional parameter invoker is of type `GameObject` and usually the gameobject the script is on. Of course you can also set the invoker to `null` (which means empty). If we take a look at the previous example of the GameObject, it looks like this:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    [VariableFilter(Variable.DataType.GameObject)]
    public VariableProperty variable = new VariableProperty();

    private void Start()
    {
        // Without invoker parameter.
        GameObject go = (GameObject)this.variable.Get();
        
        // With invoker parameter set to this gameobject.
        GameObject go2 = (GameObject)this.variable.Get(this.gameobject);
        
        // With null invoker parameter set to null.
        GameObject go3 = (GameObject)this.variable.Get(null);
    }
}
```

You may wonder what the `(GameObject)` means. The `VariableProperty.Get()` method returns an object of type [object](https://docs.microsoft.com/en-us/dotnet/api/system.object), which we can not use directly. In order for us to use it, we need to convert (cast) it to the desired type (in this case GameObject).

Getting back to the second type of variables, we again take the example of the GameObject, but this time we use `GameObjectProperty`:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    public GameObjectProperty goVariable = new GameObjectProperty();

    private void Start()
    {
        // With invoker parameter set to this gameobject.
        GameObject go = this.goVariable.GetValue(this.gameObject);

        // With invoker parameter set to null.
        GameObject go2 = this.goVariable.GetValue(null);
    }
}
```

Using the `BaseProperty<T>.GetValue()` (BaseProperty\<T> is the base class of all GC variable classes) method we directly get the value already converted (casted) to the desired type. For instance, you use the `NumberProperty` class, you get a float value when using the `GetValue()` method. Note that we can **not** use this method without the invoker parameter, as this way is now obsolete and no longer supported, it may be removed in the future.&#x20;

{% hint style="info" %}
For the variable types **BoolProperty**, **ColorProperty**, **NumberProperty**, **StringProperty**, **Vector2Property** and **Vector3Property** you can set values in the ( ) brackets if desired.&#x20;
{% endhint %}

### Examples

#### #1

In this example, we convert three variables (float, GameObject, Color) to their GC counterpart so that we can still set our own values.&#x20;

Original code:

```csharp
using UnityEngine;

public class GCVariablesTutorial : MonoBehaviour
{
    public float number = 1;
    public GameObject go;
    public Color color = Color.red;
}
```

Original inspector:&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MatiXzR9JunNTek37UY%2F-Matjb-dstXA1SwRSG6u%2Fimage.png?alt=media\&token=363bc082-d569-40a8-a0d1-5f05bdf2eb7e)

New code:&#x20;

```csharp
using UnityEngine;
using GameCreator.Variables;

public class GCVariablesTutorial : MonoBehaviour
{
    public NumberProperty number = new NumberProperty(1);
    public GameObjectProperty go = new GameObjectProperty();
    public ColorProperty color = new ColorProperty(Color.red);
}
```

New inspector:&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-Matm8BEJ009xC28fjTN%2F-MatmCpcFDsmu56lFXxw%2Fimage.png?alt=media\&token=b92168c5-c61f-43ab-9563-c7ba801ca661)

#### #2

This example focuses on converting a "Graphic" variable to support selecting the target from a Game Creator variable:&#x20;

Original code:

```csharp
public class ActionGraphicColor : IAction
{
	public Graphic graphic;

	[Range(0.0f, 10.0f)]
	public float duration = 0.0f;

	public ColorProperty color = new ColorProperty(Color.white);

	// EXECUTABLE: ----------------------------------------------------------------------------

	public override bool InstantExecute(GameObject target, IAction[] actions, int index)
	{
		if (this.duration <= 0.0f)
		{
			if (this.graphic != null) this.graphic.color = this.color.GetValue(target);
			return true;
		}

		return false;
	}

	public override IEnumerator Execute(GameObject target, IAction[] actions, int index)
	{
		if (this.graphic != null)
		{
			Color currentColor = this.graphic.color;
			Color targetColor = this.color.GetValue(target);

			float startTime = Time.unscaledTime;
			WaitUntil waitUntil = new WaitUntil(() =>
			{
				float t = (Time.unscaledTime - startTime) / this.duration;
				this.graphic.color = Color.Lerp(currentColor, targetColor, t);

				return t > 1.0f;
			});

			yield return waitUntil;
			this.graphic.color = targetColor;
		}

		yield return 0;
	}
	
	// More code to come, but inspector related, not important for this example.
```

Original inspector:

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-Mb5A2O3MG3DGrzOEg3N%2F-Mb5vUlmhc43MpihGAuS%2Fimage.png?alt=media\&token=0de9481b-20a0-413f-a6c6-7fc5ba7eaa44)

New code:&#x20;

```csharp
public class ActionGraphicColor : IAction
{
	public GameObjectProperty graphic = new GameObjectProperty();
	[Range(0.0f, 10.0f)]
	public float duration = 0.0f;

	public ColorProperty color = new ColorProperty(Color.white);

	// EXECUTABLE: ----------------------------------------------------------------------------

	public override bool InstantExecute(GameObject target, IAction[] actions, int index)
	{
		if (this.duration <= 0.0f)
		{
			if (this.graphic != null) this.graphic.GetValue(target).GetComponent<Graphic>().color = this.color.GetValue(target);
			return true;
		}

		return false;
	}

	public override IEnumerator Execute(GameObject target, IAction[] actions, int index)
	{
		if (this.graphic != null)
		{
			Color currentColor = this.graphic.GetValue(target).GetComponent<Graphic>().color;
			Color targetColor = this.color.GetValue(target);

			float startTime = Time.unscaledTime;
			WaitUntil waitUntil = new WaitUntil(() =>
			{
				float t = (Time.unscaledTime - startTime) / this.duration;
				this.graphic.GetValue(target).GetComponent<Graphic>().color = Color.Lerp(currentColor, targetColor, t);

				return t > 1.0f;
			});

			yield return waitUntil;
			this.graphic.GetValue(target).GetComponent<Graphic>().color = targetColor;
		}

		yield return 0;
	}
	
	// More code to come, but inspector related, not important for this example.
```

Sharp eyes see the difference. Because the Game Creator variable we use is of type `GameObject` we have to get the `Graphic` component and apply the the settings to there.&#x20;

```csharp
// Old code to access the graphic variable.
this.graphic

// Replaced with.
this.graphic.GetValue(target).GetComponent<Graphic>()

// ----------------------------

// Old code to access the color property of the graphic variable.
this.graphic.color

// Replaced with.
this.graphic.GetValue(target).GetComponent<Graphic>().color
```
