Unity SDK 문서

CasualTalk Unity SDK로 게임에 채팅방과 채팅 번역을 붙이는 방법입니다. 모든 기능은 정적 클래스 CasualTalk 하나로 호출하고, 결과는 await로 받습니다.

미리 보기 버전지금 SDK는 개발 환경 서버(localhost:8080)에 연결되도록 고정되어 있습니다. 게임 등록(AppID 발급)도 아직 관리자 도구 없이 수동으로 진행합니다. Unreal Engine 5 SDK는 준비 중입니다.

설치

  1. SDK 폴더 Assets/CasualTalk를 Unity 프로젝트의 Assets 아래에 복사합니다.
  2. 패키지 매니저에서 com.unity.nuget.newtonsoft-json이 설치되어 있는지 확인합니다. 채팅 메타데이터를 JSON으로 바꿀 때 씁니다.
  3. 발급받은 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.HttpPollInterval마다 HTTPS로 새 채팅을 가져옵니다.소켓을 쓸 수 없는 웹 · 일부 플랫폼

API

Initialize

Task<CasualTalkResponse> Initialize(CasualTalkInitializeOption option)

게임 인증을 하고 채팅 서버에 연결합니다. 다른 API보다 먼저 한 번 호출합니다. 실패하면 내부 상태를 정리하므로 다시 호출할 수 있습니다.

옵션 (CasualTalkInitializeOption)

속성타입설명
AppIDstring필수. 게임마다 발급받는 ID. 영문·숫자·_·-, 1~32자
UserIDstring필수. 게임 안의 플레이어 ID, 1~64자. 같은 값이면 다시 접속해도 같은 UserIDX를 받습니다
ModeCasualTalkModeTcp(기본) 또는 Http
PollIntervalTimeSpanHttp 모드에서 새 채팅을 가져오는 간격. 기본 250ms, 100ms보다 짧게 해도 효과가 없습니다

성공하면 CasualTalk.IsInitialized가 true가 되고, 서버가 발급한 내 번호를 CasualTalk.UserIDX로 읽을 수 있습니다. 이미 초기화된 상태에서 다시 부르면 DuplicateConnection을 돌려줍니다.

AddListener

CasualTalkResponse AddListener(ICasualTalkListener listener)

새 채팅을 받을 객체를 등록합니다. 같은 객체를 두 번 등록하면 Failed를 돌려줍니다. 알림은 SDK가 만든 CasualTalk 게임 오브젝트가 매 프레임 메인 스레드에서 전달하므로, 콜백 안에서 바로 UI를 바꿔도 됩니다.

public interface ICasualTalkListener
{
    void OnNotifyChatRoom(string roomID, DataChat chat);
}

JoinRoom

Task<CasualTalkResponse<SC_JoinRoomAck>> JoinRoom(string roomID)

방에 들어갑니다. 방은 따로 만들 필요 없이 이름으로 들어가면 생깁니다. 같은 방 이름이라도 다른 게임(AppID)과는 섞이지 않습니다.

응답 (SC_JoinRoomAck)

필드타입설명
RoomIDstring들어간 방 이름
UserDataUser나 (UserIDX)
ChatsList<DataChat>입장 전 최근 대화
UsersList<DataUser>방에 있는 유저. Tcp 모드 유저만 들어 있습니다

ChatRoom

Task<CasualTalkResponse<SC_ChatAck>> ChatRoom(string roomID, string message, IReadOnlyDictionary<string, object> metadata = null)

방에 채팅을 보냅니다. metadata는 JSON으로 바뀌어 그대로 전달되고, 받는 쪽은 DataChat.Meta로 읽습니다. 닉네임, 아이콘, 아이템 링크처럼 게임이 정한 정보를 실을 때 씁니다. SDK와 서버는 내용을 해석하지 않습니다.

await CasualTalk.ChatRoom("guild-42", "이 아이템 어때요?",
    new Dictionary<string, object> { ["nick"] = "하늘바람", ["item"] = 10231 });

1초에 30건을 넘기면 넘친 채팅은 TooManyRequest로 거부됩니다.

QuitRoom

Task<CasualTalkResponse<SC_QuitRoomAck>> QuitRoom(string roomID)

방에서 나갑니다. 이후 그 방의 채팅은 더 이상 받지 않습니다.

TranslateChat

Task<CasualTalkResponse<SC_TranslateAck>> TranslateChat(string roomID, string messageID, string lang)

받은 채팅 하나를 원하는 언어로 번역합니다. 원문은 서버가 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

Task<CasualTalkResponse<SC_NoticeRoomAck>> SetNoticeRoom( string joinMessage, IReadOnlyDictionary<string, object> joinMetadata, string quitMessage, IReadOnlyDictionary<string, object> quitMetadata)

내가 방에 들어오거나 나갈 때 서버가 나 대신 그 방에 남길 채팅을 등록합니다. 다른 유저에게는 일반 채팅처럼 OnNotifyChatRoom으로 전달됩니다. 다시 부르면 덮어씁니다.

  • 입장 메시지는 JoinRoom이 성공할 때 남습니다.
  • 퇴장 메시지는 QuitRoom, Tcp 연결 끊김, Http Poll 중단 때 남습니다.
  • 메시지와 메타데이터가 모두 비어 있으면 남기지 않습니다.
await CasualTalk.SetNoticeRoom(
    "하늘바람 님이 들어왔어요", new Dictionary<string, object> { ["type"] = "join" },
    "하늘바람 님이 나갔어요", new Dictionary<string, object> { ["type"] = "quit" });

Close

void Close()

연결을 끊고 SDK 상태를 정리합니다. 게임 종료 시(OnApplicationQuit) 호출합니다. 이후 다시 Initialize할 수 있습니다.

데이터 타입

CasualTalkResponse / CasualTalkResponse<T>

모든 비동기 API의 결과입니다. 연결 전에 호출하면 서버에 보내지 않고 바로 NotConnected를 돌려줍니다.

멤버타입설명
IsSuccessboolErrorCode == Success
ErrorCodeErrorCode결과 코드 (에러 코드)
DataT서버 응답. 실패하면 null

DataChat

필드타입설명
UserIDXulong보낸 유저 번호. 같은 게임의 같은 플레이어는 항상 같은 값
Chatstring채팅 원문
MessageIDstring메시지 고유 ID. TranslateChat에 넘깁니다
Metastring보낸 쪽이 넣은 metadata의 JSON. 없으면 빈 문자열

SC_TranslateAck

필드타입설명
Textstring번역문
Langstring요청한 언어
RoomID, MessageIDstring요청한 값 그대로

에러 코드

값이름언제
0Failed요청이 거부되거나 처리 중 실패함 (등록되지 않은 AppID, 잘못된 입력 등)
1Success성공
2DuplicateConnection이미 초기화된 상태에서 Initialize를 다시 호출함
3NotConnectedInitialize 전이거나 Close 후에 호출함
4Timeout서버 응답이 시간 안에 오지 않음
5TooManyRequest1초에 30건을 넘겨 채팅함

제한 사항

항목내용
채팅 속도유저당 1초에 30건. Tcp · Http 모두 같은 기준
번역 언어한국어(ko), 영어(en), 일본어(ja)
방 대화 보관방마다 최근 약 1,000건. Http 모드에서 오래 끊겼다 돌아오면 남아 있는 대화부터 받습니다
Http 모드 퇴장앱이 비정상 종료되면 퇴장이 바로 알려지지 않을 수 있습니다
유저 확인CasualTalk는 UserID를 게임이 보낸 그대로 믿습니다. 플레이어 인증은 게임 쪽에서 마친 뒤 초기화하세요