# Unity SDK

## Requirements <a href="#undefined" id="undefined"></a>

The specifications required to use the Game Chat Unity SDK are as follows.

* Minimum specifications: 2018.4.0 or later\
  (If you need support for the lower version of Unity, then make an inquiry through [Contact us](https://www.ncloud.com/support/question).)
* If you are a user of Unity editor in the 2019.4.X/2020.3.X/2021.1.X version, then make sure to use a version at or above 2019.4.29f1/2020.3.15f2/2021.1.16f1 respectively (versions where the Unity editor bug is fixed when building the AAB version).

## Install SDK and configure environment <a href="#sdk" id="sdk"></a>

The following describes how to download Game Chat Unity SDK and configure a project in Unity.

1. Click the **Settings** > **Download SDK** menus, in that order, and then click **Download Unity SDK**.
2. Run Unity, and create a project.
3. In Unity, click the **Assets** > **Import Package** > **Custom Package...** menus, in that order.
4. Open the "GameChatUnitySDK\_xxxxxxxx" file downloaded in the dashboard.
5. Select all files in the package, and then click the **\[Import]** button.
6. Save the project.

## Authentication <a href="#undefined" id="undefined"></a>

### Reset Game Chat instance <a href="#gamechat" id="gamechat"></a>

To initialize Game Chat instances using the Game Chat project ID, use the code below.

```csharp
GameChat.initialize(PROJECT_ID);

// When using in the Singapore region
GameChat.setRegion("sg");
GameChat.initialize(PROJECT_ID);
```

| ID          | type   | desc       |
| ----------- | ------ | ---------- |
| PROJECT\_ID | string | Project ID |

### Connect to Game Chat socket server

The following describes how to connect to a Game Chat socket server.

1. Use the chat user ID to access a Game Chat socket server.
   * In a Game Chat project, the chat user ID is a unique value.
2. Get the token value for using the API.
   * The token value renewed can be viewed after GameChat.connect.
3. After acquiring the token value, check if the chat user information is renewed for the currently connected device.
   * The member data received with the GameChat.connect's callback is renewed data.

Use the following code to connect to the Game Chat socket server.

```csharp
GameChat.connect(USER_ID,  (Member User, GameChatException Exception)=> 
{

    if(Exception != null)
    {
        // Error handling
        return;
    }
});
```

| ID       | type   | desc                  |
| -------- | ------ | --------------------- |
| USER\_ID | string | Chat user's unique ID |

### Remove Game Chat server connection

To remove the connection with the Game Chat socket server, use the following code.

```csharp
GameChat.disconnect();
```

### Chat user information update <a href="#undefined" id="undefined"></a>

Use the following code to save and update the chat user information after a successful connect.

**Edit nickname**

```csharp
GameChat.setNickname(USER_ID, NickName, (member, exception) =>
{
    if (exception != null)
    {
        // Error handling
        return;
    }
    
});
```

| ID       | type   | desc                  |
| -------- | ------ | --------------------- |
| USER\_ID | string | Chat user's unique ID |
| NickName | string | Chat user's nickname  |

**Edit profile URL**

```csharp
GameChat.setProfileUrl(USER_ID, ProfileUrl, (member, exception) =>
{
    if (exception != null)
    {
        // Error handling
        return;
    }
    
});
```

| ID         | type   | desc                   |
| ---------- | ------ | ---------------------- |
| USER\_ID   | string | Chat user's unique ID  |
| ProfileUrl | string | Chat user's ProfileUrl |

## Subscribe and unsubscribe to channel

Use the following code to subscribe or unsubscribe to a specific channel.

```csharp
GameChat.subscribe(CHANNEL_ID);

GameChat.unsubscribe(CHANNEL_ID);
```

| ID          | type   | desc       |
| ----------- | ------ | ---------- |
| CHANNEL\_ID | string | Channel ID |

## Send message <a href="#undefined" id="undefined"></a>

Use the following code to send a message to a specific channel.

```csharp
GameChat.sendMessage(CHANNEL_ID, MESSAGE);
```

| ID          | type   | desc                 |
| ----------- | ------ | -------------------- |
| CHANNEL\_ID | string | Channel ID           |
| MESSAGE     | string | Message text to send |

When @\[User ID] space \[Message content] is entered for the MESSAGE parameter

```csharp
@user_id message content
```

In the above case, if the username has a history of being logged in, the "mentions" information from the message details is the user ID.

## Register and remove event

Use the following code to register or remove a custom handler for events received from a Game Chat socket server.

```csharp
GameChat.dispatcher.(EVENT_NAME) += (CALLBACK_FUNCTION);
```

```csharp
public delegate void onConnectedCallback(string data);
public onConnectedCallback onConnected;
//Callback regarding "connect" events

public delegate void onDisconnectedCallback(string reason);
public onDisconnectedCallback onDisconnected;
//Callback regarding "disconnect" events

public delegate void onMessageReceivedCallback(Message message);
public onMessageReceivedCallback onMessageReceived;
//Callback regarding "message" events

public delegate void onUserAddedCallback(UserInfo userinfo);
public onUserAddedCallback onUserAdded;
//Callback regarding "usedAdded" events

public delegate void onUserRemovedCallback(Message message);
public onUserRemovedCallback onUserRemoved;
//Callback regarding "userRemoved" events

public delegate void onErrorReceivedCallback(string result, GameChatException exception);
public onErrorReceivedCallback onErrorReceived;
//Callback regarding "error" events
```

## Exceptions <a href="#undefined" id="undefined"></a>

The public class for exceptions occurring while using the Game Chat API is as follows.

```csharp

public class GameChatException
{
    // Detail Error Code
   
    // Unknown error
    public static readonly int CODE_UNKNOWN_ERROR           = 0;
    // Initialization failed
    public static readonly int CODE_NOT_INITALIZE           = 1;
    // Invalid parameter
    public static readonly int CODE_INVAILD_PARAM           = 2;  
    // Errors occurred from the socket server
    public static readonly int CODE_SOCKET_SERVER_ERROR     = 500;
    //Errors occurred from the socket
    public static readonly int CODE_SOCKET_ERROR = -501;
    // Network connection error or timeout occurred
    public static readonly int CODE_SERVER_NETWORK_ERROR    = 4002;
    // Error occurred when parsing data received from the server
    public static readonly int CODE_SERVER_PARSING_ERROR    = 4003;

    // For HTTP errors, the status code is sent as the response code. (400, 403 ...)

    // Error Code
    public int code { get; set; }
    // Error Message
    public string message { get; set; }
}
```

## Client API

### Subscribe to channel <a href="#undefined" id="undefined"></a>

#### **Subscription Data Class (per Unit)**

```csharp
public class Subscription
{
    public string id;
    public string channel_id;
    public string user_id;
    public string created_at;
}
```

| ID          | type   | desc                  |
| ----------- | ------ | --------------------- |
| id          | string | Unique ID             |
| channel\_id | string | Channel ID            |
| user\_id    | string | Chat user's unique ID |
| created\_at | string | Creation date         |

#### **Import channel subscription list**

Use the following code to import the subscription data of a specific channel in the form of a list.

```csharp
GameChat.getSubscriptions(CHANNEL_ID, OFFSET, LIMIT, (List<Subscription> Subscriptions, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    foreach(Subscription elem in Subscriptions)
    {
        //handling each subscription instance
    }
}));
```

### Channel <a href="#undefined" id="undefined"></a>

#### **Channel Data Class (per Unit)**

```csharp
public class Channel
{
    public string id;
    public string project_id;
    public string unique_id;
    public string name;
    public string user_id;
    public string created_at;
    public string updated_at;
}
```

| ID          | type   | desc                                                 |
| ----------- | ------ | ---------------------------------------------------- |
| id          | string | Channel ID (unique)                                  |
| project\_id | string | Project ID                                           |
| unique\_id  | string | Channel ID that can be set by the developer (unique) |
| name        | string | Channel name                                         |
| user\_id    | string | Chat user ID (who created the channel)               |
| created\_at | string | Creation date                                        |
| updated\_at | string | Renewal date                                         |

#### **Import channel list**

Use the following code to import the channel data of a project in the form of a list.

```csharp
GameChat.getChannels(OFFSET, LIMIT, (List<Channel> Channels, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    foreach(Channel elem in Channels)
    {
        //handling each channelInfo instance
    }
});
```

| ID     | type | desc                                                                          |
| ------ | ---- | ----------------------------------------------------------------------------- |
| OFFSET | int  | Start location of the channel to import from the list of all channels (index) |
| LIMIT  | int  | Number of channels to import                                                  |

#### **Import channel data**

Use the following code to import channel data using the channel ID and unique ID.

```csharp
//Put null in the CHANNEL_UNIQUE_ID parameter if you want to search only by CHANNEL_ID.

//If both the CHANNEL_ID and CHANNEL_UNIQUE_ID values exist, then it searches by prioritizing the CHANNEL_UNIQUE_ID value.

GameChat.getChannel(CHANNEL_ID, CHANNEL_UNIQUE_ID,  (Channel Channel, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    //handling channelInfo instance
});
```

```csharp
GameChat.getChannel(CHANNEL_UNIQUE_ID, (Channel Channel, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    //handling channelInfo instance
});
```

| ID                  | type   | desc                                          |
| ------------------- | ------ | --------------------------------------------- |
| CHANNEL\_ID         | string | Channel ID (auto-generated)                   |
| CHANNEL\_UNIQUE\_ID | string | (Unique) channel ID (customization available) |

### Create and delete channel <a href="#undefined" id="undefined"></a>

You must use an open API to create or delete a new channel within a project.\
Due to security concerns, we recommend that you use an open API to create and update channels directly from Server to Server. For more information, see the [Game Chat API Guide](https://api.ncloud-docs.com/docs/en/game-gamechat).

### Messenger <a href="#undefined" id="undefined"></a>

#### **(Received) Message Data Class (per Unit)**

```csharp
public class Message
{
    public class User
    {
        public string id;
        public string name;
        public string profile;
    }

    public string message_id;
    public string channel_id;
    public string message_type;
    public string content;

    public string[] mentions;
    public bool mentions_everyone;
    public User sender;
    public string created_at;
}
```

| ID            | type   | desc                             |
| ------------- | ------ | -------------------------------- |
| message\_id   | string | Message’s unique ID              |
| channel\_id   | string | Channel ID                       |
| message\_type | string | Message type                     |
| content       | string | Content of message (JSON string) |
| mentions      | string | Mention (tag)                    |
| created\_at   |        | string                           |

#### **Import message list**

Use the following code to import the message data of a specific channel in the form of a list.

```csharp
GameChat.getMessages(CHANNEL_ID, OFFSET, LIMIT, SEARCH, QUERY, SORT, (List<Message> Messages, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    foreach(Message elem in Messages)
    {
        //handling each message instance
    }
});
```

<table><thead><tr><th width="181">ID</th><th width="119">type</th><th>desc</th></tr></thead><tbody><tr><td>CHANNEL_ID</td><td>string</td><td>Channel ID</td></tr><tr><td>OFFSET</td><td>string</td><td>Start location of the message to import from the list of all messages</td></tr><tr><td>LIMIT</td><td>string</td><td>Number of messages to import</td></tr><tr><td>SEARCH</td><td>string</td><td>Message search criterion key. E.g., content.text<br>Perform a full scan when sending empty strings</td></tr><tr><td>QUERY</td><td>string</td><td>Message search value. Only complete matches can be searched. Perform a full scan when sending empty strings</td></tr><tr><td>SORT</td><td>string</td><td>Message sorting order (default: descending order - most recent comes first) (optional: ascending order)</td></tr></tbody></table>

#### **Translate messages**

If the automatic translation feature is activated, then arbitrary text can be translated into the specified language. The automatic translation feature can be used after integrating with the [Papago Translation](https://www.ncloud.com/product/aiService/papagoTranslation) service.

**(Received) Translation Data Class (per Unit)**

```csharp
public class Translation
{
    public string detectLang = "";
    public string lang = "";
    public bool translated = false;
    public string message = "";
}
```

<table><thead><tr><th width="163">ID</th><th width="126">type</th><th>desc</th></tr></thead><tbody><tr><td>detectLang</td><td>string</td><td>Source language code</td></tr><tr><td>lang</td><td>string</td><td>Target language code</td></tr><tr><td>translated</td><td>bool</td><td>Success or failure of translation</td></tr><tr><td>message</td><td>string</td><td>Content of result message (JSON string)</td></tr></tbody></table>

> Note
>
> For more information on source language codes and target language codes, see the [Papago Text Translation API Guide](https://api.ncloud-docs.com/docs/en/ai-naver-papagonmt-translation).

```csharp
GameChat.translateMessage(CHANNEL_ID, SORCE_LANG, TARTGET_LANG, TEXT, (List<Translation> Translations, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    foreach(Translation elem in Translations)
    {
        //handling each Translation instance
    }
});

GameChat.translateMessage(SORCE_LANG, TARTGET_LANG, TEXT, (List<Translation> Translations, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }

    foreach(Translation elem in Translations)
    {
        //handling each Translation instance
    }
});
```

<table><thead><tr><th width="195">ID</th><th width="118">type</th><th>desc</th></tr></thead><tbody><tr><td>CHANNEL_ID</td><td>string</td><td>Channel ID</td></tr><tr><td>SORCE_LANG</td><td>string</td><td>Language name of the text to send ("auto": detected automatically)<br>See the <a href="https://api.ncloud-docs.com/docs/en/ai-naver-papagonmt-translation">API Guide</a></td></tr><tr><td>TARTGET_LANG</td><td>string</td><td>Language code of the text (to receive the translation)<br>(Multiple entries allowed with "," E.g., "en, fr, th")<br>See the <a href="https://api.ncloud-docs.com/docs/en/ai-naver-papagonmt-translation">Papago Text Translation API Guide</a></td></tr><tr><td>TEXT</td><td>string</td><td>Text to send</td></tr></tbody></table>

### Chat user

**(Received) Member Data Class (per Unit)**

```csharp
public class Member
{
    public string id = "";
    public string project_id = "";
    public string nickname = "";
    public string profile_url = "";
    public string country = "";
    public string remoteip = "";
    public string adid = "";
    public string device = "";
    public string network = "";
    public string version = "";
    public string model = "";
    public string logined_at = "";
    public string created_at = "";
    public string updated_at = "";
}
```

<table><thead><tr><th width="152">ID</th><th width="124">type</th><th>desc</th></tr></thead><tbody><tr><td>id</td><td>string</td><td>Chat user's unique ID</td></tr><tr><td>project_id</td><td>string</td><td>Game Chat project ID that logged in</td></tr><tr><td>nickname</td><td>string</td><td>Chat user's nickname</td></tr><tr><td>profile_url</td><td>string</td><td>Profile image URL</td></tr><tr><td>country</td><td>string</td><td>Country connected</td></tr><tr><td>remoteip</td><td>string</td><td>Connection IP</td></tr><tr><td>adid</td><td>string</td><td>Advertisement identifier</td></tr><tr><td>device</td><td>string</td><td>Connected device's environment</td></tr><tr><td>network</td><td>string</td><td>Connected network's type (Cellular, Wi-Fi)</td></tr><tr><td>version</td><td>string</td><td>Version of the app connected</td></tr><tr><td>model</td><td>string</td><td>Connected device's model</td></tr><tr><td>logined_at</td><td>string</td><td>Login date</td></tr><tr><td>created_at</td><td>string</td><td>Chat user creation date</td></tr><tr><td>updated_at</td><td>string</td><td>Chat user information renewed date</td></tr></tbody></table>

#### **Chat user information update**

You can update the user information of a chat server.

```csharp

// Chat user nickname update
// The strings allowed for nicknames are 2 to 128 characters in length, excluding whitespaces (spaces, tabs, and line breaks).
GameChat.setName(MEMBER_ID, NAME, (Member member, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }
    //handling updated Member instance
});

//Chat user profile image URL update
GameChat.setProfileUrl(MEMBER_ID, PROFILE_URL, (Member member, GameChatException Exception) => {

    if(Exception != null)
    {
        // Error handling
        return;
    }
    //handling updated Member instance
});

```

| ID         | type   | desc                         |
| ---------- | ------ | ---------------------------- |
| MEMBER\_ID | string | Chat user's unique ID        |
| NAME       | string | Chat user's nickname or name |
| PROFILE    | string | Profile image URL            |

## GameChatExtension (Emoji, HyperLink)

This helper class facilitates easy handling of emojis and hyperlink text included in the received message.

* Since TMP\_GameChatTextUGUI is an extension class of TextMeshPro, a built-in asset of Unity, you must use first use Package Manager to install TextMeshPro.
* The TextMeshPro asset is included as a built-in asset from Unity 2018.2 or later.
* The default output of emoji sprite sheets is available from Emoji v13.0 (Android). You can change and customize the sprite sheet.

```csharp
namespace GameChatUnity.Extension
{
    public class TMP_GameChatTextUGUI : TextMeshProUGUI
    {
        public bool isHyperLinked { get; set; }    // Whether to process link-type addresses as hyperlinks (append html tag)
        public string LinkTextColor { get; set; }  // hyperlink text color
    }
}
```

**\<Example>**

```csharp
using GameChatUnity.Extension;

TMP_GameChatTextUGUI message = msgObject.GetComponent<TMP_GameChatTextUGUI>();

//Insert text through setMessage for hyperlink recognition and processing.
message.setMessage(MESSAGE_CONTENT);
message.color = Color.green;
message.isHyperLinked = true;

...

msgObject = Instantiate(msgObject) as GameObject;

...

// Manually implement the click event listener for hyperlinks.

//Handling with TMP_LinkInfo
TMP_LinkInfo linkInfoArr = message.textInfo.linkInfo[LINK_INDEX];

...
```
