# Inventory Custom Entries

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

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

In this tutorial, I want to show you how to extend the Game Creator inventory with custom entries.&#x20;

### Prerequisites

* Install Unity
* Install IDE (I use Visual Studio 2019)
* Import Game Creator
* Import and enable the Inventory module

### Game Creator Inventory

Before we begin, I want to talk a bit about the inventory of Game Creator. It is a module for Game Creator, which allows you to store items in it (as you would expect). It contains an [item catalogue](https://docs.gamecreator.io/inventory/inventory/inventory-window/catalogue) (the item store), a [types section](https://docs.gamecreator.io/inventory/inventory/inventory-window/types) for the types of items you have, a [recipes section](https://docs.gamecreator.io/inventory/inventory/inventory-window/recipes) for combining items to a new one and a [settings section](https://docs.gamecreator.io/inventory/inventory/inventory-window/settings). All of these sections are saved in a database in your project. The database is nothing else than a serialized scriptable object of type `DatabaseInventory`, which derives from `IDatabase`. To display it within an editor window, you need to access this serialized object and transfer the values to the according property fields. I will cover this in a later tutorial when we make new editor windows step by step (one with scriptable objects, another without).&#x20;

### Unity Editor Knowledge

In this tutorial we will, amother other things, change a script that derives from the `Editor`class. Normally, when a script derives from `Editor` and you want to start building your project, the build will fail. This is because the class `Editor` is not available in built versions of the game, only in the Unity Editor. We have to place the script in a folder with the name `Editor`, so it doesn't get included in the built game. But why the name `Editor`? Unity uses so called **Special folder names** to tread a folder's content in a special way. See [Unity Special Folders](https://docs.unity3d.com/Manual/SpecialFolders.html) for more information.&#x20;

### Script Architecture/Structure

In order to extend the inventory, we need to understand how the underlying script architecture. In the project window under `Assets --> Plugins --> Game Creator --> Inventory`, we have a bunch of folders. Animations are in the **Animations** folder, editor scripts in **Editor** folder, actions, conditions and many more scripts in **Mono** and so on. We need to change the following scripts:&#x20;

| Filename      | Folder       | Usage                          | Derives from      |
| ------------- | ------------ | ------------------------------ | ----------------- |
| Item.cs       | /Mono/Items/ | Defines the item object        | Scriptable Object |
| ItemEditor.cs | /Editor/     | Defines the Item Editor Window | Editor            |

The `Item.cs` defines the item object itself. This class is used when a new object of type `Item` is generated (like we do in the Inventory UI by clicking **Create Item**): &#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MD0otoqpUHD4bGnhdbx%2F-MD0qX_WLwQ_0eSkaxTg%2Fimage.png?alt=media\&token=61e5dae5-c499-4a4b-8832-5f8a669e12f3)

This newly generated object will be stored in the database I mentioned in a previous chapter. A method inside the script `ItemEditor.cs` gets executed when you click on **Inventory** in the sidebar of the Game Creator Preferences window, basically reading the content of the database and displaying it. In the next chapter, we will take a look at the structure of these scripts. It is better to have a certain understanding of how the scripts are structured before we continue.&#x20;

#### Item.cs

This script contains the class `Item`, which contains the properties that can be set in the Inventory window and a method that allows us to create new item instances. It has properties like the name of the item, the description, if it can be sold, the price, item type and much more. There are two sections in this script. **Properties** and **Constructor**. Properties should be self-explanatory. If you open the script, we see that the Constructor (a method) section is only active in the Unity Editor. This is done with a so called [define directive](https://docs.unity3d.com/Manual/PlatformDependentCompilation.html), here `#if UNITY_EDITOR`. These directives allow us to i.e. execute certain code only in the editor (like in this case), on certain platforms only (like Windows or MacOS) or when using certain Unity versions (like Unity 2020.1). Each of these define directives need an opening statement `#if xxx` and a closing statement `#endif`.&#x20;

```csharp
#if UNITY_EDITOR

<Your code>

#endif
```

#### ItemEditor.cs

This scripts however is much more complex. It not only contains constant variables, but static members and some methods as well. Again, we have two sections, **Properties** and **Methods**. When we open the script, we see that there are constant and static variables and a class before the **Properties** section. You might have heard of constant and static variables, but if not, they are not like normal variables.&#x20;

**Constant** variables are variables with a value that, once assigned at compile-time, will never change and cannot be changed. You can only assign [primitive or C# builtin types](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types), like string and float.&#x20;

**Static** members (i.e. variables and methods, in this case variables) are not accessible when you create a new instance of an object. They belong to the type of the object, not the instance of an object. Example:&#x20;

```csharp
public class Inventory
{
    public static string name = "myName"; // static string variable
    public static string GetName() {...}  // static method with string return value
}
```

If we create a new instance of the `Inventory`class, we won't be able to do the following:&#x20;

```csharp
void MyMethod()
{
    Inventory myInventory  = new Inventory();

    Debug.Log(myInventory.name); // Doesn't work!
    myInventory.GetName();       // Doesn't work!
}
```

We can only do this:&#x20;

```csharp
void MyMethod()
{
    Debug.Log(Inventory.name); // Works!
    Inventory.GetName();       // Works!
}
```

But back to the script. In the **Properties** section we have a bunch of `SerializedProperty` variables. A `SerializedProperty` is used when you want to access a value of a variable (property) of a serialized object. I will go deeper into this topic in a later tutorial. Finally, we have the **Methods** section of this class with all the methods. There are two particular methods to look for: `OnEnable()` and `PaintContent()`

For each item in the item database, a new object of type `ItemEditor` is instantiated and the method `OnPreferencesWindowGUI` of the same class gets called. When the objects gets instantiated, it automatically calls `OnEnable()`, what reads the variables of the underlying database item of type `Item`(which is now a serialized object) and sets the values of the `ItemEditor`serialized property variables to the according `Item` variable values (like itemName, sprite, price etc.). `OnPreferencesWindowGUI` does some more stuff, but also calls `PaintContent()`. This method paints the content of the window where the items are shown. Because we now have the serialized properties with the values of the item in the database, it is possible to simply add an `EditorGUILayout.PropertyField` with the serialized property as the value. Example:&#x20;

```csharp
// The code is simplified and shortened for better understanding

private const string PROP_PREFAB = "prefab";

void OnEnable()
{
    this.spPrefab= serializedObject.FindProperty(PROP_PREFAB);
}

public void PaintContent()
{
    EditorGUILayout.PropertyField(this.spPrefab);
}
```

{% hint style="info" %}
Note: `serializedObject` refers to the item in the database and `PROP_PREFAB` to the variable. `serializedObject.FindProperty(PROP_PREFAB)` does nothing else than grab the value of the  item object like we would with `GameObject prefab = item.prefab`.&#x20;
{% endhint %}

### Extending the inventory

Now that we have covered many things around the Game Creator inventory, we are ready to continue. For the start, let's add a string variable to the `Item` class (Item.cs). You can give any name you want. This is the first step to extend the inventory. Add it in the **Properties** section between the `public GameObject prefab` and `public bool canBeSold` variables. You can later put it anywhere in this section you like, but I do it this way for you to better understand. I include the previous and next one as well.&#x20;

```csharp
public GameObject prefab;

public string myVariable; // I know, not a good name...

public bool canBeSold = true;
```

Save it and jump over to the `ItemEditor` class (ItemEditor.cs). Here we do more things:&#x20;

1. Add a private constant string variable
2. Add a public SerializedProperty variable
3. Assign our SerializedProperty variable in OnEnable()
4. Add a EditorGUILayout.PropertyField to PaintContent()

Let's start with the first step. Add the private constant string variable in the same position you added your string variable in the `Item` class:&#x20;

```csharp
private const string PROP_PREFAB = "prefab";
private const string PROP_MYVARIABLE = "myVariable";
private const string PROP_CANBESOLD = "canBeSold";
```

{% hint style="warning" %}
Attention: The value of the constant string must be the same as the name of your added variable in the `Item` class! In my case, my variable is called **myVariable**, that's why the constant string must also be **myVariable**.&#x20;
{% endhint %}

The next thing we do is add a `SerializedProperty` variable to the Properties section:&#x20;

```csharp
private SerializedProperty spPrefab;
private SerializedProperty spMyVariable;
private SerializedProperty spCanBeSold;
```

Now we assign our `SerializedProperty` variable the value of the property value of the serialized object in the method `OnEnable()`:&#x20;

```csharp
this.spPrefab = serializedObject.FindProperty(PROP_PREFAB);
this.spMyVariable = serializedObject.FindProperty(PROP_MYVARIABLE);
this.spCanBeSold = serializedObject.FindProperty(PROP_CANBESOLD);
```

And finally we add a property field to the method that paints the content of the window, `PaintContent()`:&#x20;

```csharp
EditorGUILayout.PropertyField(this.spPrefab);

EditorGUILayout.Space();

EditorGUILayout.PropertyField(this.spMyVariable);

EditorGUILayout.Space();

EditorGUILayout.PropertyField(this.spCanBeSold);
```

If we switch back to Unity and let it compile, open the Game Creator Preferences window, go to the Inventory tab and create a new item. You should now see our newly added variable.&#x20;

![](https://3625548948-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6E9D__lMnHqqxqKxIn%2F-MD1QOi1EPfZ4bcHDkOd%2F-MD1QwAmB8P11giqsqJ5%2Fimage.png?alt=media\&token=bb3a77b3-d60b-4a51-959f-70b3b82029d7)

You can add as many custom entries this way as you like. You can add i.e. weapons (from the Shooter module) or anything else. Have fun making games!
