Unity uGUIの原理解析
Unity uGUI は、Unity によって開始された公式 UI ソリューションです。Unityではパッケージとして提供されます。公式リファレンスマニュアル APIリファレンス
Unity uGUI の使用については、Unity UGUI の超詳細な教示を参照できます。
準備
UGUI は Unity によって提供されるコア パッケージであるため、ソース コードを確認してデバッグできるようになります。[設定] -> [外部ツール] -> [.csproj ファイルの生成] で [組み込みパッケージ] をチェックする必要があります。再生成後、Visual Studio でプロジェクトを確認できますUnityEngine.UI
。この時点で、附加到Unity
関数を通常どおり使用して UGUI コードをデバッグできます。
UnityEngine.UI
Visual Studio のクラス図の表示機能を使用すると、クラス図を確認できます。クラス図を生成するには、VS コード構造を参照して、クラス図を自動的に生成できます。
具体的なクラス図はおおよそ次のとおりです (Unity バージョン 2019.4.20)。
クラス図の分析
クラス図から、UGUI の UI コンポーネントの基本クラスは UIBehaviour であることがわかります。UI コンポーネントは次のように大別できます。
- イベントシステム
- イベントシステム
- ポインター入力モジュール
- コンポーネント
- マスク関連(Mask、RectMask2D)
- グリッドの変更に関連する UI 効果 (インターフェイス IMeshModifier、Shadow、OutLine を実装)
- 選択可能(トグル、スクロールバー、ドロップダウン、ボタン、入力フィールド、スライダー)
- グラフィック画像関連(RawImage、Image、Text)
- レイアウト
- ILayoutController、ILayoutElement など
UGUIの原理
UGUI では、UI の構成は大きく分けてインターフェイスとイベントです。と は
UI の作成時に自動的に生成され、これら 2 つはインターフェイスとイベントに対応します。ここも通常はと一緒に表示されます。Canvas
EventSystem
EventSystem
Input Module
EventSystem
から継承すると、 OnEnable の場合はこの静的変数UIBehaviour
に追加され、 OnDisable の場合は静的変数から削除されることがわかります。このステップの目的は、current 自体が Update 内にあるかどうかを判断することです。つまり、複数のコンポーネントがある場合、Update でコンテンツをトリガーするのは 1 つだけです。m_EventSystems
m_EventSystems
EventSystem
Update の最後には、一連の判定を経て、InputModule の Process メソッドが呼び出されます。
public class EventSystem : UIBehaviour
{
//...
protected override void OnEnable()
{
base.OnEnable();
m_EventSystems.Add(this);
}
protected override void OnDisable()
{
if (m_CurrentInputModule != null)
{
m_CurrentInputModule.DeactivateModule();
m_CurrentInputModule = null;
}
m_EventSystems.Remove(this);
base.OnDisable();
}
protected virtual void Update()
{
if (current != this)
return;
TickModules(); // <<-- 在这里触发 InputModule 的 UpdateModule 方法
//...
if (!changedModule && m_CurrentInputModule != null)
m_CurrentInputModule.Process(); // <<-- 在这里进行输入的处理
}
//...
}
InputModule には PointerInputModule、StandaloneInputModule、TouchInputModule があり、これらのクラスは BaseInputModule から継承されます。
以下にStandaloneInputModule
例を示します。ここでは、Process 関数が EventSystem の Update で呼び出されるメソッドです。マウス イベントを処理するためにも呼び出されますProcessMouseEvent
。イベントを処理する前に、どのコンポーネントがクリックされたかを知る必要もあります。したがって、 GetMousePointerEventData も呼び出して、から継承されたコンポーネントEventSystem.RaycastAll
で光線検出を実行しますBaseRaycaster
。
public class StandaloneInputModule : PointerInputModule
{
//...
public override void Process()
{
if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())
return;
// ...
// touch needs to take precedence because of the mouse emulation layer
if (!ProcessTouchEvents() && input.mousePresent)
ProcessMouseEvent(); // 处理鼠标事件
// ...
}
/// <summary>
/// Process all mouse events.
/// </summary>
protected void ProcessMouseEvent(int id)
{
var mouseData = GetMousePointerEventData(id); // << 在这里面会调用 EventSystem.RaycastAll 来执行射线检测
//...
}
}
概要: EventSystem は主に、入力モジュール (InputModule) を通じて検出する必要があるすべてのオブジェクト (BaseRaycaster) を検出します。通常、私たちが目にするのは、光線検出のための GraphicRaycaster (および統合ゲーム オブジェクトにマウントされた Canvas) です。次に、GraphicRaycaster を通じて ICanvasRaycastFilter インターフェイスを実装する各 Graphic (つまり、RawImage、Image、Text) を呼び出します。