카트
개요
Fusion 카트 샘플은 Server 권한 클라이언트 예측 모델을 사용하여 레이싱 게임을 만드는 방법을 보여줍니다. 여기서 플레이어는 이름을 룸 식별자로 사용하여 룸을 만들고 조인할 수 있습니다.
시작하기 전에
샘플을 실행하려면 먼저 PhotonEngine 관리 화면에서 Fusion AppId를 생성한 후 실시간 설정(Fusion 메뉴에서 연결 가능)의 App Id Fusion
필드에 붙여 넣으십시오. Photon App 설정 에셋은 Fusion 메뉴 Fusion > Realtime Settings
에서 선택할 수 있습니다.
다운로드
버전 | 릴리즈 일자 | 다운로드 | ||
---|---|---|---|---|
1.1.7 | Jun 21, 2023 | Fusion Karts 1.1.7 Build 198 |
주요 특징
이 프로젝트에는 완전한 게임 루프가 있어 최대 8명의 사용자가 서로 협력하여 누가 이길지 경쟁할 수 있을 뿐만 아니라 무한 랩 트랙에서 타이머 없이 함께 연습할 수 있습니다. 주요 기능은 다음과 같습니다.
- 두 가지 모드(레이스 및 연습)
- 두 개의 레이싱 트랙
- 다양한 통계를 가진 카트입니다.
- 부스트/바나나 장애물, 코인과 같은 공유 아이템
- 확장 가능한 스크립트 가능 객체 기반 항목 시스템
- 클라이언트가 가입할 코드를 사용하여 방을 호스트로 설정하면 "room not found", "room full", "room is current in session" 등의 Edge-case가 처리됩니다.
폴더 구조
메인 스크립트 폴더 /Scripts
에는 Networking
및 Fusion Helpers
를 포함한 하위 폴더가 있으며, 다른 하위 폴더에는 게임을 제어하는 다양한 인터페이스와 관리자 컴포넌트 등이 있습니다.
게임 런처
GameLauncher.cs
클래스는 플레이 모드 메뉴에서 선택하는 옵션에 따라 사용자를 호스트 또는 클라이언트로 설정하는 역할을 합니다. 이는 UI에 대한 참조를 제공하며 플레이어의 스폰, 플레이어의 스폰 해제 및 종료와 같은 작업을 관리합니다.
최초 실행
샘플을 처음 시작할 때 사용자에게 닉네임을 제공하고(원하는 경우) 지역을 선택하라는 메시지가 표시됩니다. 이 화면은 옵션 메뉴에서 언제든지 접근할 수 있습니다. 제공된 닉네임은 다음 세 곳에서 사용됩니다.
- 사용자가 룸을 만들거나 룸에 가입하면 UI 항목이 제공된 닉네임으로 인스턴스화됩니다.
- 이 닉네임은 레이싱 중에 세계 공간의 캔버스에서 각 카트 위에 인스턴스화됩니다.
- 레이스 종료 시 결과 화면에서는 1, 2, 3등을 나타내는 닉네임을 사용합니다.
룸
Fusion 카트 샘플은 Photon Cloud 세션 위에 추상화된 룸을 사용합니다. 이 샘플의 경우 한 번에 최대 8명의 사용자가 룸에 연결할 수 있습니다. 선택적으로 1과 8 사이로 설정할 수 있습니다.
룸 생성하기
CreateGameUI
스크립트는 캔버스 계층에 있는 Create Room Screen
아래에 다양한 UI 요소에 대한 참조를 저장합니다. Room Code
의 Input 필드는 이 룸의 ID를 설정합니다. 사용자가 로비에 참여하려고 하면 유사한 입력 필드가 표시되고 인식된 코드를 제시해야 합니다. 플레이어 수 슬라이더를 사용하여 호스트는CreateGameUI
스크립트 내의 ServerInfo.MaxUsers
를 설정하여 룸의 사용자 수를 클램프 할 수 있습니다. 샘플에는 두 개의 다른 게임 모드와 두 개의 다른 트랙이 포함되어 있으며, 룸을 만드는 동안 ServerInfo.cs
에서 적절한 정숫값을 설정하는 다음 방법을 통해 선택할 수 있습니다:
C#
public void SetGameType(int gameType)
{
ServerInfo.GameMode = gameType;
}
public void SetTrack(int trackId)
{
ServerInfo.TrackId = trackId;
trackImage.sprite = ResourceManager.Instance.tracks[trackId].trackIcon;
}
룸에 참여하기
룸에 참여하려면 사용자가 룸 코드를 제공해야 합니다. 사용자가 존재하지 않는 룸에 참여하려고 하면 해당 룸을 표시하라는 UI 메시지가 나타납니다. 사용자는 현재 세션에 있는 룸에 참석할 수 없으며, 연결하려는 룸과 동일한 지역에 있어야 합니다. JoinGameUI
스크립트는 입력 필드에 대한 참조를 보유하여 필요한 코드를 제공합니다. 입력 필드에 입력된 텍스트가 없을 경우 코드가 없는 룸을 만들 수 없으므로 확인 버튼을 대화 불가능으로 합니다.
C#
private void SetLobbyName(string lobby)
{
ClientInfo.LobbyName = lobby;
confirmButton.interactable = !string.IsNullOrEmpty(lobby);
}
준비
각 사용자의 준비 상태는 플레이어 목록의 닉네임 옆에 표시되고 사용자는 녹색 확인 표시로 표시됩니다. 모든 선수들은 레이스가 시작되기 전에 먼저 준비를 해야 합니다. LobbyUI.cs
의 EnsureAllPlayersReady
함수는 각 RoomPlayer
NetworkBehaviour의 PlayerChanged
이벤트를 구독하고 있으며, IsReady
는 Fusion의 Networked 속성을 통해 제공되는 OnChanged
콜백을 통해 네트워크 속성을 호출합니다. 호출되면 함수는 각 RoomPlayer
의 IsReady
부울이 true로 설정되어 있는지 확인한 다음 LevelManager.LoadTrack
을 sceneIndex
파라미터가 선택한 트랙에 해당하는 인덱스로 설정되어 호출합니다. 이 메서드는 Fusions 활성 씬을 설정하여 등록된 씬 객체 공급자를 호출합니다.
입력 처리
이 샘플은 새로운 입력 시스템을 사용하며 InputAction
클래스를 활용하여 키보드와 게임패드 컨트롤을 모두 지원합니다. 다양한 컨트롤러를 쉽게 지원할 수 있는 새로운 입력 시스템입니다. 촉각 피드백을 포함하여 키보드와 조이스틱을 바로 사용할 수 있습니다.
키보드
- A 및 D 또는 왼쪽 및 오른쪽 화살표 키를 조작
- 가속하려면 W 또는 위쪽 화살표 키를 누르십시오.
- S 또는 아래쪽 화살표 키를 반전시킵니다.
- Alt는 뒤를 살펴봅니다.
- 홉/드리프트 할 공간입니다.
- 경음기/항목을 사용하도록 전환합니다.
게임 패드
- 왼쪽 아날로그 스틱 조정
- 가속하려면 South 버튼
- East 버튼 후진
- D-Pad를 아래로 내려서 뒤돌아보기
- 우측 범퍼가 홉/드리프트에 연결
- 좌측 범퍼는 경음기/아이템 사용
(컨트롤러 럼블을 지원)
카트
카트는 KartComponent
에서 파생된 많은 개별 부품으로 구성되어 있으며, KartEntity
는 이들 사이의 허브 역할을 하며 주변 환경을 제공합니다. 컴포넌트는 다음과 같습니다.
KartAnimator
-Animator
컴포넌트, 파티클 시스템 및 추적과 같은 시각적 요소, 애니메이션 및 효과 재생 방법에 대한 참조.KartAudio
- 카트의 각 영구 오디오 소스에 대한 참조이며 엔진 피치와 볼륨을 담당하고 드리프트 오디오를 재생KartCamera
- 카메라 원근법, 시야 및 속도선 파티클 시스템 제어KartController
- 가속, 스티어링, 표류 및 부스트, 휠 회전 및 도로 방향 설정 등 대부분의 로직과 네트워킹이 여기에서 이루어집니다.KartInput
- 로컬에서 입력을 폴링하고InputAction
활성화/비활성화 및 콜백 처리KartLapController
- 카트의 현재 랩 및 체크포인트 처리KartItemController
- 항목 사용 버튼을 누를 때의 동작 처리
KartEntity
는 GameUI
HUD 인터페이스에 대한 참조를 가지고 있으며 컴포넌트 구조체의 일부가 아니라 카트의 상태를 플레이어에게 외부적으로 반영하는 방법을 제공합니다.
픽업
픽업은 이 샘플에서 카트가 상호 작용할 수 있는 느슨하게 정의된 엔티티 집합에 레이블을 지정하는 데 사용되는 용어입니다. 모든 픽업은 ICollidable
인터페이스를 구현하며, 특정 동작은 ICollidable.Collide
구현에 의해 결정됩니다. KartEntity
는 OnTriggerStay
메소드로 수행되며 KartEntity
인스턴스에 대한 참조가 전달되는 상호 작용을 시작합니다. OnTriggerStay
가 사용되는 이유는 네트워크 컨텍스트에서 OnTriggerEnter
함수의 특성을 신뢰할 수 없기 때문입니다.
- 코인: 코인은 게임 플레이의 관점에서 기능적인 목적을 제공하지 않지만, 한 명의 플레이어가 수집할 수 있는 기본적 실체를 보여주고, 스폰 해제된 후 UI에 표시되는 카운터에 추가하는 기능을 가지고 있습니다.
- 아이템 상자: 아이템 상자는 그 자체가 픽업이 아닌 동시에 동작을 용이하게 하기 위해
ICollidable
을 구현합니다. 아이템 박스는KartEntity.SetHeldItem
메소드를 통해 카트에 파워업을 할당합니다.
파워업
파워업은 아이템 박스에서 얻을 수 있는 특별한 종류의 픽업이며 플레이어의 재량에 따라 수집 후 임의의 시간에 사용할 수 있습니다.
파워업을 구성하는 두 가지 컴포넌트는 Powerup
ScriptableObject와 추상 SpawnedPowerup
클래스입니다.
SpawnedPowerup
은 ICollidable
에서 상속받고 ICollidable.Collide
를 구현하므로 상속한 클래스에 대해 선택적인 구현이 되도록 합니다. Powerup.Use
메소드에 의해 생성된 후 즉시 호출되는 선택적 초기화를 위한 가상 Init
메서드도 제공됩니다.
- 바나나: 바나나를 사용하면 카트 뒤에 떨어뜨려 플레이어에게 위험 요소로 작용합니다.
BananaPowerup
은 카트 위를 달리는 카트를 쉽게 회전시키기 위해SpawnedPowerup.Collide
보다 우선합니다. - 부스트: 순간적으로 레벨 2 상승효과를 부여합니다. 부스트 파워업은 바나나처럼 물리적으로 표현되지 않으며 부스트가 주어진 후 즉시 소멸됩니다.