포톤 챗은 포톤 서버의 기능 중 하나이다.

 각 기능은 dashboard.photonengine.com/en-US/PublicCloud 에서

 CREATED A NEW APP 을 통해 포톤타입을 지정해야하며,

 하나의 게임에서 다양한 타입의 포톤 기능을 사용하고 싶다면,

 필요한 기능 갯수 만큼의 APP ID 를 CREATED A NEW APP 을 통하여 만들어야한다.

 

 아래에서 기술하는 사용방법은 본인이 성공한 방법대로 적었다.

--------------------------------------------------------------------------------

 

1. 먼저 에셋 스토어에서 포톤 챗을 다운로드 받아 임포트한다 (무료)

assetstore.unity.com/packages/tools/network/photon-chat-45334

 

Photon Chat | 네트워크 | Unity Asset Store

Get the Photon Chat package from Exit Games and speed up your game development process. Find this & other 네트워크 options on the Unity Asset Store.

assetstore.unity.com

 

 

 

---------------------------------------------------------------------------------

 

2. 포톤 챗을 임포트 한 뒤 포톤 PUN2 를 임포트한다 (무료)

assetstore.unity.com/packages/tools/network/pun-2-free-119922

 

PUN 2 - FREE | 네트워크 | Unity Asset Store

Get the PUN 2 - FREE package from Exit Games and speed up your game development process. Find this & other 네트워크 options on the Unity Asset Store.

assetstore.unity.com

 

 이유를 정확히 확인 할 수 없었으나, PUN2 -> Chat 순으로 임포트 하는 경우 에러메세지가 검출되는 경우가 있었다.

 PUN2 에셋 안에 Chat 에셋 및 데모가 들어있으나 임포트를 하면서 덮어쓰자.

 

 

--------------------------------------------------------------------------------

 

3. dashboard.photonengine.com/en-US/PublicCloud 에서 CREATED A NEW APP 을 클릭

<좌측 최 하단의 버튼을 누르자>

 

Photon Type 을 Photon Chat 으로 바꾸고, 적당히 이름과 설명을 적고 CREATE 를 누르자

 

 

다음과 같은 화면을 볼 수 있다.

큰 검은 사각형은 CREATED A NEW APP 에서 적었던 어플리케이션 이름이 있을 것이고

APP ID 는 복사가 가능한 ID 가 생성되어있다.

 

 

복사한 아이디는

Asset - Resources - ChatSettingFile 과

Asset - Photon - PhotonUnityNetwork - Resources - PhotonServerSettings 의 App Id Chat

 

양쪽에 다 넣어주자.

 

ChatSettingFile 은 Photon Chat 을 임포트할 때 생성되고

PhotonServerSettings 는 Photon PUN2 를 임포트할 때 생성된다.

 

두 세팅파일의 App Id 에 접근하고 싶다면

ChatSettingFile -> ChatSettings.Instance.AppId;

PhotonServerSettings -> PhotonNetwork.PhotonServerSettings.AppSetting.AppIdChat

으로 접근할 수 있다.

 

 

발급받은 App ID 를 입력하자

 

 

 

------------------------------------------------------------------------------------------------

 

 PhotonChat 의 구현은 기본 스크립트에 IChatClientListener 라는 인터페이스를 상속받아서 만든다.

 상속받은 인터페이스의 구현만으로 채팅 프로그램을 만들 수 있다.

 

 편집기에서 IChatClientListener 의 정의로 이동하면 각 메소드가 가져야 할 기능에 대한 설명이 적혀있다.

 

 

using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Chat;
using Photon.Realtime;
using Photon.Pun;
using AuthenticationValues = Photon.Chat.AuthenticationValues;
using ExitGames.Client.Photon;

public class PhotonChatTest : MonoBehaviour, IChatClientListener
{

    private ChatClient chatClient;
    private string userName;
    private string currentChannelName;

    public InputField inputFieldChat;
    public Text currentChannelText;
    public Text outputText;
    
    // Use this for initialization
    void Start()
    {
        Application.runInBackground = true;

		// 유저 닉네임은 서버에 접속하면 변경하기 힘들다
        // 테스트시 유저의 구분을 위하여 현재 시간을 유저명으로 임시 설정
        userName = DateTime.Now.ToShortTimeString();
        currentChannelName = "Channel 001";
        
        chatClient = new ChatClient(this);

		// true 가 아닌 경우 어플이 백그라운드로 갈 때 연결이 끊어진다
        chatClient.UseBackgroundWorkerForSending = true;
        chatClient.Connect(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat, "1.0", new AuthenticationValues(userName));
        AddLine(string.Format("연결시도", userName));
    }

	// 현재 채팅 상태를 출력해줄 UI.Text
    public void AddLine(string lineString)
    {
        outputText.text += lineString + "\r\n";
    }

	// 어플리케이션이 종료되었을 때 호출
    public void OnApplicationQuit()
    {
        if (chatClient != null)
        {
            chatClient.Disconnect();
        }
    }

	// DebugLevel 에 정의 된 enum 타입에 따라 메세지를 출력한다
    public void DebugReturn(ExitGames.Client.Photon.DebugLevel level, string message)
    {
        if (level == ExitGames.Client.Photon.DebugLevel.ERROR)
        {
            Debug.LogError(message);
        }
        else if (level == ExitGames.Client.Photon.DebugLevel.WARNING)
        {
            Debug.LogWarning(message);
        }
        else
        {
            Debug.Log(message);
        }
    }

	// 서버에 연결을 성공함
    public void OnConnected()
    {
        AddLine("서버에 연결되었습니다.");
		
        // 지정한 채널명으로 접속
        chatClient.Subscribe(new string[] { currentChannelName }, 10);
    }

	// 서버와의 연결이 끊어짐
    public void OnDisconnected()
    {
        AddLine("서버에 연결이 끊어졌습니다.");
    }

	// 현재 클라이언트의 상태를 출력
    public void OnChatStateChange(ChatState state)
    {
        Debug.Log("OnChatStateChange = " + state);
    }

    public void OnSubscribed(string[] channels, bool[] results)
    {
        AddLine(string.Format("채널 입장 ({0})", string.Join(",", channels)));
    }

    public void OnUnsubscribed(string[] channels)
    {
        AddLine(string.Format("채널 퇴장 ({0})", string.Join(",", channels)));
    }

	// Update() 의 chatClient.Service() 가
    // 매 호출 시 OnGetMessages 를 호출한다.
    public void OnGetMessages(string channelName, string[] senders, object[] messages)
    {
        if (channelName.Equals(currentChannelName))
        {
            // update text
            this.ShowChannel(currentChannelName);
        }
    }
    public void ShowChannel(string channelName)
    {
        if (string.IsNullOrEmpty(channelName))
        {
            return;
        }

        ChatChannel channel = null;
        bool found = this.chatClient.TryGetChannel(channelName, out channel);
        if (!found)
        {
            Debug.Log("ShowChannel failed to find channel: " + channelName);
            return;
        }

        this.currentChannelName = channelName;
        // 채널에 저장 된 모든 채팅 메세지를 불러온다.
        // 유저 이름과 채팅 내용이 한꺼번에 불러와진다.
        this.currentChannelText.text = channel.ToStringMessages();
        Debug.Log("ShowChannel: " + currentChannelName);
    }


	// 개인 메세지를 보낼 경우 사용하는 메소드
    public void OnPrivateMessage(string sender, object message, string channelName)
    {
        Debug.Log("OnPrivateMessage : " + message);
    }

    public void OnStatusUpdate(string user, int status, bool gotMessage, object message)
    {
        Debug.Log("status : " + string.Format("{0} is {1}, Msg : {2} ", user, status, message));
    }

	// 포톤 엔진 공식 홈페이지에도 기술되어 있는 내용이다
    // chatClient.Service() 를 Update 에서 호출하던지
    // 필요에 따라 chatClient.Service() 를 반드시 호출 해야한다
    void Update()
    {
        chatClient.Service();
    }

    public void OnUserSubscribed(string channel, string user)
    {
        throw new System.NotImplementedException();
    }

    public void OnUserUnsubscribed(string channel, string user)
    {
        throw new System.NotImplementedException();
    }


	// 인스펙터의 InputField 에서 입력받은 메세지를 보낼 때 사용한다.
    // InputField 의 On End Edit 에 이 메소드를 할당하자.
    public void OnEnterSend()
    {
        if (Input.GetKey(KeyCode.Return) || Input.GetKey(KeyCode.KeypadEnter))
        {
            this.SendChatMessage(this.inputFieldChat.text);
            this.inputFieldChat.text = "";
        }
    }

	// 입력한 채팅을 서버로 전송한다.
    private void SendChatMessage(string inputLine)
    {
        if (string.IsNullOrEmpty(inputLine))
        {
            return;
        }

        this.chatClient.PublishMessage(currentChannelName, inputLine);
    }
}

 

해당 스크립트가 들어간 오브젝트는 다음과 같은 모습이 되어있다.

Input Field Chat 은 서버로 보내기 전 채팅을 입력받는 역할을 한다.

하단의 사진과 같이 설정하면 접속 후 메세지를 입력한 뒤 엔터를 눌러서 서버에 메세지를 보낼 수 있다.

 

Current Channel Text 는 채팅창의 역할을 하는 오브젝트로, 유저의 모든 채팅이 표시되는 공간이다.

데모에는 Mask 와 ScrollPanel 을 이용하여 마스크 밖으로 나가는 채팅 메세지는 표시하지 않도록 만들었다.

 

Ouput Text 는 디버그 용으로 접속 상태를 표시한다.

 

 

 

----------------------------------------------------------------------------------------------------

 

이것이 기본적인 포톤 챗을 구현하는 방법이다.

제대로 작동하는지 확인하고 싶다면,

지금까지 만든 테스트용 포톤 챗을 익스포트하여 새 에디터에서 돌리거나

1개 이상의 릴리즈를 만들어서 확인해도 된다.

 

그외 기본적인 사용 방법은 포톤엔진 공식 홈페이지나, 공식 티스토리에 기술되어있다.

+ Recent posts