Unity SDK 문서
CasualTalk Unity SDK로 게임에 채팅방과 채팅 번역을 붙이는 방법입니다. 모든 기능은 정적 클래스 CasualTalk 하나로 호출하고, 결과는 await로 받습니다.
localhost:8080)에 연결되도록 고정되어 있습니다. 게임 등록(AppID 발급)도 아직 관리자 도구 없이 수동으로 진행합니다. Unreal Engine 5 SDK는 준비 중입니다.설치
- SDK 폴더
Assets/CasualTalk를 Unity 프로젝트의Assets아래에 복사합니다. - 패키지 매니저에서
com.unity.nuget.newtonsoft-json이 설치되어 있는지 확인합니다. 채팅 메타데이터를 JSON으로 바꿀 때 씁니다. - 발급받은 AppID를 준비합니다. 개발용 AppID는
casualtalk-dev입니다.
빠른 시작
초기화 → 리스너 등록 → 방 입장 → 채팅 순서입니다. 새 채팅은 리스너의 OnNotifyChatRoom으로 메인 스레드에서 들어옵니다.
public class ChatSample : MonoBehaviour, ICasualTalkListener
{
private async void Start()
{
var init = await CasualTalk.Initialize(new CasualTalkInitializeOption
{
AppID = "casualtalk-dev",
UserID = "player-1024", // 게임에서 쓰는 플레이어 ID
Mode = CasualTalkMode.Tcp,
});
if (!init.IsSuccess) return;
CasualTalk.AddListener(this);
var join = await CasualTalk.JoinRoom("guild-42");
foreach (var chat in join.Data.Chats) Debug.Log(chat.Chat); // 최근 대화
await CasualTalk.ChatRoom("guild-42", "안녕하세요!");
}
public void OnNotifyChatRoom(string roomID, DataChat chat)
{
Debug.Log($"[{roomID}] {chat.UserIDX}: {chat.Chat}");
}
private void OnApplicationQuit() => CasualTalk.Close();
}
연결 방식
두 방식의 유저는 같은 방에서 서로의 채팅을 같은 순서로 받습니다. 호출하는 API도 같고 Mode만 다릅니다.
| 모드 | 동작 | 적합한 경우 |
|---|---|---|
| CasualTalkMode.Tcp | 채팅 서버와 연결을 유지하고 새 채팅을 즉시 받습니다. 연결이 끊기면 서버가 방에서 자동으로 퇴장시킵니다. | PC · 모바일 앱 (기본값) |
| CasualTalkMode.Http | PollInterval마다 HTTPS로 새 채팅을 가져옵니다. | 소켓을 쓸 수 없는 웹 · 일부 플랫폼 |
API
Initialize
게임 인증을 하고 채팅 서버에 연결합니다. 다른 API보다 먼저 한 번 호출합니다. 실패하면 내부 상태를 정리하므로 다시 호출할 수 있습니다.
옵션 (CasualTalkInitializeOption)
| 속성 | 타입 | 설명 |
|---|---|---|
AppID | string | 필수. 게임마다 발급받는 ID. 영문·숫자·_·-, 1~32자 |
UserID | string | 필수. 게임 안의 플레이어 ID, 1~64자. 같은 값이면 다시 접속해도 같은 UserIDX를 받습니다 |
Mode | CasualTalkMode | Tcp(기본) 또는 Http |
PollInterval | TimeSpan | Http 모드에서 새 채팅을 가져오는 간격. 기본 250ms, 100ms보다 짧게 해도 효과가 없습니다 |
성공하면 CasualTalk.IsInitialized가 true가 되고, 서버가 발급한 내 번호를 CasualTalk.UserIDX로 읽을 수 있습니다. 이미 초기화된 상태에서 다시 부르면 DuplicateConnection을 돌려줍니다.
AddListener
새 채팅을 받을 객체를 등록합니다. 같은 객체를 두 번 등록하면 Failed를 돌려줍니다. 알림은 SDK가 만든 CasualTalk 게임 오브젝트가 매 프레임 메인 스레드에서 전달하므로, 콜백 안에서 바로 UI를 바꿔도 됩니다.
public interface ICasualTalkListener
{
void OnNotifyChatRoom(string roomID, DataChat chat);
}
JoinRoom
방에 들어갑니다. 방은 따로 만들 필요 없이 이름으로 들어가면 생깁니다. 같은 방 이름이라도 다른 게임(AppID)과는 섞이지 않습니다.
응답 (SC_JoinRoomAck)
| 필드 | 타입 | 설명 |
|---|---|---|
RoomID | string | 들어간 방 이름 |
User | DataUser | 나 (UserIDX) |
Chats | List<DataChat> | 입장 전 최근 대화 |
Users | List<DataUser> | 방에 있는 유저. Tcp 모드 유저만 들어 있습니다 |
ChatRoom
방에 채팅을 보냅니다. metadata는 JSON으로 바뀌어 그대로 전달되고, 받는 쪽은 DataChat.Meta로 읽습니다. 닉네임, 아이콘, 아이템 링크처럼 게임이 정한 정보를 실을 때 씁니다. SDK와 서버는 내용을 해석하지 않습니다.
await CasualTalk.ChatRoom("guild-42", "이 아이템 어때요?",
new Dictionary<string, object> { ["nick"] = "하늘바람", ["item"] = 10231 });
1초에 30건을 넘기면 넘친 채팅은 TooManyRequest로 거부됩니다.
QuitRoom
방에서 나갑니다. 이후 그 방의 채팅은 더 이상 받지 않습니다.
TranslateChat
받은 채팅 하나를 원하는 언어로 번역합니다. 원문은 서버가 messageID로 찾으므로 텍스트를 보내지 않습니다. 말풍선의 번역 버튼에 연결하는 용도입니다.
| 인자 | 설명 |
|---|---|
roomID | 채팅이 올라온 방 |
messageID | 받은 DataChat.MessageID |
lang | 받을 언어: ko, en, ja |
var res = await CasualTalk.TranslateChat(roomID, chat.MessageID, "ko");
if (res.IsSuccess) bubble.ShowTranslation(res.Data.Text);
원문이 이미 요청한 언어면 원문을 그대로 돌려줍니다. 결과는 캐시하지 않으므로 같은 메시지를 다시 요청하면 표현이 조금 다를 수 있습니다.
SetNoticeRoom
내가 방에 들어오거나 나갈 때 서버가 나 대신 그 방에 남길 채팅을 등록합니다. 다른 유저에게는 일반 채팅처럼 OnNotifyChatRoom으로 전달됩니다. 다시 부르면 덮어씁니다.
- 입장 메시지는
JoinRoom이 성공할 때 남습니다. - 퇴장 메시지는
QuitRoom, Tcp 연결 끊김, Http Poll 중단 때 남습니다. - 메시지와 메타데이터가 모두 비어 있으면 남기지 않습니다.
await CasualTalk.SetNoticeRoom(
"하늘바람 님이 들어왔어요", new Dictionary<string, object> { ["type"] = "join" },
"하늘바람 님이 나갔어요", new Dictionary<string, object> { ["type"] = "quit" });
Close
연결을 끊고 SDK 상태를 정리합니다. 게임 종료 시(OnApplicationQuit) 호출합니다. 이후 다시 Initialize할 수 있습니다.
데이터 타입
CasualTalkResponse / CasualTalkResponse<T>
모든 비동기 API의 결과입니다. 연결 전에 호출하면 서버에 보내지 않고 바로 NotConnected를 돌려줍니다.
| 멤버 | 타입 | 설명 |
|---|---|---|
IsSuccess | bool | ErrorCode == Success |
ErrorCode | ErrorCode | 결과 코드 (에러 코드) |
Data | T | 서버 응답. 실패하면 null |
DataChat
| 필드 | 타입 | 설명 |
|---|---|---|
UserIDX | ulong | 보낸 유저 번호. 같은 게임의 같은 플레이어는 항상 같은 값 |
Chat | string | 채팅 원문 |
MessageID | string | 메시지 고유 ID. TranslateChat에 넘깁니다 |
Meta | string | 보낸 쪽이 넣은 metadata의 JSON. 없으면 빈 문자열 |
SC_TranslateAck
| 필드 | 타입 | 설명 |
|---|---|---|
Text | string | 번역문 |
Lang | string | 요청한 언어 |
RoomID, MessageID | string | 요청한 값 그대로 |
에러 코드
| 값 | 이름 | 언제 |
|---|---|---|
| 0 | Failed | 요청이 거부되거나 처리 중 실패함 (등록되지 않은 AppID, 잘못된 입력 등) |
| 1 | Success | 성공 |
| 2 | DuplicateConnection | 이미 초기화된 상태에서 Initialize를 다시 호출함 |
| 3 | NotConnected | Initialize 전이거나 Close 후에 호출함 |
| 4 | Timeout | 서버 응답이 시간 안에 오지 않음 |
| 5 | TooManyRequest | 1초에 30건을 넘겨 채팅함 |
제한 사항
| 항목 | 내용 |
|---|---|
| 채팅 속도 | 유저당 1초에 30건. Tcp · Http 모두 같은 기준 |
| 번역 언어 | 한국어(ko), 영어(en), 일본어(ja) |
| 방 대화 보관 | 방마다 최근 약 1,000건. Http 모드에서 오래 끊겼다 돌아오면 남아 있는 대화부터 받습니다 |
| Http 모드 퇴장 | 앱이 비정상 종료되면 퇴장이 바로 알려지지 않을 수 있습니다 |
| 유저 확인 | CasualTalk는 UserID를 게임이 보낸 그대로 믿습니다. 플레이어 인증은 게임 쪽에서 마친 뒤 초기화하세요 |