一般に、ゲームには多数の UI コンポーネントが含まれます。以前のメッセージ フレームワークを使用してすべての UI 関連情報を処理するだけだと、非常に複雑で非効率になります。そこで、UIシステムを独立したシステムとして扱い、UIフレームワークを構築します。
UI フレームワークは主に 3 つの層に分かれています。UIManager はすべての UI コンポーネントを管理するために使用され、UIController はロール情報パネルやストア パネルなどの特定の UI パネルを管理するために使用されます。UIControl は、個々の UI コンポーネントを制御するために使用されます。
UI システムでは、以前のメッセージ システムで使用されていたブロードキャスト フレームワークを放棄しました。このソリューションでは、UI コンポーネントごとにメッセージを送受信するためのメソッドを記述する必要があり、複雑すぎるためです。UIController と UI Manager を通じて、各 UI コンポーネントが他の UI コンポーネントにアクセスできることを期待しています。例えば、「ストア」コントローラのボタンコンポーネントは、「バックパック」コントローラのバックパックのグリッド画像を直接変更し、ストアから購入したアイテムをバックパックに追加する機能を直接実現できます。
1 UIマネージャー
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager : ManagerBase<UIManager> {
public Dictionary<string, UIController> UIControllerDic = new Dictionary<string, UIController>();
public void SetActive(string controllerName, bool active) {
transform.Find(controllerName).gameObject.SetActive(active);
}
public UIControl GetUIControl(string controllerName, string controlName) {
if (UIControllerDic.ContainsKey(controllerName)) {
if (UIControllerDic[controllerName].UIControlDic.ContainsKey(controlName)) {
return UIControllerDic[controllerName].UIControlDic[controlName];
}
}
return null;
}
public override byte GetMessageType() {
return MessageType.Type_UI;
}
}
ここでは、UIManager の下にすべての UIController を保存する辞書を作成します。
SetActiveメソッドで各UIControllerのスイッチを制御します。GetUIControl は、特徴的な UIControl を見つけるために使用されます。ここでは、まず対応する UIController を検索し、次に UIController の下の UIControl を検索することに注意してください。この方法により、走査するコンポーネントの数が減り、効率が向上し、異なる UIController で同じ名前のコンポーネントが存在する問題を回避できます。
UIManager uiManager = UIManager.UIManager としてのインスタンス;
この文が何をしているかに注目してください。UIManager クラスは ManagerBase を継承し、ManagerBase は SingletonBase を継承してその型を ManagerBase にします。これにより、UIManager.Instance タイプが依然として ManagerBase に属し、問題が発生します。したがって、ここでは ManagerBase を UIManager に強制的にダウンキャストする必要があります
2 UIコントローラー
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIController : MonoBehaviour
{
public Dictionary<string, UIControl> UIControlDic = new Dictionary<string, UIControl>();
void Awake() {
UIManager.Instance.UIControllerDic.Add(transform.name, this);
foreach (Transform trans in transform) {
if (trans.gameObject.GetComponent<UIControl>() == null) {
trans.gameObject.AddComponent<UIControl>();
}
}
}
}
UIController に辞書を作成して、UIController 配下に UIControl を保存します。
Awake メソッドでは、まずコンポーネントを UIManager ディクショナリに登録します。同時に、1 つの UIController の下に多数の UI コンポーネントが存在する可能性があることを考慮すると、それらを手動で追加するのは非常に面倒です。そこで、UIController の下の UI オブジェクトを調べて、それぞれに UIControl コンポーネントを追加します。
3 UIコントロール
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class UIControl : MonoBehaviour
{
void Awake() {
if (transform.parent != null) {
UIController controller = transform.GetComponentInParent<UIController>();
if (controller != null) {
controller.UIControlDic.Add(transform.name, this);
}
}
}
public void ChangeText(string str) {
if (GetComponent<Text>() != null) {
GetComponent<Text>().text = str;
}
}
public void ChangeImage(Sprite sprite) {
if (GetComponent<Image>() != null) {
GetComponent<Image>().sprite = sprite;
}
}
public void AddButtonClickEvent(UnityAction action) {
Button control = GetComponent<Button>();
if (control != null) {
control.onClick.AddListener(action);
}
}
public void AddSliderEvent(UnityAction<float> action) {
Slider control = GetComponent<Slider>();
if (control != null) {
control.onValueChanged.AddListener(action);
}
}
public void AddInputFieldEvent(UnityAction<string> action) {
InputField control = GetComponent<InputField>();
if (control != null) {
control.onValueChanged.AddListener(action);
}
}
}
Awake メソッドでは、UIControl コンポーネントを UIController に登録します。これでフレームワークの構築が完了しました。後続の ChangeText、ChangeImage、AddButtonClickEvent、および AddInputFieldEvent は、UI 操作を容易にする関数です。ここでは例として AddButtonClickEvent を取り上げます。
public void AddButtonClickEvent(UnityAction action) {
Button control = GetComponent<Button>();
if (control != null) {
control.onClick.AddListener(action);
}
}
AddButtonClickEvent のパラメータの型は UnityAction であり、匿名メソッドとして理解できます。UnityAction 型を使用するには、UnityEngine.Events をインポートする必要があります。次のプログラムでは、ゲーム オブジェクトのボタン コンポーネント コントロールを取得し、そのコントロールにアクション リスナーをマウントします。
他のメソッドの実装原理も同様であり、その後の開発で実際のニーズに応じてさらに UI 制御メソッドを追加できます。