This document is about: QUANTUM 2
SWITCH TO

Character Selection


Available in the Gaming Circle and Industries Circle
Circle

概述

格鬥範例在Quantum中自己執行一個角色選擇模式以:

  1. 簡化從角色選擇到遊戲遊玩的過渡;及,
  2. 以一個完全確定性的方式來強化角色選擇規則。

注意事項: 這個方法可以用於任何基於規則的角色選擇的遊戲(比如:MOBA,基於英雄的射擊遊戲等等)。它也可以在回合結束時針對地圖選擇投票來被調整。

角色選擇

角色選擇的視覺效果回饋及規則集被分別執行。前者在Unity而後者在Quantum中完成。這個頁面將介紹角色選擇設定的不同方面,以及它們之間的關聯。

Unity

在Unity中的遊戲場景包含角色選擇的下列部分:

  • 選擇UI;
  • 角色選擇實體原型;及,
  • 針對視覺效果回饋的回調,其反映玩家做出的選擇決定。

所有這些元素可以在CharacterSelect物件下的場景中找到(Side Bar and UI Camera > Camera > Foreground UI Canvas > CharacterSelect)。

CharacterSelect Parent Object
在場景階層中的角色選擇物件位置。

選擇UI

使用角色檔案圖片來呈現角色選擇給玩家。這些包含:

  • 一個圓形遮罩
  • 可用角色的一個方形圖案
  • 一個有顏色的圓圈以聚焦目前的選擇

選擇UI是完全被動的。它代表的選擇順序及可用角色,是由角色選擇原型所驅動,並且選擇聚焦是由角色選擇回調物件上的CharacterSelectCallback指令碼所處理。

角色選擇原型

在Unity中的角色選擇UI P1及P2是純粹的視覺效果,並且不影響在Quantum側上的CharacterSelectSystem中找到的底層邏輯。CharacterSelectSystem所需的資訊,是分別由角色選擇原型P1及P2所持有。

角色選擇原型只由兩個元件所組成:

  • Entity Prototype;及,
  • CharacterSelect元件。

任何及所有類型的實體原型都需要Entity Prototype元件,而CharacterSelect元件被特定地設計,以持有關於可選的鬥士及繫於選擇互動的聲音視覺效果回饋的資訊。

CharacterSelect Entity Prototype Composition
角色選擇實體原型組成。

注意事項: 角色選擇原型用於建立一個實體,其只用於在Quantum中持有一個遊戲狀態,因此在Unity中它不需要任何視覺效果代表;因此,它確實有一個與它關聯的實體檢視。

在編輯器中可以設置的欄位是:

  • Fighter Index:將能夠控制該角色選擇原型的玩家參照。在格鬥範例中,索引0及1將分別映射到玩家1及2。關於如何將玩家參照指派給玩家的更多資訊,請閱讀操作手冊 > 玩家中的文檔。
  • Fighter Choices:這個欄位持有一個鬥士資料資產的清單。各個鬥士資料資產代表一個可選擇的角色。 注意事項: 它們在清單中的順序是在Quantum中的角色選擇系統使用的選擇順序。因為選擇UI被解耦,因此需要手動地配對選擇UI中的角色檔案的順序及在角色選擇元件中的鬥士資料資產!
  • Toggle Left / Right SFX:當向左/右移動選擇時觸發的音效。
  • Select SFX:當玩家確認他們的角色選擇時觸發的音效。

所有其他欄位都由Quantum模擬中的角色選擇系統來設定及操控。

選擇的視覺效果

CharacterSelectCallback指令碼處理所有玩家選擇視覺效果回饋。它繼承自SubscriptionBehaviour基礎類別,其是一個簡單的公用程式上層類別,其處理與Quantum事件及回調訂閱(取消訂閱)的介面。

UI元素設定

CharacterSelectCallback指令碼開始工作之前,它需要知道在運行階段它可以/應該操控的UI元素。
首先,需要設定CharacterSelectSet的數量;在格鬥範例中,它被設定為2,因為預設情況下是針對2名玩家。各個CharacterSelectSet都有一個 主要物件,其是放置可選擇的角色圖片的物件(在目前的情況是P1及P2),以及一個 選擇元件 的清單,其是以面板形式放置在角色圖片旁邊的聚焦圓形。

Character Select Callback Setup
角色選擇回調設定。

注意事項: 角色圖片聚焦面板的排序必須與角色選擇元件中的鬥士選擇相同!

最後,CharacterSelectCallback需要一個參照到 主要標題觀看文字,其將在進行選擇時被顯示。

  • 將呈現 主要標題 直到兩名玩家都已經完成他們的選擇程序。
  • 在本機玩家已經確認他們的角色選擇,並且在等待遠端玩家確認他們的選擇時,將顯示 觀看文字
邏輯

CharacterSelectCallback的情形,它正在註冊並且接聽CallbackUpdateView回調。當模擬(Quantum)將控制權交給檢視(Unity)時,就會觸發這個特定回調。此時,指令碼從Quantum.Game中獲取最後已驗證幀。然後該幀可以用於篩選元件、迭代結果的集合,以及輪詢它們的資訊。

注意事項: 可以從幀狀態 輪詢。然而, 允許從Unity 寫入 到它。這將是非確定性的,並且導致模擬中斷同步。

基於從幀輪詢來的資訊,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之中:

  1. 玩家被新增到可用玩家清單;
  2. 清單中的前兩名玩家被允許選擇他們的角色;及,
  3. 輸家被清單中的下一名可用玩家所取代。

玩家指派

接收一個玩家的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元件的控制權,並且因此被授與選擇角色參加下一場對戰的能力。如果沒有可用的位置,他們將必須等待他們的回合;請參見贏者留下章節。

選擇驗證

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以反映兩個玩家是否已經做出他們的選擇及他們的角色設定。

贏者留下

格鬥範例執行一個街機風格的「贏者留下」對戰;換句話說,輸家交出控制權,而在觀眾/等待清單上的下一位玩家被給予機會來獲得冠軍。玩家被選擇的順序由他們加入遊戲並且被新增到f.Global->playerOrderList的順序來定義——請參見CharacterSelectSystem中的OnPlayerDataSet方法。

NextMatchState資產中處理這個流程。首先,它從對戰中移除了失敗的玩家,方法是調用CharacterSelectSystem.RemoveFighter;這也針對該鬥士重新設定了CharacerSelect元件,這樣新的玩家能夠選擇他們自己的角色。最後,它以ResetRoundState.ResetFighters重新設定了剩下的鬥士到他們的原始位置。

當新的玩家已經選擇他們的角色,下一場對戰開始。

新增新的可選擇的角色

為了新增新的可選擇的角色,請遵循這些步驟:

  1. CharacterSelect元件的DSL定義中增加鬥士選擇陣列的大小——array<asset_ref<FighterData>>[4] fighterChoices
  2. 在角色選擇P1及P2原型上的CharacterSelect元件中,新增角色的FighterData資產到fighterChoices欄位。
  3. 新增角色描述到選擇UI。
  4. 確保選擇UI中針對P1及P2的角色順序,匹配在CharacterSelect元件的fighterChoices陣列中的FighterData資產的順序。
Back to top