레트로의 유니티6 : NGO 네트워크 게임 PONG - 1

댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!

댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!
NetworkManager 컴포넌트는 네트워크 게임에서 네트워크의 전반적인 상태를 관리함. 게임 도중 동시에 두 개 이상의 네트워크 매니저가 활성화되어 있으면 안됨.
플레이어 프리팹
NetworkObject 컴포넌트가 포함되어 있어야 합니다.NetworkObject가 붙은 모든 네트워크 프리팹을 등록합니다.→ 즉, Default Player Prefab은 “기본 플레이어로 사용할 프리팹”이고, Network Prefabs Lists는 “네트워크 생성이 허용된 프리팹 전체 목록”입니다.

넷코드에서 네트워크를 거쳐 스폰할 모든 네트워크 프리팹들은 미리 네트워크 매니저에 등록되어야 한다. 미리 클라이언트들 사이에 약속되지 않은 프리팹이 네트워크 게임 도중에 스폰되어서는 안되기 때문.
따라서 다음 과정을 통해 네트워크 프리팹 리스트 에셋을 생성하고, 생성된 에셋 게임 도중 사용할 네트워크 프리팹을 등록할 수 있음.

DefaultNetworkPrefabs 에셋은 새 네트워크 매니저 컴포넌트를 생성할 때 Network Prefabs Lists 필드에 자동 할당
트랜스포트
네트워크 매니저가 사용할 트랜스포트(Transport)로 UnityTransport를 설정햇음. 유니티 넷코드는 게임 개발과 관련된 네트워크 기능을 쓰기 쉽게 추상화하여 제공함.
트랜스포트 레이어에서는 네트워크 드라이버를 사용하는 구체적인 구현들이 있고, 어떤 네트워크 프로토콜을 사용할지, 단일 패킷의 최대 크기는 얼마나 할지 등을 결정함.
넷코드에서 사용할 트랜스포트는 교체 가능. 원하면 트랜스포트 레이어를 직접 구현할 수 있음. 현재는 넷코드 패키지와 함께 설치된 기본 트랜스포트 패키지인 UnityTransport를 사용할거임.



주요 필드는 다음 두가지
Address : 연결할 호스트 주소, 접속하려는 호스트 컴퓨터의 IP 주소입니다. 같은 컴퓨터에서 테스트할 때는 보통 127.0.0.1을 사용합니다.
Port : 사용할 포트 번호, 네트워크 프로그램이 통신할 때 사용할 출입구 번호입니다. 호스트와 클라이언트가 같은 번호를 사용해야 하며, 예시로 7777을 사용합니다.
틱 주기
네트워크 매니저의 틱 주기(TickRate)는 시뮬레이션 주기라고 부르기도 함. 틱 주기는 초당 실해할 틱 업데이트의 수를 결정함. 틱 업데이트는 네트워크 데이터를 동기화하거나 처리하는 주기
틱 주기가 짧을수록? -> 네크워크 사건들을 더 정확한 주기로 기록하고 동기화하므로 랙이나 패킷 손실에 의한 오차가 줄어들고 게임이 더 부드럽게 느껴짐. ++But++ 서버와 클라이언트의 부담이 커짐. 틱 주기가 과하게 높으면 틱이 손실되거나 처리가 지연될 확률이 높아져 게임이 불안정해질 수 있음.
틱 주기 설정 예시? -> 틱 주기는 게임의 장르와 서버의 성능, 대역폭 등을 고려하여 설정하는게 좋음. ex) 1:1 대전액션게임은 틱 주기가 초당 60 이상이면 Good, 반면 전략 게임은 초당 30이면 충분!
GameInitializer
Game Initializer는 게임이 시작될 때 필요한 초기 설정을 한 번에 실행하는 스크립트나 오브젝트입니다.
예를 들어 다음 작업을 담당할 수 있습니다.
즉, 게임 실행 시 필요한 준비 작업을 담당하는 초기화 담당자라고 보면 됩니다. Unity 기본 컴포넌트라기보다는 프로젝트에서 직접 만든 스크립트인 경우가 많습니다.

MenuScene

MenuManager 주요 코드
private void Awake()
{
/// NetworkConfig.ConnectionApproval -> 연결에 대해 승인 여부를 직접 설정할지를 결정
/// ConnectionApproval = true로 설정함으로써, 새로운 연결이 요청되었을 때, 이를 승낙할지 직접 결정하도록 설정
NetworkManager.Singleton.NetworkConfig.ConnectionApproval = true;
/// ConnectionApprovalCallback은 연결 승인 여부를 판단할 메서드를 할당할 수 있는 Action 타입의 이벤트
/// ApprovalCheck는 직접 구현한 메서드이며, 조건에 따라 연결을 승낙할지 결정
NetworkManager.Singleton.ConnectionApprovalCallback = ApprovalCheck;
// ※ 연결을 승낙하는 쪽은 서버/호스트 이므로 다른 클라이언트에서는 네트워크 매니저의 ConnectionApprovalCallback이 실행되지 않음.
}
/// <summary>
/// 클라이언트가 호스트에 연결을 시도했다가 연결이 끊어졌을 때 그 사유를 표시해줘야함.
/// 이를 위해서 클라이언트가 연결이 끊어졌음을 감지할 수 있는 이벤트가 필요함.
/// 네트워크 매니저의 OnClientDisconnectCallback 이벤트는 어떤 클라이언트의 연결이 끊어졌을 때 실행됨.
/// OnEnable()/OnDisable() - 네트워크 매니저의 OnClientDisconnectCallback에 OnClientDisconnectCallback를 할당. MenuManager가 비활성화된 상태에서는 실행되지 않도록 -= 연산자 실행
/// OnClientDisconnectCallback : 접속이 끊긴 이유를 UI에 호출해주는 직접 구현한 메서드
/// </summary>
private void OnEnable()
{
// 접속이 종료된 경우 호출되는 콜백을 등록
NetworkManager.Singleton.OnClientDisconnectCallback
+= OnClientDisconnectCallback;
}
private void OnDisable()
{
// 게임 종료시 네트워크 매니저가 먼저 파괴되는 경우에 대한 예외 처리
if (NetworkManager.Singleton != null)
{
// 접속이 종료된 경우 호출되는 콜백을 해제
NetworkManager.Singleton.OnClientDisconnectCallback
-= OnClientDisconnectCallback;
}
}
// 연결을 승인할 때 호출되는 콜백
// ConnectionApprovalRequest : 연결 요청 정보
// ConnectionApprovalResponse : 연결 승낙 여부 정보
// ConnectionApprovalResponse.Approved : 연결 승인 여부
// ConnectionApprovalResponse.CreatePlayerObject : 플레이어 오브젝트 생성 여부
// ConnectionApprovalResponse.Reason: (연결 실패) 이유
private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request,
NetworkManager.ConnectionApprovalResponse response)
{
// 총 플레이어 수가 2명 이상이면 연결을 거부
if (NetworkManager.Singleton.ConnectedClientsList.Count < 2)
{
response.Approved = true;
// 플레이어 오브젝트는 직접 생성할 것
response.CreatePlayerObject = false;
}
else
{
response.Approved = false;
response.Reason = "Max Player in session is 2";
}
}
// 호스트로 게임을 생성할 때 호출되는 메서드
// 해당 메서드는 로컬 클라이언트가 자신을 호스트(플레이어로서 참가하는 서버)로 하여 새로운 게임 세션을 생성
public void CreateGameAsHost()
{
// 네트워크 매니저 가져오기
var networkManager = NetworkManager.Singleton;
// 네트워크 트랜스포트 설정 가져오기
// NetworkManager에 설정된 네트워크 트랜스포트를 UnityTransport로 가져옵니다.
// 네트워크 트랜스포트: 데이터를 실제 인터넷으로 보내주는 통신 방식입니다.
// 여기서는 UnityTransport가 사용됩니다. NGO의 메시지를 UDP 같은 실제 네트워크 데이터로 변환합니다.
// NetworkConfig.NetworkTransport의 타입이 기본 네트워크 트랜스포트 타입으로 정의되어 있기 때문에 명시적 캐스팅을 해줌.
var transport = (UnityTransport)networkManager.NetworkConfig.NetworkTransport;
// 사용할 포트 번호 지정
// 호스트가 사용할 통신 포트 번호를 설정합니다.
// 통신 포트 번호: 컴퓨터 안에서 네트워크 프로그램을 찾기 위한 출입구 번호입니다.
// 예를 들어 7777 포트를 사용하면 클라이언트도 호스트의 IP 주소와 7777 포트로 접속합니다.
transport.ConnectionData.Port = DefaultPort;
// 호스트로 게임을 시작
if (networkManager.StartHost()) // 호스트 모드 시작
{
// 게임에 참가하는 모든 플레이어가 로비 씬을 로드하도록 설정
// 유니티 기본 빌트인 SceneManager와 다른, NetworkManager.Singleton.SceneManager를 사용하여,
// 클라이언트 사이에서 로드할 씬을 동기화
networkManager.SceneManager.LoadScene("Lobby", LoadSceneMode.Single);
}
else
{
// 호스트 시작에 실패한 경우
infoText.text = "Host failed to start";
Debug.LogError("Host failed to start");
}
}
// 클라이언트로 게임에 참여할 때 호출되는 메서드
// 클라이언트가 '게임 참가' 버튼을 눌렀을 때 호출되는 함수
public void JoinGameAsClient()
{
var networkManager = NetworkManager.Singleton;
var transport = (UnityTransport)networkManager.NetworkConfig.NetworkTransport;
// 호스트 주소를 설정
// 연결할 호스트의 주소와 포트 번호를 트랜스포트에 설정
transport.SetConnectionData(hostAddressInputField.text, DefaultPort);
// 클라이언트로 게임에 참여
if (!NetworkManager.Singleton.StartClient())
// StartClient() 메서드는 성공적으로 호스트에 연결되면 true를 반환
{
// 클라이언트 시작에 실패한 경우
infoText.text = "Client failed to start";
Debug.LogError("Client failed to start");
}
}
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다

게임 광고 수익은 단순히 광고를 붙이는 것이 아니라, 여러 광고 네트워크를 경쟁시켜 가장 높은 수익을 만드는 구조입니다.

안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
XR을 활용한 게임 개발 3기(유니티) 수강생입니다. 곧 수료 하지만 앞으로 이곳에 가끔 저의 개발 경험이 나 지식 기록할까 합니다. 더 나아가 이 사이트가 제 개인위키의 역할을 할 수 있으면 좋겠습니다. 한국 게임 시장을 흔들겠습니다



게임 광고 수익은 단순히 광고를 붙이는 것이 아니라, 여러 광고 네트워크를 경쟁시켜 가장 높은 수익을 만드는 구조입니다.


안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.