> For the complete documentation index, see [llms.txt](https://playnetwork.gitbook.io/play-sdk-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://playnetwork.gitbook.io/play-sdk-documentation/sdk-integration-guides/virtual-items/unity.md).

# Unity

## Introduction

Virtual items are game items, that can be purchased using game currency or can be rewarded as completing an [Achievements](/play-sdk-documentation/sdk-integration-guides/achievements.md). The Virtual item can also be minted an turn into NFT through the [PLAY Dev Dashboard](https://ready.gg/developer/).&#x20;

For example, a virtual item can be:

* Racing Game: It can be different types of cars.&#x20;
* Puzzle game: It can be a bunch of hints pack.
* Match-3 game: There can be different types of power-ups.
* Shooting Game: Different types of guns, ammo etc&#x20;

Virtual Items can be created using the [ PLAY Dev Dashboard](https://ready.gg/developer/).

<details>

<summary>VirtualItem</summary>

* **id** (string): *Unique id for the virtual item.*
* **name** (string): *Name of the virtual item.*
* **description** (string): *Description of the virtual item.*
* **appIds** (List\<string>): *List of project id where your item can be accessed.*
* **createdAt** (long): *Date and time of the item creation.*
* **updatedAt** (long): *Date and time of the last update on the item.*
* **createdBy** (string): *User ID of the creator of the item*
* **updatedBy** (string): *User ID of the last person who updated the item.*
* **isStackable** (bool): Indicate if the item can be stored under the same ID in the inventory.
* **tags** (List\<string>): *List of tags to filter the items.*
* **properties** (List\<Property>): *List of properties you can store in json format to retrieve with the virtual item.*
* **prices** (List\<PriceInfo>): *List of prices defined for this item. Used to process transaction with the user's currencies.*

</details>

### Virtual item class methods

* **IsNFT();**
  * *Return a bool to let you know if the virtual item is an NFT or not.*
* **GetRGNCoinPrice();**
  * *Return the price in rgn-coin if the item is an NFT.*
* **GetCustomCoinPrice(string currencyName);**
  * *Return the price based on your custom currency setup in the virtual item.*

### **Get All Virtual Items for current app**

```csharp
using System.Collections.Generic;
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    public async void GetAllVirtualItem()
    {
        List<VirtualItem> virtualItems = await VirtualItemsModule.I.GetVirtualItemsAsync();
        foreach (var virtualItem in virtualItems)
        {
            Debug.Log($"Virtual item id : {virtualItem.id} \n" +
                $"virtual item name : {virtualItem.name}");
            // etc
        }
    }
}
```

### Get with pagination

There is also a method overload for pagination requests. The pagination means you request not all items at once for the project. In this example every request contains 5 items. Each time you call the method, 5 more items will be loaded and added to the loaded item list.&#x20;

```csharp
using System.Collections.Generic;
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    private List<VirtualItem> allLoadedItems = new List<VirtualItem>();
    private VirtualItem lastLoadedItem = null;

    public async void GetVirtualItemsPaginationAsync()
    {
        List<VirtualItem> virtualItems = new List<VirtualItem>();
        if (allLoadedItems.Count > 0)
        {
            lastLoadedItem = allLoadedItems[allLoadedItems.Count - 1];
            virtualItems = await VirtualItemsModule.I.GetVirtualItemsAsync(5, lastLoadedItem.id); // Get 5 more items
        }
        else
        {
            virtualItems = await VirtualItemsModule.I.GetVirtualItemsAsync(5, ""); // Get 5 first items
        }
        allLoadedItems.AddRange(virtualItems);
        Debug.Log(allLoadedItems.Count);
    }
}
```

## Different ways to retrieve virtual items :

### **Get by tags**  <a href="#get-by-tags" id="get-by-tags"></a>

```csharp
using System.Collections.Generic;
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    public async void GetVirtualItemsAsync()
    {
        List<string> tags = new List<string> { "guns", "rifles" };
        List<VirtualItem> virtualItems = await VirtualItemsModule.I.GetByTagsAsync(tags);
    }
}
```

### Get by ids&#x20;

```csharp
using System.Collections.Generic;
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    public async void GetByIdsAsync()
    {
        List<string> ids = new List<string> { "item_one_id", "item_two_id" };
        List<VirtualItem> virtualItems = await VirtualItemsModule.I.GetVirtualItemsByIdsAsync(ids);
    }
}
```

### Updating Virtual Items data&#x20;

```csharp
using System.Collections.Generic;
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    public async void UpdateVirtualItemInfosAsync()
    {
        string virtualItemId = "some_virtual_item";
        await VirtualItemsModule.I.SetNameAsync(virtualItemId, "New Virtual Item Name");
        await VirtualItemsModule.I.SetDescriptionAsync(virtualItemId, "New Virtual Item Description");

        List<string> newTags = new List<string> { "tag01", "tag02" };
        await VirtualItemsModule.I.SetTagsAsync(virtualItemId, newTags);
    }
}
```

### Storing and getting custom json data :

It is possible the store and retrieve custom properties json string associated with virtual item. The json string should be UTF8 formatted string not longer than 100k characters.

```csharp
using UnityEngine;
using RGN.Modules.VirtualItems;

[System.Serializable]
public struct MyCustomVirtualItemData
{
    public int MyInt;
    public string MyString;
    public float MyFloat;
}

public class VirtualItemExamples : MonoBehaviour
{
    public async void UpdatePropertiesAsync()
    {
        string virtualItemId = "some_virtual_item";

        var myCustomData = new MyCustomVirtualItemData()
        {
            MyFloat = 42.78f,
            MyInt = 51,
            MyString = "Hello World"
        };
        string propertiesJson = JsonUtility.ToJson(myCustomData);
        await VirtualItemsModule.I.SetPropertiesAsync(virtualItemId, propertiesJson);
    }

    public async void GetPropertiesAsync()
    {
        string virtualItemId = "some_virtual_item";

        var jsonProperties = await VirtualItemsModule.I.GetPropertiesAsync(virtualItemId);
        MyCustomVirtualItemData myCustomData = JsonUtility.FromJson<MyCustomVirtualItemData>(jsonProperties);

        Debug.Log(myCustomData.MyString);
    }
}
```

### Updating and downloading the virtual item image :

```csharp
using UnityEngine;
using RGN.Modules.VirtualItems;

public class VirtualItemExamples : MonoBehaviour
{
    public async void UpdateVirtualItemImageAsync(string virtualItemId, Texture2D virtualItemImage)
    {
        byte[] bytes = virtualItemImage.EncodeToPNG();
        await VirtualItemsModule.I.UploadImageAsync(virtualItemId,bytes);
    }
}
```

To download virtual item image you can use following code:

```csharp
using UnityEngine;
using RGN.Modules.VirtualItems;
using RGN.Model;
using System.Threading.Tasks;

public class VirtualItemExamples : MonoBehaviour
{
    public async Task<Texture2D> DownloadVirtualItemImageAsync(string virtualItemId)
    {
        byte[] bytes = await VirtualItemsModule.I.DownloadImageAsync(virtualItemId, ImageSize.Small);
        Texture2D resultTexture = new Texture2D(1, 1);
        resultTexture.LoadImage(bytes);
        resultTexture.Apply();
        return resultTexture;
    }
}
```

### Buy virtual items

To buy virtual items, please refer to the [Store Module](/play-sdk-documentation/sdk-integration-guides/store.md#buy-virtual-items-and-store-offers).
