This document is about: FUSION 2
SWITCH TO

Fusion Golf

Level 4

개요

Fusion Golf 샘플은 물리에 중점을 둔 아케이드 골프 레이싱 게임을 만드는 접근 방식을 보여줍니다. 이 샘플은 서버 권한, 클라이언트 예측 모델을 사용하여 세션 브라우저와 룸 코드를 통한 직접 연결 기능을 갖추고 있습니다. 호스트는 홀당 최대 시간, 최대 샷 수, 플레이어 간 충돌 여부, 세션 브라우저에서의 세션 가시성 등 다양한 게임 설정을 수정할 수 있습니다. 샘플에는 대포, 회전기, 부스트 터널 및 엘리베이터 플랫폼과 같은 물리 기반 객체가 포함된 18홀 코스가 있습니다. Fusion Golf는 원래 Fusion 1.0을 사용하여 제작되었으나, 현재는 Fusion 2.0으로 포팅 되었으며, Fusion 1.0 버전의 대부분의 기능을 유지하고 있습니다.

시작하기 전에

샘플을 실행하려면 먼저 PhotonEngine 관리 화면에서 Fusion AppId를 생성하고, 이를 Real Time 설정의 App Id Fusion 필드에 붙여 넣으세요(Fusion 메뉴에서 접근 가능). 그런 다음 Scenes 폴더에서 Menu 씬을 로드하고 Play를 누르세요.

다운로드

버전 릴리즈 일자 다운로드
2.0.1 May 27, 2024 Fusion Golf 2.0.1 Build 557

주요 기능

  • 전체 네트워크 게임 상태 시스템 (프리 게임, 인트로, 플레이, 아웃트로, 포스트 게임)
  • 다른 플레이어 관전
  • 사용자 정의 가능한 게임 설정 (충돌, 홀 수, 최대 샷 수, 최대 시간)
  • 세계의 객체 상태 동기화
  • 로비 브라우저 (및 룸을 비공개로 설정할 수 있는 기능)
  • 물리 중심 객체 (캐논, 스피너, 엘리베이터 플랫폼, 부스트 터널)
  • 사용자 정의 가능한 플레이어 비주얼 (RGB 슬라이더)
  • 지역 설정, 닉네임 설정, 그래픽 옵션

프로젝트

폴더 구조

주요 스크립트 폴더 /Scripts에는 Fusion과 인터페이스 하는 것이 주요 기능인 스크립트가 들어있는 Networking 하위 폴더가 있습니다. 주요 스크립트:

플레이어 레지스트리

플레이어 레지스트리는 룸의 각 플레이어에 대한 참조를 저장하며, 플레이어의 수를 세고, 선택하고, 하나 또는 여러 플레이어에 대해 작업을 수행하는 유틸리티 메소드를 제공합니다. 유틸리티 함수의 기본 동작은 관전자 플레이어를 무시하는 것이지만, includeSpectators 매개 변수가 true이면 전체 플레이어 컬렉션에 대해 작동합니다.

관전자

관전자는 게임에 참여하는 대신 시청을 선택한 플레이어입니다. 관전자의 PlayerObject에는 절대 Controller가 할당되지 않습니다.

GameState

게임 로직의 흐름과 동작은 GameState NetworkBehaviour에 의해 제어됩니다. GameState는 게임의 단계를 나타내는 열거형을 정의하며, 네트워크 된 StateMachine 속성이 이를 상태로 사용합니다. StateMachine<T>onEnter, onExit, onUpdate의 3가지 필드를 가진 StateHooks 클래스를 정의합니다. StateMachine 클래스를 사용할 때 각 열거형 상태는 상태에 들어갈 때, 나올 때 및 상태에 적극적으로 머무는 동안 발생하는 작업을 정의하는 StateHooks를 가질 수 있습니다.

게임에 들어가기

사용자는 세션 브라우저를 사용하거나 세션 코드를 통해 직접 세션을 호스팅 하거나 참여할 수 있습니다. 사용자가 호스트를 선택한 경우 세션 코드를 입력하는 것은 선택 사항이며, 비워두면 자동으로 생성됩니다. 세션에 들어가면 화면 상단에 코드가 표시됩니다.

세션 코드는 runner.SessionInfo.Name을 통해 접근할 수 있습니다.

지역 선택

호스트 또는 참여를 선택하기 전에 사용자는 Photon Cloud 지역을 선택할 수 있는 드롭 다운을 보게 됩니다. 드롭 다운 옵션은 지역 문서에 따라 선택되었습니다.

매치메이커

호스팅, 참여 및 세션 브라우저는 모두 Matchmaker 클래스에서 처리됩니다. 이는 NetworkRunner.StartGame 메서드의 래퍼 역할을 하며, 연결 오류가 발생할 경우 오류를 DisconnectUI로 전달하여 사용자에게 표시됩니다.

입력 처리

입력은 PlayerInputBehaviour.cs에 의해 폴링 되어 사용자 정의 INetworkInput 구조체 PlayerInput에 저장됩니다. 이 샘플에서 입력은 클릭 및 마우스 이동으로만 구성됩니다. PlayerInput은 상대적으로 단순하며 3개의 필드만 포함합니다:

  • isDragging - 플레이어가 마우스 버튼을 누르고 있는지 여부
  • dragDelta - 플레이어의 마우스가 아래로 얼마나 드래그 되었는지
  • yaw - 플레이어가 향하고 있는 각도 이 데이터는 Putter 플레이어 스크립트에 의해 처리되며, 로컬 플레이어와 관전자 모두 적절한 UI를 볼 수 있게 합니다.

플레이어

플레이어는 두 부분으로 처리됩니다:

  • PlayerObject - 이 객체가 연결된 PlayerRef 값, 플레이어의 컨트롤러(Putter)에 대한 참조, 방 내 인덱스, 닉네임, 선택한 색상 및 점수와 관련된 게임 플레이 데이터를 포함합니다.
  • Putter - 물리학 및 UI에 대한 입력에 응답하는 역할을 합니다.

마이그레이션 노트

앞서 언급했듯이, Fusion Golf는 Fusion 1.0에서 Fusion 2.0으로 포팅 되었습니다. Fusion 1.0에서 Fusion 2.0으로의 마이그레이션에 대한 자세한 내용은 여기에서 확인할 수 있습니다. 포팅 과정에서 이루어진 몇 가지 변경 사항은 다음과 같습니다.

  • 물리: Fusion 2.0은 물리 애드온을 별도로 사용합니다. 가져온 후 게임에서 사용하는 NetworkRunner는 이제 RunnerSimulatePhysics3D 컴포넌트를 필요로 합니다. 이 게임은 물리학 시뮬레이션에 크게 의존하므로, 이 컴포넌트의 Client Physics Simulation 속성을 "Simulate Always"로 설정해야 합니다:
runner simulate physics 3d 설정.
이 샘플의 대부분의 NetworkRigidbody3D 컴포넌트 설정.
  • 스크립트 및 프로토타입: Fusion 1.0에 존재하는 폴더 Assets/Fusion/Scripts에는 PlayerSpawnerPrototype과 같은 프로토타이핑 도구가 포함되어 있습니다. 그러나 Fusion 2.0에서는 더 이상 존재하지 않습니다. 이 디렉터리의 많은 스크립트는 업그레이드할 수 있지만, 많은 스크립트가 중복되거나 과도하게 복잡하거나 불필요하여 이 샘플에서 제거되었습니다. 새로 생성해야 했던 유일한 클래스는 PlayerSpawner로, 플레이어가 참여할 때 NetworkObject를 생성하고 떠날 때 제거하는 NetworkRunner 프리팹에 연결된 SimulationBehaviour입니다:

C#

public class PlayerSpawner : SimulationBehaviour, IPlayerJoined, IPlayerLeft
{
    public NetworkObject playerObject;

    public void PlayerJoined(PlayerRef player)
    {
        // 클라이언트 서버 토폴로지에서는 서버만 플레이어를 생성할 수 있습니다.
        if (Runner.Topology == Topologies.ClientServer)
        {
            if (Runner.CanSpawn)
            {
                Runner.Spawn(playerObject, inputAuthority: player);
            }
        }
        // 공유 토폴로지에서는 모든 플레이어가 생성할 수 있지만, 로컬 플레이어만 자신의 플레이어를 생성하기를 원합니다.
        else if (Runner.LocalPlayer == player)
        {
            Runner.Spawn(playerObject, inputAuthority: player);
        }
    }

    public void PlayerLeft(PlayerRef player)
    {
        bool canDespawn = (Runner.Topology == Topologies.ClientServer && Runner.IsServer) || 
            (Runner.Topology == Topologies.Shared && Runner.IsSharedModeMasterClient);

        if (canDespawn)
        {
            PlayerObject leavingPlayer = PlayerRegistry.GetPlayer(player);
            Runner.Despawn(leavingPlayer.Object);
        }
    }
}
  • FixedUpdateNetwork: Fusion 2.0에서 FixedUpdateNetwork는 프록시에서 실행되지 않습니다. 이는 포팅 시 일부 이상한 동작을 유발할 수 있습니다. 예를 들어, 이 샘플에서 GameState는 호스트에서만 상태 전환을 실행하는 문제가 있었습니다. 다음 줄은 Spawned 메서드의 끝 근처에 추가되었습니다:

C#

...
// 모든 프록시에 대해 FixedUpdateNetwork가 호출되도록 합니다.
Runner.SetIsSimulated(Object, true);
...
  • 스폰 하기: Fusion 1.0에서는 Runner.Spawn을 호출하려고 하지만 ClientServer 토폴로지를 사용하는 게임의 클라이언트와 같이 권한이 없는 경우 생성이 조용히 실패합니다. Fusion 2.0에서는 클라이언트가 객체를 생성할 수 없는 경우 객체를 생성하려고 하면 예외가 발생하여 다양한 문제가 발생할 수 있습니다. 이 샘플에서는 오류를 방지하기 위해 Runner.Spawn을 호출하기 전에 Runner.CanSpawn을 사용하여 확인합니다.

타사 에셋

Golf 샘플에는 각 제작자가 제공한 여러 에셋이 포함되어 있습니다. 전체 패키지는 각 사이트에서 직접 프로젝트에 사용할 수 있습니다:

중요: 상업 프로젝트에 사용하려면 각 제작자로부터 라이선스를 구매해야 합니다.

Back to top