캐릭터 선택
![Circle](/v2/img/docs/circles/icon-gaming_1x.png)
개요
Fighting Template은 Quantum 내부 자체에서 다음을 위해 캐릭터 선택 모드를 구현하고 있습니다:
- 캐릭터 선택에서 게임 플레이로의 전환을 단순화하며 그리고
- 완전히 결정론적인 방식으로 캐릭터 선택 규칙을 적용합니다.
주의: 이 접근 방식은 규칙 기반 캐릭터 선택(예: MOBA, 히어로 기반 슈팅 등)이 있는 모든 게임에 사용할 수 있습니다. 또한 라운드 종료 시 맵 선택 투표에 맞게 조정할 수 있습니다.
캐릭터 선택
캐릭터 선택의 시각적 피드백과 규칙 집합은 별도로 구현됩니다. 전자는 유니티에서 하고 후자는 퀀텀에서 구현합니다. 이 페이지에서는 캐릭터 선택 설정의 다양한 측면과 서로 간의 관계를 살펴봅니다.
유니티
Unity의 게임 씬에는 캐릭터 선택의 다음 부분이 포함됩니다:
- 선택 UI
- 캐릭터 선택 엔티티 프로토타입 그리고
- 플레이어가 선택하는 선택 결정을 반영하는 시각적 피드백용 콜백.
이런 모든 요소들은 CharacterSelect
객체 하위의 씬에서 찾아볼 수 있습니다(Side Bar and UI Camera > Camera > Foreground UI Canvas > CharacterSelect
).
![characterselect parent object](/docs/img/quantum/v2/fighting-template/character-selection-scene-hierarchy.png)
선택 UI
캐릭터 프로필 사진을 사용하여 플레이어에게 캐릭터 선택 항목을 제공합니다. 컴포넌트는 다음과 같습니다.
- 원형 마스크
- 사용할 수 있는 캐릭터의 사각형 그림
- 현재 선택 항목을 강조 표시하는 컬러 원
선택 UI는 완전히 수동적입니다. 이 선택 순서와 이 선택 가능한 캐릭터는 캐릭터 선택 프로토타입에 의해 구동되며 선택 강조 표시는 캐릭터 선택 콜백 객체의 CharacterSelectCallback
스크립트에 의해 처리됩니다.
캐릭터 선택 프로토타입
유니티의 캐릭터 선택 UI P1 및 P2는 순수하게 시각적이며 Quantum의 CharacterSelectSystem
에 있는 기본 로직에 영향을 미치지 않습니다. CharacterSelectSystem
에 필요한 정보는 각각 캐릭터 선택 프로토타입 P1과 P2가 보관합니다.
캐릭터 선택 프로토타입은 다음 두 가지 컴포넌트만으로 구성됩니다.
Entity Prototype
그리고,CharacterSelect
컴포넌트
Entity Prototype
컴포넌트는 모든 유형의 엔티티 프로토타입에 필요한 반면, CharacterSelect
컴포넌트는 선택 가능한 전투기에 대한 정보와 선택 상호작용에 관련된 시청각 피드백을 보관하도록 특별히 설계되었습니다.
![characterselect entity prototype composition](/docs/img/quantum/v2/fighting-template/character-select-prototype.png)
노트: 캐릭터 선택 프로토타입은 Quantum에서 게임 상태를 유지하는 데만 사용되는 엔티티를 만드는 데 사용되므로 유니티에서는 시각적 표현이 필요하지 않으므로 엔티티 뷰가 연결되어 있지 않습니다.
편집기에서 구성할 수 있는 필드들은 다음과 같습니다:
Fighter Index
: PlayerRef를 사용하여 해당 캐릭터 선택 프로토타입을 제어할 수 있습니다. Fighting Template에서 인덱스 0과 1은 각각 플레이어 1과 2에 매핑됩니다. PlayerRefs를 플레이어에게 할당하는 방법에 대한 자세한 내용은 설명서 > 플레이어를 참조하세요.Fighter Choices
: 이 필드에는 FighterDataAsset 목록이 있습니다. 각 FighterDataAsset는 선택 가능한 캐릭터를 나타냅니다. 주의: 나열된 순서는 Quantum의 CharacterSelectSystem에서 사용하는 선택 순서입니다. 선택 UI가 분리되었으므로 선택 UI의 캐릭터 프로파일과 캐릭터 선택 컴포넌트의 전투기 데이터 에셋의 순서를 수동으로 일치시켜야 합니다!Toggle Left / Right SFX
: 선택 영역을 왼쪽/오른쪽으로 이동할 때 SFX가 트리거되었습니다.Select SFX
: 플레이어가 캐릭터 선택을 확인하면 SFX가 트리거됩니다.
다른 모든 필드는 Quantum 시뮬레이션에서 CharacterSelectSystem에 의해 설정 및 조작됩니다.
선택의 시각화
CharacterSelectCallback
스크립트는 모든 플레이어 선택의 시각화 피드백을 처리합니다. Quantum 이벤트 및 콜백 (미) 구독과의 인터페이스를 처리하는 단순 유틸리티 부모 클래스인 SubscriptionBehaviour
를 기본 클래스로 상속합니다.
UI 요소 설정
CharacterSelectCallback
스크립트가 작동하려면 런타임에 조작할 수 있는 UI 요소를 알아야 합니다.
먼저 CharacterSelectSet
의 양을 설정해야 합니다. Fighting Template에서는 기본적으로 2명의 플레이어에게 사용되므로 2로 설정됩니다. 각 CharacterSelectSet
는 선택 가능한 캐릭터 사진이 배치되는 객체인 메인 객체와 캐릭터 사진 옆에 패널 형태로 배치된 강조 표시 원인 선택 컴포넌트 목록을 가져옵니다.
![character select callback setup](/docs/img/quantum/v2/fighting-template/character-select-callback.png)
주의: 캐릭터 그림 강조 표시 패널은 캐릭터 선택 컴포넌트의 파이터 선택과 동일하게 정렬되어야 합니다!
마지막으로, CharacterSelectCallback
에는 선택이 진행되는 동안 표시되는 Main Header 및 Spectating Text에 대한 참조가 필요합니다.
- Main Header는 두 플레이어가 최종 선택을 마칠 때까지 제시됩니다.
- Spectating Text는 로컬 플레이어가 캐릭터 선택을 확인한 후 원격 플레이어가 자신의 캐릭터를 확인하기를 기다리는 동안 표시됩니다.
로직
CharacterSelectCallback
의 경우 CallbackUpdateView
콜백을 등록하고 리슨 합니다. 이 특정 콜백은 시뮬레이션(Quantum)이 뷰(유니티)로 제어 권한을 넘겨줄 때마다 트리거 됩니다. 이때 스크립트는 Quantum의 최신 검증된 프레임을 가져옵니다. 그런 다음 이 프레임을 사용하여 컴포넌트를 필터링하고 결과 수집을 반복하고 정보를 폴링 할 수 있습니다.
주의: 프레임 상태에서 poll 을 할 수 있습니다. 그러나 쓰기 는 허용되지 않습니다. 이는 불확실하며 시뮬레이션 비동기화가 발생할 수 있습니다.
그런 다음 프레임에서 폴링된 정보를 기반으로 CharacterSelectCallback
스크립트는 필요한 UI 요소를 활성화하거나 비활성화할 수 있습니다.
C#
protected override void SubscriptionDispatch(CallbackUpdateView result){
var frame = result.Game.Frames.Verified;
var charSelect = frame.Filter<CharacterSelect>();
bool isSelecting = false;
bool isSpectating = false;
while (charSelect.Next(out var e, out var cs)) {
var obj = characterSelectSets[cs.fighterIndex];
obj.mainObject.SetActive(cs.isSelecting);
for (int i = 0; i < obj.selectionComponents.Length; i++){
obj.selectionComponents[i].SetActive(cs.highlightedCharacterIndex == i && frame.Number % 10 < 5);
}
if (cs.isSelecting != true) continue;
if (result.Game.PlayerIsLocal(cs.playerRef)){
isSelecting = true;
} else {
isSpectating = true;
}
}
mainHeader.SetActive(isSelecting);
spectatingText.SetActive(isSpectating && !isSelecting);
}
Quantum
Quantum 측면에서는 캐릭터 선택 프로세스가 CharacterSelectSystem
에서 수행됩니다.
- 플레이어들은 사용 가능한 플레이어 목록에 추가됩니다.
- 목록의 처음 두 플레이어는 캐릭터를 선택할 수 있으며
- 패자는 목록에서 다음으로 사용 가능한 플레이어로 대체됩니다.
플레이어 할당
플레이어의 RuntimePlayer
데이터 수신은 ISignalOnPlayerDataSet
의 트리거가 발생됩니다.
C#
public void OnPlayerDataSet(Frame f, PlayerRef player){
var list = f.ResolveList(f.Global->playerOrderList);
list.Add(player);
var filter = f.Filter<CharacterSelect>();
while (filter.NextUnsafe(out var e, out var cs)) {
if (cs->isSelecting == true) continue;
list.Remove(player);
cs->playerRef = player;
cs->highlightedCharacterIndex = 0;
cs->isSelecting = true;
cs->lastInput = InputFlag.NONE;
break;
}
}
CharacterSelectSystem
은 시그널을 실행하고 이를 트리거 한 플레이어를 프레임에 있는 글로벌 목록 playerOrderList
에 추가합니다. 사용 가능한 공간이 있으면 CharacterSelect
컴포넌트에 대한 제어 권한이 할당되어 다음 경기에 참여할 캐릭터를 선택할 수 있습니다. 사용할 수 없는 경우 차례를 기다려야 합니다. Winner Stays 섹션을 참조하십시오.
선택 유효성 검사
CharacterSelectionSystem
은 Quantum 측의 캐릭터 선택 규칙을 적용합니다.
시스템은 먼저 선택 인덱스에 따라 목록에서 선택한 캐릭터를 루핑하여 유효한 공간에서 선택했는지 확인합니다.
C#
if ((inputFlag & InputFlag.Left) != 0) {
cs->highlightedCharacterIndex--;
if (cs->highlightedCharacterIndex < 0)
cs->highlightedCharacterIndex = cs->fighterChoices.Length - 1;
f.Events.PlayAudioEffect(FPVector2.Left, cs->toggleLeftSFX);
} else if ((inputFlag & InputFlag.Right) != 0){
cs->highlightedCharacterIndex++;
if (cs->highlightedCharacterIndex >= cs->fighterChoices.Length)
cs->highlightedCharacterIndex = 0;
f.Events.PlayAudioEffect(FPVector2.Left, cs->toggleRightSFX);
}
캐릭터마다 의상이 여러 개입니다. 캐릭터에 적용될 의상 변형은 캐릭터 선택을 확인하는 데 사용되는 액션 버튼에 따라 달라집니다.
C#
if ((inputFlag & InputFlag.LP) != 0) {
SelectionMade(f, cs, 0);
} else if ((inputFlag & InputFlag.LK) != 0) {
SelectionMade(f, cs, 1);
} else if ((inputFlag & InputFlag.HP) != 0) {
SelectionMade(f, cs, 2);
} else if ((inputFlag & InputFlag.HK) != 0) {
SelectionMade(f, cs, 3);
}
SelectionMade()
메소드는 뷰 업데이트를 위한 확인 이벤트를 트리거 시키고 ISignalOnFighterSelected
시그널(FighterSystem
에 의해 구현됨)을 생성시켜줍니다. ISignalOnFighterSelected
는 선택한 캐릭터를 인스턴스화 해 주며 설정(위치, 회전, 동일한 쌍둥이인 경우 의상 교환 등) 하고 f.Global->ready
을 설정하여 두 플레이어 모두 선택을 마치고 설정이 완료되었다는 것을 반영합니다.
Winner Stays
Fighting Template은 아케이드 스타일 “Winner Stays” 매치를 구현합니다. 즉, 패자는 제어권을 포기하고 관중/대기 목록의 다음 참가자는 크라운을 향해 슛을 합니다. 플레이어를 선발하는 순서는 경기에 참가한 순서와 f.Global->playerOrderList
에 추가된 순서로 정해집니다 - CharacterSelectSystem
의 OnPlayerDataSet
메소드를 참고하세요.
이 프로세스는 NextMatchState
에셋에서 처리됩니다. 먼저 CharacterSelectSystem.RemoveFighter
를 호출하여 게임에서 진 선수를 제거합니다. 이렇게 하면 해당 파이터의 CharacerSelect
컴포넌트도 재설정되어 새 플레이어가 자신의 캐릭터를 선택할 수 있습니다. 마지막으로 남은 파이터의ResetRoundState.ResetFighters
로 재설정합니다.
새로운 플레이어가 캐릭터를 선택하자마자 다음 경기가 시작됩니다.
새로운 선택가능한 개릭터 추가
새 선택 가능한 캐릭터를 추가하려면 다음 단계를 수행하십시오.
CharacterSelect
컴포넌트의 DSL 정의 -array<asset_ref<FighterData>>[4] fighterChoices
에서 파이터 선택 배열의 크기를 늘립니다;- 캐릭터 선택 P1 및 P2 프로토타입의
CharacterSelect
컴포넌트에 있는fighterChoices
필드에 캐릭터의FighterData
에셋을 추가합니다. - 선택 UI에 캐릭터 초상화를 추가합니다.
- P1 및 P2용 선택 UI의 캐릭터 순서가
CharacterSelect
컴포넌트의fighterChoices
배열에 있는FighterData
에셋의 순서와 일치하는지 확인합니다.