This document is about: QUANTUM 2
SWITCH TO

입력


Available in the Gaming Circle and Industries Circle
Circle

개요

격투 게임에서 입력은 플레이어 간의 빠른 전송, 정밀도 및 상태 입력 스트림을 단순히 소비하는 것이 아니라 일정 기간 동안 추적할 수 있는 능력을 필요로 합니다.

이 페이지에서는 유니티에서 캡처하는 플레이어 입력과 이러한 값이 Quantum에서 평가 및 계산되는 방법에 대해 설명합니다.

입력 구조체

대역폭을 낮게 유지하려면 일반적으로 입력 구조체를 가능한 작게 유지하는 것이 좋습니다. 이것은 입력의 일부로 단일 열거형 InputFlag를 보유하여 Fighting Template에서 극단으로 밀어 넣습니다.

chsarp

input {
  InputFlag inputFlag;
}

InputFlag 열거형 정의는 두 값의 거듭제곱을 명시적으로 할당하므로 비트 연산을 사용하여 InputFlag를 조작할 수 있습니다. 이렇게 하면 InputFlag가 여러 입력 값을 동시에 저장할 수 있습니다.

C#

// Input flags used to represent the directional and button inputs
enum InputFlag {
  NONE = 0,
  Left = 1,
  Right = 2,
  Down = 4,
  Up = 8,
  LP = 16,  // light punch
  LK = 32,  // light kick
  HP = 64,  // heavy punch
  HK = 128, // heavy kick
  Directions = 15, // Used by the systems to extract the input directions from the input struct
  Buttons = 240, // Used by the systems to extract the button input from the input struct
}

유니티 측

Fighting template은 모바일(UI 버튼)과 PC(키보드 및 게임 패드)의 두 가지 입력 인터페이스를 구현합니다. 빌드의 실행 플랫폼에 따라 실행 중인 한 입력 또는 다른 입력이 고려됩니다.

입력 인터페이스가 다양하더라도 입력 로직은 기기 간에 동일하게 유지됩니다.

입력 로직

입력 로직은 QuantumDemoInput.cs 스크립트에서 설정되며 PollInput 콜백을 리슨합니다.

키보드 입력

QuantumDemoInput.csKeycodeSet 구조체에 설정된 각 버튼은 부울 값으로 표시됩니다. 부울 값이 true로 평가되면 Input 구조체의 InputFlag 매개 변수로 유지되는 값이 그에 따라 업데이트됩니다.

C#

if (UInput.GetKey(Left)){
   input.inputFlag |= InputFlag.Left;
}

모바일 입력

모바일 입력은 버튼의 누름 값을 처리하는 MobileJoystick이라는 UI 스크립트와 모든 활동 MobileJoystick 스크립트와 입력이 들어왔을 때를 다루는 QuantumDemoInput.cs 로직의 두 부분으로 나뉘어 있습니다.

MobileJoystick은 8개 방향으로 모두 이동할 수 있도록 2개의 플래그 매개변수를 제공합니다. 오른쪽 위 대각선은 Quantum.InputFlag.Up Quantum.InputFlag.Right으로 표시됩니다. flag1flag2가 동일한 값으로 설정되어 있으면 고유 입력으로 간주됩니다. 비트 방향 작업을 사용하면 각 UI 버튼의 설정에 관계없이 값 할당이 동일하게 유지됩니다.

C#

public class MobileJoystick : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler{
   public Quantum.InputFlag flag1;
   public Quantum.InputFlag flag2;
   public Quantum.InputFlag FlagValue { get; private set; }

   public void OnPointerEnter(PointerEventData eventData){
       FlagValue = flag1 | flag2;
   }

   public void OnPointerExit(PointerEventData eventData){
       FlagValue = Quantum.InputFlag.NONE;
   }
}

QuantumDemoInput은 알려진 MobileJoystick 스크립트 배열 위에서 반복되고 비트 또는 각 버튼에 있는 값을 함께 추가하는 데 사용됩니다.

C#

for (int i = 0; i < mobileButtons.Length; i++){
   input.inputFlag |= mobileButtons[i].FlagValue;
}

Quantum 측

시뮬레이션 측(Quantum)에서는 여러 프레임에 걸친 순차 입력에 의해 트리거되는 조합과 지속적인 버튼 누름이 필요한 충전 공격을 모두 허용하려면 입력을 여러 프레임에 걸쳐 추적해야 합니다.

입력 시퀀스는 InputCommandData 에셋을 사용하여 편집 시 정의되고 InputBuffer 컴포넌트를 사용하여 런타임에 추적됩니다.

InputCommandData

InputCommandDataBase는 추상 에셋 클래스입니다. 이 클래스는 필요에 맞게 TestCmdPair()를 구현할 구체적인 에셋을 정의하는 데 사용됩니다.

C#

public abstract unsafe partial class InputCommandDataBase{
   /// The parameter set for the forward and backward version of the input.  Should be a fixed point parameter.
   public CAParameters forDirectionParameter;
   public CAParameters backDirectionParameter;

   /// The forward and backward version of the command
   public InputFlag[] forDirectionInputSequence;
   public InputFlag[] backDirectionInputSequence;

   public void TestCmdPair(Frame f, InputBuffer* i, int side, CustomAnimator* a, ref QList<InputValue> dSeq);
   protected abstract bool TestCmd(Frame f, InputBuffer* iB, int side, InputFlag[] flagArray, ref QList<InputValue> directionalSequence);
}

Fighting Template에 포함된 구체적인 구현은 다음과 같습니다.

  • InputCommandData 그리고
  • ChargeInputCommandData.

InputCommandData는 일련의 입력을 수행하여 플레이어가 트리거 하는 특수 동작을 활성화하는 데 사용됩니다. ChargeInputCommandData는 동일한 입력을 유지하여 여러 프레임에 걸쳐 충전이 필요한 입력 시퀀스를 정의하는 데 사용됩니다.

InputBuffer

프레임의 일부로 각 플레이어별로 입력을 추적해야 합니다. 이를 위한 가장 편리하고 유연한 방법은 각 플레이어가 통제하는 엔티티의 컴포넌트를 이 목적에 전용으로 사용하는 것입니다(Fighting Template에서 사용하는 접근 방식).

InputBuffer 컴포넌트는 다음 세 가지를 추적하는 데 사용됩니다.

  • 입력 방향
  • 버튼 누름 그리고
  • 입력의 누름 또는 뗀 시간의 길이

InputBufferInputBufferSystem에 의해 업데이트됩니다.

C#

component InputBuffer{
  list<InputValue> directionalSequence;
  list<InputValue> buttonSequence;
  array<InputTimer>[8] inputTimers;
}

InputValue 유형은 DSL에 정의된 단순한 구조체입니다. 이 파일에는 InputFlag의 복사본과 연결된 프레임 번호가 포함되어 있습니다. 방향 입력 및 동작 버튼 시퀀스는 별도로 조작되므로 InputBuffer 컴포넌트에서 두 개의 InputValue 목록을 유지함으로써 별도로 추적됩니다.

C#

struct InputValue{
  InputFlag inputFlag;
  Int32 frame;
}

특정 입력이 눌리거나 해제된 시간은 InputTimer 구조체를 사용하여 추적됩니다.

C#

struct InputTimer{
  FP timeDown;
  FP timeUp;
}

InputBufferSystem

InputBufferSystem은 두 가지의 목적이 있습니다:

  • 입력 구조체에서 현재 InputFlag를 검토하고
  • InputBuffer 컴포넌트를 업데이트합니다.

현재 입력의 입력 플래그를 평가하기 전에 방향 및 버튼 입력이 분리됩니다.

C#

InputFlag dirFlag = input->inputFlag & ~(InputFlag.Buttons);
InputFlag btnFlag = input->inputFlag & ~(InputFlag.Directions);

이 분할은 이동 세트를 트리거하기 위해 플레이어가 수행한 작업을 추적하는 데 도움이 됩니다. 먼저 UpdateInput()은 입력이 보류 중인지 확인하여 InputBuffer 컴포넌트의 InputTimer를 업데이트합니다.

  • 눌려짐:해당 입력에 대한 InputTimer.TimeDown 이 증가
  • 누르지 않음: 해당 프레임 동안 입력이 눌려 있지 않고 입력에 대한 재설정 허용 오차가 초과된 경우 해당 입력의 InputTimer.TimeDown이 재설정됩니다. 이 작업은 충전 이동을 활성화하기 위해 수행됩니다(예: 몇 프레임에 대해 충전한 다음 앞으로 누름 및 버튼을 누름)

모든 InputTimers가 업데이트된 후 InputBufferSystemCustomAnimator의 매개 변수를 이 새로운 값들로 업데이트합니다.

마지막 단계인 InputBufferSystemInputBufferComponent가 보유한 입력 시퀀스 목록을 추출합니다. 현재 입력의 방향값은 컴포넌트에 저장된 이전 InputValues와 비교하여 확인되고 두 값이 다를 경우 업데이트됩니다. 이 목록은 각 플레이어의 파이터와 관련된 모든 InputCommandData 에셋에서 TestCmdPair() 메소드에 대한 매개 변수로 전달됩니다.

이 구현은 앞서 언급한 측면을 결합하여 플레이어들이 변경 사항 사이의 허용 오차(기본적으로 약 10프레임)와 함께 입력 시퀀스를 입력할 수 있도록 합니다.

예를 들어 플레이어의 파이터가 InputCmd_QuarterCircle 에셋을 보유하고 있는 경우, 입력 시퀀스가 다음 값으로 구성된 경우 QCF_F 애니메이션 매개 변수를 트리거하고 관련 동작을 실행합니다.

C#

{frame = 80, value = 4}  // Down
{frame = 90, value = 6}  // Down + Right
{frame = 100, value = 2} // Right

그런 다음 명령 버퍼가 32개 입력이므로 양수의 입력 시퀀스로 등록됩니다.

특별한 이동 트리거

유니티 애니메이터에서 편집 시 특별한 이동이 설정되고 CustomAnimatorGraph 에셋으로 베이크됩니다. 런타임의 InputBufferSystem은 단순히 CustomAnimator 컴포넌트의 매개 변수를 업데이트합니다. CustomAnimatorUpdaterCustomAnimator 컴포넌트(CustomAnimatorSystem 참조)에서 Update()를 호출할 때 전환 매개 변수가 모두 충족되면 이동이 트리거 됩니다. 현 상태를 벗어나 새로운 상태로 진입하면 각 상태에서 SignalOnAnimatorStateExitISignalOnAnimatorStateEnter 가 발생됩니다.

주의: InputBufferSystem에서 업데이트된 매개 변수는 모두 FixedPoint 타입입니다. 이 작업은 여러 프레임에 대해 새 입력을 수행하지 않은 플레이어가 이전 프레임에서 캐시 된 입력에 기반하여 실수로 공격을 수행하지 않도록 하기 위해 수행됩니다.

fighting template special move trigger parameters
Uppercut_LP 특별 이동용 전환 트리거 매개 변수.

예를 들어 Uppercut_LP 상태는 다음 조건이 동시에 충족되는 한 AnyState에서 트리거될 수 있습니다.

  • Z축(ZMotionF)의 움직임이 0보다 크고 0.15보다 작음
  • 라이트 펀치 입력 시간이 0보다 크고 0.15보다 작음
  • 캐릭터가 현재 땅에 있음(즉, InAir가 거짓임).
  • 캐릭터는 현재 특수 공격을 수행할 수 있는 상태(즉, CanSpecialAtk이 true).

FixedPoint 매개 변수는 InputBufferSystem에서 직접 업데이트되거나 InputCommandData에 전달된 입력 시퀀스의 결과로 계속 업데이트됩니다. 반면 부울 매개 변수는 FighterAnimatorState의 일부이며 캐릭터가 처음 현재 상태로 전환될 때 설정됩니다.

Back to top