This document is about: QUANTUM 2
SWITCH TO

Quantum 103 - 플레이어 캐릭터

개요

Quantum 103은 캐릭터 컨트롤러를 사용하여 움직이는 캐릭터를 소개합니다. 또한 Quantum에서 게임플레이 코드를 작성하는 방법에 대한 지침도 제공합니다.

캐릭터 엔티티 설정

게임 씬 (Quantum > 3d > Character Controller Entity)에서 새로운 캐릭터 컨트롤러 엔티티를 생성합니다. PlayerCharacter로 이름을 부여하고 객체의 트랜스폼을 (2, 2, 0)으로 설정합니다.

이 엔티티는 PhysicsCollider3D를 사용할 수 있는 엔티티이며 CharacterController3D 컴포넌트가 EntityPrototype MonoBehaviour에 추가되어 있습니다.

  • CharacterController3D는 캐릭터의 움직임을 제어합니다. 구성 필드는 캐릭터 컨트롤러의 동작을 조정하기 위한 구성을 제공합니다. 기본 구성은 Resources/DB/Configs에서 확인할 수 있습니다. 이 튜토리얼에서는 기본 구성이 사용됩니다.
  • 유니티 CharacterController와 달리 Quantum의 캐릭터 컨트롤러는 콜라이더 역할을 하지 않습니다. PhysicsCollider3D 컴포넌트는 엔티티의 콜라이더 역할을 하며 시각적 영역의 크기와 일치합니다.
PlayerCharacter 인스펙터

종종 단일 엔티티가 아닌 컴포넌트 데이터와 달리 엔티티 간에 공유되는 데이터에 대한 접근 권한을 엔티티에 부여해야 합니다. Quantum에서 이 작업은 에셋 구성 파일을 통해 수행됩니다. 구성 파일은 코드로 만들거나 유니티의 ScriptableObjects에 정의할 수 있습니다. 캐릭터 컨트롤러에는 캐릭터 컨트롤러가 이동하고 상호 작용하는 방식에 대한 정보를 저장하는 구성 파일이 있습니다.

플레이 모드를 누릅니다. 보시는 바와 같이 실체는 아직 움직이지 않으며 중력의 영향을 받지 않습니다. 캐릭터 컨트롤러를 작동시키려면 코드 구현이 필요합니다.

Quantum 코드 프로젝트에서 열기

Quantum의 게임플레이는 quantum_code c# 프로젝트에서 작성되었습니다. 프로젝트를 열려면 Visual Studio 또는 Rider의 새 인스턴스를 엽니다.

  • Visual Studio에서 Open a project or solution를 선택합니다.
  • Rider에서 Open을 선택합니다.
    quantum_code 폴더에서 .sln 파일을 찾아 선택합니다.

Visual Studio를 사용할 때 .NET 프레임워크 버전을 업그레이드하라는 팝업이 나타날 수 있습니다. 권장 버전을 다운로드하려면 이 항목을 선택합니다.

Prompt to update .NET Framework
목표 팩 다운로드.

Rider를 사용할 때. 용액을 연 후 ctrl + shift + b를 누릅니다. 오류 메시지가 표시된 창이 나타나면 지침에 따라 Microsoft의 NET Framework 목표 팩을 다운로드합니다..

이제 게임플레이 코드 작성을 시작할 준비가 되었습니다.

Gameplay 코드

솔루션 탐색기에서 quantum_code 프로젝트 파일을 마우스 오른쪽 버튼으로 클릭하고 Add > New Directory를 선택합니다. 디렉터리 이름을 Platformer로 지정합니다.

Add a new directory
새로운 디렉토리 추가.

이제 새로 만든 Platformer 폴더를 마우스 오른쪽 단추로 클릭합니다. Add > Class를 선택합니다. 그리고 팝업에서 Class를 다시 선택하고 이름을 MoventCharacterSystem.cs으로 설정한 다음 Add 버튼을 클릭합니다.

Add a the MovementSystem
MovementSystem.cs 추가.

다음 텍스트가 포함된 클래스 파일이 생성되었습니다:

C#

namespace Quantum.Platformer
{
    class MovementSystem
    {
    }
}

ECS에서 게임플레이 코드를 작성하는 가장 일반적인 패턴은 컴포넌트 목록을 포함하는 엔티티 모음에 시스템을 반복하는 것입니다. Quantum ECS를 사용하면 시스템 메인 스레드 필터를 사용하여 이를 달성할 수 있습니다.

먼저 MovementSystem 클래스에 필터 구조를 추가합니다:

C#

public struct Filter
{
    public EntityRef Entity;
    public CharacterController3D* CharacterController;
}

각 필터에는 항상 EntityRef 필드와 필터링할 컴포넌트 포인터 필드가 포함되어야 합니다. 필터의 컴포넌트 유형에는 항상 포인터를 사용합니다.

publicunsafe 키워드를 클래스에 추가하고 SystemMainThreadFilter<MovementSystem.Filter> 클래스에서 상속받습니다:

C#

public unsafe class MovementSystem : SystemMainThreadFilter<MovementSystem.Filter>

다음 코드를 사용하여 추상 Update' 함수의 재정의를 추가합니다:

C#

public override void Update(Frame f, ref Filter filter)
{
    // note: pointer property access via -> instead of .
    filter.CharacterController->Move(f, filter.Entity, default);
}

업데이트 함수는 필터에 모든 컴포넌트가 있는 각 엔티티에 대해 각 프레임에서 한 번 실행됩니다. 프레임 매개 변수는 시스템이 실행되는 현재 프레임을 나타내며 특정 프레임에 대한 전체 게임 상태에 대한 접근을 제공합니다.

이 코드는 단순히 캐릭터 컨트롤러의 이동 함수를 호출하고 기본 제로 벡터를 전달합니다. 이것은 캐릭터 컨트롤러가 어떤 방향으로도 움직이려고 하지 않지만 엔티티는 중력의 영향을 받는다는 것을 의미합니다.

그러나 이 코드는 아직 실행되지 않습니다. 시스템을 실행하려면 SystemSetup.cs 파일에 등록해야 합니다. 파일을 열고 다음을 using 선언에 추가합니다.

C#

using Quantum.Platformer;

그런 다음 user systems go here 주석 아래에 다음 행을 추가합니다.

C#

// user systems go here 
new MovementSystem(),

마지막으로 Core.CullingSystem2D, Core.PhysicsSystem2D 그리고
Core.NavigationSystem를 추가한 행을 주석 처리합니다. 이 시리즈에서 만들어진 게임은 그것들을 사용하지 않습니다.

SystemSetup 파일은 다음과 같습니다:

C#

using Photon.Deterministic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quantum.Platformer;

namespace Quantum {
  public static class SystemSetup {
    public static SystemBase[] CreateSystems(RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
            return new SystemBase[] {
        // pre-defined core systems
        // new Core.CullingSystem2D(),
        new Core.CullingSystem3D(),

        // new Core.PhysicsSystem2D(),
        new Core.PhysicsSystem3D(),

        Core.DebugCommand.CreateSystem(),

        // new Core.NavigationSystem(),
        new Core.EntityPrototypeSystem(),
        new Core.PlayerConnectedSystem(),

        // user systems go here 
        new MovementSystem(),
      };
    }
  }
}

SystemSetup의 시스템은 나열된 순서대로 실행됩니다.

이동 구현을 완료하기 위한 마지막 단계가 남아 있습니다. quantum_code 프로젝트는 별도의 프로젝트이기 때문에 빌드해야 합니다. 빌드(ctrl + shift + b)를 누릅니다.

중요: quantum_code 프로젝트를 변경할 때마다 유니티 프로젝트에서 변경 사항이 작동하려면 나중에 빌드해야 합니다.

유니티 편집기로 돌아가 플레이 모드로 들어갑니다. 캐릭터 스피어는 현재 KCC 중력의 영향을 받지만 키보드 입력에는 아직 반응하지 않습니다.

입력

Platformer 폴더를 마우스 오른쪽으로 클릭합니다. Add > New Item을 선택합니다. 새 창이 나타나면 Visual C# Items > General > Text File을 선택하고 Input.qtn으로 파일 이름을 지정한 후 Add 버튼을 클릭합니다.

Add the text file
텍스트 파일을 선택하고 Input.qtn으로 이름 지정.

Qtn 파일은 DSL(Quantum Domain Specific Language)을 사용하는 Quantum 관련 파일입니다. DSL의 구문은 C#과 유사합니다. DSL은 엔티티 컴포넌트 데이터 및 입력 데이터를 정의하는 데 사용됩니다. 게임플레이 시스템은 C#에 있습니다.

Input.qtn 파일에 다음을 추가합니다:

C#

input
{
    button Jump;
    FPVector2 Direction;
}

입력은 Quantum에서 특수한 키워드입니다. Quantum은 입력 동기화를 사용하므로 게임 상태가 아닌 입력만 네트워크를 통해 전송됩니다. 여기서 정의된 input은 네트워크를 통해 전송되어 게임플레이 시뮬레이션을 위한 입력으로 사용될 데이터입니다.

노트: 입력은 틱마다 전송되며 자주 변경되고 실시간 게임플레이에 영향을 미치는 입력에 사용됩니다. 예를 들어 이동 및 버튼 누르기가 있습니다. 예측이 필요 없는 불규칙한 희귀 입력의 경우 명령을 사용합니다.

FPVector2 유형은 유니티 Vector2 타입과 동등한 Quantum입니다. Quantum은 장치 간에 시뮬레이션이 결정적이라는 것을 보장하기 위해 부동소수점 대신 고정점(FP)을 사용합니다. 방향 벡터는 나중에 수평 및 수직 입력 축으로 채워집니다.

점프 버튼은 플레이어가 점프하도록 하는 데 사용됩니다. 버튼 유형은 Quantum 관련 유형이며 모든 버튼 입력에 사용해야 합니다. 버튼 입력에 부울을 사용하지 마십시오. 대역폭을 더 많이 사용합니다.

이제 입력이 정의된 프레스 빌드(ctrl + shift + b)가 있습니다. DSL 컴파일러를 실행하여 C# 클래스에서 입력을 사용할 수 있게 합니다.

노트: DSL 파일에 대한 지원을 강조하는 구문을 IDE에 추가하려면 여기 가이드를 따르십시오

Movement 시스템 업데이트

이제 입력을 사용할 수 있으므로 MovementSystem을 열고 Update 기능의 코드를 다음 코드로 바꿉니다.

C#

public override void Update(Frame f, ref Filter filter)
    {
        // gets the input for player 0
        var input = *f.GetPlayerInput(0);

        if (input.Jump.WasPressed)
        {
            filter.CharacterController->Jump(f);
        }

        filter.CharacterController->Move(f, filter.Entity, input.Direction.XOY);
    }

유니티 입력 연결

Unity 프로젝트에서 Photon/QuantumDemo/Game/Scripts/LocalInput 스크립트를 엽니다. 이 스크립트는 유니티 입력을 수집하여 Quantum 엔진으로 전달하는 역할을 합니다. 스크립트의 코드를 다음으로 바꿉니다:

C#

using Photon.Deterministic;
using Quantum;
using UnityEngine;

public class LocalInput : MonoBehaviour
{
    private void Start()
    {
        QuantumCallback.Subscribe(this, (CallbackPollInput callback) => PollInput(callback));
    }

    public void PollInput(CallbackPollInput callback)
    {
        Quantum.Input input = new Quantum.Input();

        // Note: Use GetButton not GetButtonDown/Up Quantum calculates up/down itself.
        input.Jump = UnityEngine.Input.GetButton("Jump");
        
        var x = UnityEngine.Input.GetAxis("Horizontal");
        var y = UnityEngine.Input.GetAxis("Vertical");
        
        // Input that is passed into the simulation needs to be deterministic that's why it's converted to FPVector2.
        input.Direction = new Vector2(x, y).ToFPVector2();

        callback.SetInput(input, DeterministicInputFlags.Repeatable);
    }
}

이제 다시 플레이 모드로 전환하면 캐릭터가 WASD 키를 사용하여 이동하고 스페이스 키를 사용하여 점프할 수 있습니다.

Player movement in Unity editor
Back to top