Photon Server Plugin — 부가 기능(2)
이전 파트에서 서버 쪽 구성 파일을 생성해보았습니다. 지금부터는 클라이언트 측에 구현해야만 Photon Plugin과 통신할 수 있는지에 대해 알아보겠습니다~
클라이언트에서 우리는 Unity 내 PUN(Photon Unity Networking)을 사용합니다. 만약에 Photon에서 제공하는 Unity Asset을 본 적이 없다면 우선 아래 문서의 입문 소개 및 조작 부분을 보시면 바로 실습해볼 수 있습니다! 🎯
Tanks, Multiplayer with PUN! (Part 1)
클라이언트 측 구현
깔끔하고 심플하게 만들기 위해 우리는 PhotonPluginTest라는 새로운 별개 파일을 만들고, 별개 파일 Assets 안에 Asset Store에서 다운로드한 PUN을 넣고, 다시 별개 파일 디렉터리 PhotonPluginTest를 생성합니다. 그 안에 Scene과 Script를 넣으면 총 두 개 스크린, 두 개 프로그램이 보입니다. 완성된 파일 구조는 아래 그림과 같습니다.
Unity 내, 우리의 PhotonPlugin 별개 파일 구조
- StartScene은 시작 화면으로, Photon Server와의 연결 로그인에 사용합니다.
- cs는 우리 게임에서 PhotonServer와만 통신하는 전용 요소로, Photon.PunBehaviour에서 가져온 것입니다. 프로그램 코드:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PhotonManager : Photon.PunBehaviour {
public static PhotonManager instance;
//로컬 사용자
public static GameObject localPlayer;
// 캐릭터 진입 지점
GameObject defaultSpawnPoint;
void Awake()
{
if (instance ! = null)
{
DestroyImmediate(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
instance = this;
//PUN의 맵 로딩 자동 동기화를 사용할 수 있고, 맵 로딩 초기화 시 발생할 수 있는 네트워크 문제를 피할 수 있습니다.
PhotonNetwork.automaticallySyncScene = true;
}
void Start () {
Connect();
// InvokeRepeating("UpdateStatus", 2, 1);
}
void Connect() {
//Photon Cloud/Server와의 연결 시작 시 게임 버전은 문자열 모드로 설정
PhotonNetwork.ConnectUsingSettings("PUN_PhotonPlugin_1.0");
}
void UpdateStatus() {
string status = PhotonNetwork.connectionStateDetailed.ToString();
Debug.Log(status);
}
public void JoinGameRoom()
{
//게임룸과 명칭 설정 시 사용자 인원수 최대 2명
RoomOptions options = new RoomOptions();
options.MaxPlayers = 2;
// options.Plugins = ;
PhotonNetwork.JoinOrCreateRoom("RoomPlugins", options, TypedLobby.Default);
}
public override void OnConnectedToMaster ()
{
//마스터 서버에 연결 후, 버튼(UI)으로 기타 후속 동작을 표시하거나 실행할 수 있습니다.
Debug.Log("Master Server에 접속하였습니다");
}
public override void OnJoinedRoom()
{
Debug.Log("룸에 진입했습니다");
//마스터 클라이언트일 경우, 즉시 구축 및 초기화하고 게임 화면 로딩 가능
if (PhotonNetwork.isMasterClient)
{
PhotonNetwork.LoadLevel("GameRoomScene");
}
}
//게임 화면 로딩
void OnLevelWasLoaded(int levelNumber)
{
if (!PhotonNetwork.inRoom) return;
Debug.Log("게임 화면 로딩/게임룸내");
}
public override void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
{
Debug.Log("Other Player Entered." );
}
}
아래에서 화면에서 우리 관리자를 대표하는 요소인 PhotonManager.cs를 볼 수 있습니다. 다음은 설정 화면입니다.
Photon Manager
StartScene 화면에서도 JoinRoomButton만 존재합니다. OnClick 상태에서 PhotonManager.JoinGameRoom을 호출하기 때문에, PUN초기화 프로그램을 기다려야 하고, 마스터 서버 에 연결하는 경우에는 해당 버튼을 클릭해야만 게임룸으로 입장할 수 있습니다. 다음은 설정 화면입니다.
JoinGameRoom & OnClick Event
- 게임 서버에 연결 후GameRoomScene이 로딩되고 나면, 우리는 해당 화면에 EventObject를 생성하고, 해당 객체로 서버 쪽의 Photon Plugin과 연결합니다. 간단한 설정 화면은 다음과 같습니다.
GameRoomScene 화면에서, PhotonServer와 연결한 EventObject
- cs는 우리 사용자를 대표합니다. 룸에서 PhotonServer와 연결해 원하는 이벤트를 촉발하고 수신합니다. 따라서 여기에서도Photon.PunBehaviour을 가져오게 됩니다.
프로그램 코드:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class EventObject : Photon.PunBehaviour {
void Awake()
{
PhotonNetwork.OnEventCall += this.OnEvent;
}
public void DoRaiseEvent()
{
byte evCode = 1;
// byte[] content = new byte[] { 3, 6, 9 };
bool reliable = true;
PhotonNetwork.RaiseEvent( evCode, null, reliable, null);
}
private void OnEvent( byte eventCode, object content, int senderID)
{
if ( (eventCode == 1) && (senderID <= 0) )
{
// PhotonPlayer sender = PhotonPlayer.Find(senderid);
int counter = (int)content;
Debug.Log( string.Format("Counter from Server: {0}", counter ));
}
}
}
- 화면에 있는 RaiseEventButton으로 DoRaiseEvent를 호출하면 Photon Plugin에 이벤트 정보 및 데이터를 발송할 수 있습니다. 이하 설정 진행:
Raise Event Button 및 EventObject.DoRaiseEvent
실행 및 테스트
Photon Server가 실행되었나요? 아직 실행되지 않았다면 우선 이전 파트 내용을 다시 보면서 실행시켜보세요! 이 과정이 끝나야만 다음 진도를 나갈 수 있습니다!
Photon Server를 정상적으로 실행시킨 후, Unity로 돌아왔습니다. 우선 서버의 일부 매개 변수 IP 주소, 포트, 프로토콜 등의 값을 설정하고, PUN에 제공하면 우리 대신 서버의 동작을 자동으로 연결합니다. 설정 영역에서 Unity의 Window → Photon Unity Networking → Highlight Server Settings를 찾아보면, 아래와 같은 화면이 전출됩니다.
PUN의 Photon Server Settings
위 그림은 자가 서버이기 때문에 Self Hosted를 선택했고, IP는 인트라넷 값에 서버 포트는 변경 없이 그대로 사용, 프로토콜은 우선 UDP 선택을 권장합니다. 자가 서버이고, AppId는 현재 사용하지 못하니, 나중에 설정해도 됩니다.
이어서 Unity의 Build로 게임 사용자 프로그램을 데스크탑 버전으로 설정하고 실행시킵니다.
Unity로 돌아와 StartScene 화면으로 변경해 Play를 눌러 프로그램을 실행시킵니다.
이렇게 아래 그림과 같이 두 개 클라이언트가 작동되었습니다.
두 클라이언트 : MacOS 버전 및 Unity 내 Play Mode
위 그림에서, 실행 후 PUN과 Photon Server 연결 및 마스터 서버와 연결될 때까지 기다리고 나면 클라이언트마다 Join Game Room 버튼을 눌러 쉽게 게임 서버로 입장합니다.
두 클라이언트 모두 게임 서버와 연결되고 나면 Raise Event 버튼이 생성되고 각자 해당 Raise Event Button을 몇 번 클릭합니다.
예시 그림:
게임 룸 입장 후, 다시 Raise Event 버튼 클릭
Nothing Happened?! What the … 😱 무슨 일이 일어난 것일까요? 😮
조급해하지 말고, 게임 화면 내 EventObject.cs 속 두 개의 기능에 주목해봅시다.
- DoRaiseEvent: Photon Server에 이벤트 1개 발송할 때, 코드번호=1, 자체 데이터 불필요 설계 상 필요한 경우, 데이터 포함 상태로 전송할 수 있습니다.
- OnEvent: Photon Server에서 전송해 온 이벤트를 수신합니다. 우리는 오직 코드 번호=1만 수신하고, 서버 id(Sender ID 정수=사용자)만 진입 처리합니다.
따라서, 이 둘(클라이언트 — 서버) 사이에 무슨 작업들이 이루어질까요?
- Raise Event Button 클릭 시, 클라이언트의DoRaiseEvent에서 Photon Server에 이벤트 송출 내용을 알립니다.
- 우리가 작성한 Photon Plugin 이벤트 알림을 수신하고 나면, 우리가 설계한 동작이 실행됩니다: 카운팅 1회, Broadcast카운터값 및 이벤트 코드(코드번호= 1)를 동일 룸에 있는모든 사용자에게 발송하게 됩니다.
- 클라이언트마다 이벤트 알림을 수신하고 나면, OnEvent 가 호출되는데, 우리가 설계한 EventCode(해당 샘플 내값= 1), Sender ID 가 사용자가 아니라고 판단되면, 데이터를 인출해, console 내(Debug.Log) 표시합니다.
따라서 우리가 서로 다른 클라이언트에서 RaiseEventButton을 몇 번 클릭하고 나면 Console 에서 서버에서 전송해 온 카운터값을 볼 수 있고, 클릭한 횟수대로 증가하게 됩니다.
예시 화면:
Counter Value는 클라이언트에서 Raise Event를 발송할 때마다 증가
결국, 우리는 Photon Plugin 방식으로 클라이언트 — 서버를 연결해 데이터를 처리합니다. 간단하죠! 본 스텝 과정을 모두 마무리했습니다. 이제 플러그인 방식의 장점에 대해 어느 정도 이해하셨죠? 😀
이전에는 이러한 목적을 달성하려면 자체적으로 서버 애플리케이션 확장 및 많은 프로그램 코드를 입력한 후 구성 파일을 배치해야만 했었는데 그렇다 해도 운행에 성공한다거나 쉽게 그 방식을 이해하는 것은 아닙니다. (이미 머리가 아파…) 이후 게임 구조 확충 방법은 나중에..
요약
Photon Plugin과 플레이어 간 전송 방식은 일반적으로 말해 클라이언트 -> 서버, 서버 -> 클라이언트의 단방향 발송이긴 하나, 이번에 해본 방식으로는 쌍방향 전송이 가능하며, 플러그인이 이 둘 사이에서 관련 사용자 간의 데이터 연산 처리에 참여하고 있습니다.
이 프로젝트에서 플러그인을 쉽게 이해하기 위해 서버 측 컴퓨팅만 했으나, 이는 플러그인에서 더 나아가 Photon Server 내부와의 데이터를 액세스할 수 있거나 서버 외부의 데이터 베이스, 클라우드 컴퓨팅, WebService와 통신함을 의미합니다. 제3자 Google Cloud Platform, AWS, Microsoft Azure 등의 서버 플랫폼과 같은 구조입니다. 🎯
이런 구조만이 데이터를 안전하게 처리할 뿐 아니라, 클라이언트 쪽에서 우리의 처리 방법을 알 필요도 없게 됩니다. 더 큰 장점은, 미래의 게임 구조를 아주 쉽게 구상 및 발전시킬 수 있다는 점입니다! 👏🏻
좋은 아이디어가 생각나지 않았나요? 그렇다면 빨리 시작해보시고, 그 기능의 파워를 테스트해보세요! 👍
모든 궁금한 문제나 의견이 있을 경우,https://www.facebook.com/photoncloudkr/ 으로 메시지를 주시거나,
developer@photonengine.kr로 메일 주세요!
댓글
댓글 0개
댓글을 남기려면 로그인하세요.