Karts
개요
Fusion Kart 샘플은 플레이어가 룸 식별자로 이름을 사용하여 룸을 만들고 가입할 수 있는 서버 권한, 클라이언트 예측 모델을 사용하여 레이싱 게임을 만드는 방법에 대한 접근 방식을 보여줍니다.
시작하기 전에
샘플을 실행하려면 먼저 PhotonEngine 관리 화면에서 Fusion AppId를 생성하고 Real Time 설정 (Fusion 메뉴에서 접근 가능)의 App Id Fusion
에 붙여 넣습니다. Photon 앱 설정 에셋은 Fusion 메뉴 Fusion > Realtime Settings
에서 찾을 수 있습니다.
다운로드
버전 | 릴리즈 일자 | 다운로드 | |
---|---|---|---|
2.0.1 | Jul 23, 2024 | Fusion Karts 2.0.1 Build 605 |
하이라이트
이 프로젝트에는 완전한 게임 루프가 있어 최대 8명의 사용자가 서로 참여하여 누가 이길지 경쟁적으로 레이싱을 펼칠 수 있을 뿐만 아니라 무한 랩이 있는 트랙에서 타이머 없이 함께 연습할 수 있습니다. 주요 특징은 다음과 같습니다:
- 두 가지 모드(레이싱 및 연습)
- 두 가이의 레이싱 트랙
- 다양한 통계를 사용하는 차트
- 부스트/바나나 장애물, 코인과 같은 공유 항목
- 확장 가능한 스크립트 가능 객체 기반 아이템 시스템
- 클라이언트가 가입할 수 있도록 코드를 사용하여 룸을 호스트로 설정하고 "룸을 찾을 수 없음", "룸이 가득 찼음", "룸이 현재 세션 중" 등의 에지 케이스를 처리합니다.
폴더 구조
메인 스크립트 폴더 /Scripts
에는 Networking
및 Fusion Helpers
를 포함한 하위 폴더가 있으며, 다른 하위 폴더에는 게임 플레이를 관리하는 다양한 인터페이스 및 관리자 컴포넌트 등이 포함되어 있습니다.
게임 런처
GameLauncher.cs
클래스는 플레이 모드 메뉴에서 어떤 옵션을 선택하느냐에 따라 사용자를 Host
또는 Client
설정하는 역할을 합니다. 이 클래스는 UI를 참조하는 것으로, 플레이어의 스폰, 플레이어의 스폰 해제, 셧다운 등을 관리하는 역할을 합니다.
최초 실행
샘플을 처음 시작할 때 사용자는 (원하는 경우) 닉네임을 입력하고 지역을 선택하라는 메시지를 받게 됩니다. 이 화면은 언제든지 옵션 메뉴에서 접근할 수 있습니다. 제공되는 닉네임은 다음 세 가지 장소에서 사용됩니다:
- 사용자가 룸을 만들거나 룸에 가입할 때 UI 아이템은 제공된 닉네임으로 인스턴스화됩니다.
- 닉네임은 세계 공간 캔버스에서 레이싱하는 동안 각 카트 위에 인스턴스화됩니다.
- 레이싱 종료 시 결과 화면에서 닉네임을 사용하여 1위, 2위, 3위 등을 표시합니다.
룸
Fusion Karts 샘플은 Photon Cloud 세션 위에 추상화된 룸을 사용합니다. 이 샘플의 경우 최대 8명의 사용자가 한 번에 룸에 연결할 수 있습니다. 최댓값은 선택적으로 1에서 8 사이로 설정할 수 있습니다.
룸 생성하기
CreateGameUI
스크립트는 Canvas 계층의 Create Room Screen
아래에 다양한 UI 요소에 대한 참조를 저장합니다. Room Code
의 입력 필드는 이 룸의 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
Network Behavior의 PlayerChanged
이벤트를 구독하고 있으며, 이 플레이어의 IsReady
네트워크 속성은 Fusion의 Networked
속성을 통해 제공되는 OnChanged
콜백을 통해 호출됩니다. 이 함수를 호출하면 각 RoomPlayer
의 IsReady
부울이 true로 설정되어 있는지 확인한 후 선택한 트랙의 해당 인덱스에 대해 sceneIndex
파라미터를 사용하여 LevelManager.LoadTrack
을 호출합니다. 이 메소드는 Fusion 활성 씬을 설정하고 등록된 씬 개체 공급자를 호출합니다.
입력 처리
이 샘플은 새로운 입력 시스템을 사용하고, 키보드와 게임패드 제어를 위한 지원을 처리하기 위해 InputAction
클래스를 활용합니다. 다양한 컨트롤러를 쉽게 지원하기 위한 새로운 입력 시스템입니다. 햅틱 피드백을 포함하여 키보드와 조이스틱 지원이 기본으로 제공됩니다.
키보드
- A 및 D 또는 좌우 화살표 키로 좌우 측 이동
- W 또는 위 화살표 키로 가속
- S 또는 아래 화살표로 반대로 이동
- Alt키로 뒤돌아보기
- 스페이스 키로 홉/드리프트
- 시프트 키로 경적/아이템 사용
게임 패드
- 좌측 아날로그 스틱으로 운전
- 아래 버튼으로 가속
- 왼쪽 버튼으로 반대 이동
- D패드로 뒤돌아보기
- 우측 범퍼로 홉/드리프트
- 좌측 범퍼로 경적/아이템 상요
(컨트롤러 럼블 지원)
Karts
Karts는 모두 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
스크립트 가능 객체와 추상적인 SpawnedPowerup
클래스 두 가지입니다.
SpawnedPowerup
은 ICollidable
를 상속받아 ICollidable.Collide
를 가상으로 구현함으로써 파생 클래스에 대한 선택적 구현입니다. Powerup.Use
메소드에 의해 생성된 후 즉시 호출되는 선택적 초기화를 위한 가상 Init
메소드도 제공됩니다.
- 바나나: 바나나는 물리적인 존재로서 카트 뒤에 떨어져 플레이어들에게 위험 요소로 작용합니다.
BananaPowerup
은SpawnedPowerup.Collide
를 오버라이드 하여 카트를 쉽게 회전시킬 수 있습니다. - 부스트: 레벨 2의 즉각적인 부스트를 제공합니다. 부스트 파워업은 바나나와 같이 물리적인 표현이 없으며, 부스트가 제공된 후 즉시 스폰 해제됩니다.