내일배움캠프 41일차 TIL, 2D 멀티 - Photon

황오영·2024년 6월 14일
0

TIL

목록 보기
41/56

심화주차 강의 - 포톤

<출처 내배캠 게임개발 심화주차 강의노트>

  • 오늘 서버강의를 들어서 내용정리를 하려고 한다.
  • 서버는 뒤끝서버 이용해서 강의를 들었었는데 그때도 비동기 콜백에 대해서 많이 어려웠는데 포톤은 어떤지 잘 정리해야 겠다.

멀티 게임

  • 맨처음 게임개발을 시작할 때 대부분은 싱글플레이로 개발을 하지만 최근 기술에 발전으로 멀티플레이에 대한 접근성이 좋아졌다.
  • 특히나 게임에서 소셜의 요소는 빼놓을수 없고 나 역시 게임은 같이하는맛이지! 하는 생각이 있고 최근 모바일 게임의 싱긒플레이 게임보다 40%가량 늘 만큼 멀티게임에 대한 수요와 관심이 더 늘었다고 한다.

네트워크 용어

  • IP Address : 인터넷에 연결된 장치들을 식별하기 위한 고유 주소 서로 통신을 하기위해 필요
  • Port : IP주소 내에서 포트는 특정 애플리케이션 또는 서비스를 지정하는데 사용 웹의 경우 포트 80, 443을 지원한다(HTTP, HTTPS)
  • 라우팅 : 데이터 패킷이 송신자에서 수신자에게 도달하기 위한 네트워크 경로
  • 패킷 : 네트워크를 통해 전송되는 데이터 큰 데이터의 경우 여러 패킷으로 분할되어 전송된다.
  • TCP : 신뢰성 있는 데이터 전송을 보장 (속도가 조금 걸림)
  • UDP : 신속한 데이터 전송을 위한 설계 (손실이 있을 수 있음)

통신 방법

  • 클라이언트 - 서버 : 중앙 서버에서 클라이언트의 요청을 처리하고 응답하는 역할
  • P2P 모델 : 중앙 집중 서버 없이 참여자가 서로 통신하는 방식식

게발에서의 주의사항

  • 비동기적 로직 : 서버의 로직들은 비동기적으로 처리된다 적 결과가 바로 활용되는 것이 아닌 콜백등을 이용하여 처리결과를 받아 이어서 처리한느 방식이 되므로 프로그램의 복잡도가 높아진다.
  • 틱 빈도 : 게임 서버가 로직을 업데이트하는 빈도, 틱률이 높아지면 부드럽고 정확한 게임이 되지만 서버에 부하가 걸린다. 즉 적절한 틱 빈도를 설정해야 한다.
  • 지연(Latency) 네트워크 지연 시간은 플레이어 간의 상호작용을 심각하게 저해하고 플래이 경험을 낮춘다. 특히나 실시간 멀티플레이에선 낮은 지연 시간을 유지해야 한다.
  • 연결 해제 : 네트워크 불안정으로인해 게임연결이 해제되었을때도 처리를 해줘야함 게임플레이에 부정적인 영향을 미칠수 있다. 악용의 가능성
  • 검증 : 클라이언트에서 수행한 방식이 올바른지 유효성검사가 필요하다.

사용되는 백엔드 솔루션

  • 포톤 : 유니티와 긴밀한 통합으로 많은 인디 개발자들이 선호하고 빠르게 구현이 가능한 강렬한 툴 단 동시접속 유저수가 적은 개발에 유리
  • UGS : 멀티플레이어 개발을 위한 유니티의 공식 솔루션 이것 역시 동접수가 적은 개발에 유리
  • Firebase : 간단하고 빠르게 기초적인 백엔드를 구현할 수 있다. 보통 인증, 데이터베이스에 많이 사용, 싱글플레이에 적합하다.
  • PlayFab : 마이크로소프트에서 제공한다 하지만 한국커뮤니티는 지원이 살짝 부족
  • 뒤끝 : 한국지원이 잘 되어있어 한국에서 인기가 있음 길드 우편함등의 소셜기능 지원, 양산형 게임으로 데이터 서버 저장, 인증 기능과 같은 싱글플레이에 적합하다.

포톤

포톤

  • Exit Games에서 개발한 멀티플레이어 게임개발을 위한 네트워크

특징

  • 실시간 멀티플레이 게임에 초첨
  • 사용하기 쉬운 API
  • 별도의 설정 없이 CCU증가에 대한 설정 가능

자주 사용되는 클래스

PhotonNetwork

  • 내장 메소드
  1. ConnectUsingSettings : 포톤 클라우드에 연결
  2. CreateRoom 및 JoinRoom : 방을 파고 만듬!
  3. Instantiate : 네트워크 상에서 오브젝트를 생성 네트워크 동기화 작업

MonoBehaviourPunCallbacks

  • 내장 메소드
  1. OnConnectedToMaster : 게임이 포톤 마스터 서버에 연결 하면 호출
  2. OnJoinedRoom : 로컬플레이어 참가하면 호출
  3. OnPlayerEnteredRoom : 다른 플레이어가 들어가면 호출

자주 사용하는 컴포넌트

1.PhotonView
2.PhotonTransformView
3.PhotonAnimatorView
4.PhotonRigidbodyView
움직임을 위한 뷰들이 많음 변수와 상태를 동기화

예시 코드

using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using TMPro;

public class LobbyManager : MonoBehaviourPunCallbacks
{
    [SerializeField] private TextMeshProUGUI StatusText; 
    [SerializeField] private GameObject waitPanel;

    private readonly int MAX_USERS = 2;
    private bool connect = false;
    
    // 현재 상태 표시 
    private void Update() => StatusText.text = "Current Status: " + PhotonNetwork.NetworkClientState.ToString();

    // 서버 접속
    public void Connect() => PhotonNetwork.ConnectUsingSettings();
    
    // 연결 끊기
    public void Disconnect() => PhotonNetwork.Disconnect();
    
    // Disconnect 이벤트 콜백
    public override void OnDisconnected(DisconnectCause cause) => Debug.Log("Disconnected");

    // Connect 이벤트 콜백
    public override void OnConnectedToMaster()
    {
        Debug.Log("Connected To Server");
        connect = true;
    }

    // 입장
    public void JoinRoom()
    {
        if(connect)
        {
            PhotonNetwork.JoinRandomRoom();
            Debug.Log( "Entered");
        }
        else
        {
            Debug.LogWarning("Not Connected");
        }
    }

    // 랜덤 룸 입장에 실패하면 새로운 방 생성
    public override void OnJoinRandomFailed(short returnCode, string message) =>
        PhotonNetwork.CreateRoom(Random.Range(1,1000).ToString(), new RoomOptions { MaxPlayers = MAX_USERS });

    // Join 이벤트 콜백
    public override void OnJoinedRoom()
    {
        int currentPlayers = PhotonNetwork.CurrentRoom.Players.Count;

        // 꽉 차면 바로 시작작
        if(currentPlayers == PhotonNetwork.CurrentRoom.MaxPlayers)
        {
            PhotonNetwork.LoadLevel(1);
        }
        else
        {
            // 대기 필요, 더 많은 플레이어를 기다리는 로직
            Debug.Log(currentPlayers + " / " + PhotonNetwork.CurrentRoom.MaxPlayers + " players joined. Waiting for more...");
            // 대기 UI 활성화 또는 기타 로직 구현
            waitPanel.SetActive(true); // 가정: uiPanel이 대기중인 플레이어를 위한 UI라고 가정합니다.
        }
    }

    public override void OnPlayerEnteredRoom(Player newPlayer)
    {
        // 더이상 들어오지 않도록 막음.
        PhotonNetwork.CurrentRoom.IsOpen = false;
        // 두 명이서 하는 게임으로, 더이상 체크할 필요 없음.
        waitPanel.SetActive(false);
        PhotonNetwork.LoadLevel(1);
    }
}

오늘의 회고

  • 생각보다 포톤 서버가 재미있었다. 최종때 사용을 할 기회가 있을지는 모르겠지만 가능하다면 해보는것도? 서버를 사용할지 말지에 대해 걱정이 있다 해보고 싶긴 한데.. 일단 팀원분들과 회의를 진행해야 할듯
  • 주말엔 대략적으로 레퍼런스 게임들 정리하고 컨텐츠 정리하고 등등 기획안을 짜볼 예정이다.. 최종 프로젝트 준비하려고 하니 할것이 너무많다 힘내야지
  • 프레임워크도 조금 수정해야 할듯 튜터님들이 얘기해주신 부분이 많아서 이런부분들을 수정해서 사용해야겠다. 싱글톤이라던가 Resources.load함수 관련해서 사용한다거나.
  • 특히 Adreesable 얘기를 많이 해주셨는데 가능하다면 같이 해보는걸로!
  • 날씨가 많이 덥다 체력관리 잘 해야겠다.
profile
게임개발을 꿈꾸는 개발자

0개의 댓글