最初に
Unityにはコンポーネントに設定されたイベントハンドラをマウスクリック等で呼び出す、イベントシステムという仕組みがあります。これがどうやって動いているかを調査したので、まとめました。
勘違いしている箇所などあればご指摘お願いします。
以下URLを参考にさせてもらいました。
http://blog.d-yama7.com/archives/190
https://docs.unity3d.com/ja/current/Manual/EventSystem.html
環境: Unity 2018.1.5f1 (64-bit)
イベントシステムの主要なオブジェクト
EventSystem
ゲームオブジェクトの追加でUI→EventSystemとやると、このコンポーネントが付いたオブジェクトが生成されます。
Updateメソッドで毎フレームInputModuleの処理をキックしているコンポーネントです。
また、シーン内に存在する全てのRaycasterを使って指しているオブジェクト一覧を得るなどのユーティリティ的な役割も行います。
InputModule
マウスの状態やRaycasterから得た指しているオブジェクトを元に、実際にイベントを発生させているコンポーネントです。
既定ではEventSystemのGameObjectに最初からStandaloneInputModuleが追加されています。
RayCaster
unityは3次元を扱うので、マウスでクリックした点から直接「何が指されているか」を求めることができません。
RayCasterはRayオブジェクトを使って「何が指されているか」を取得するためのコンポーネントです。
種類ごとにアタッチすべきGameObjectが異なるので注意が必要です。
- Graphic Raycaster - キャンバスのUI要素を指す。Canvasにアタッチする必要がある。
- Physics Raycaster - 3D物理要素を指す。カメラのGameObjectにアタッチする必要がある。
- OVR Physics Raycaster - Oculus用のVRコントローラーや視線から3D物理要素を指す。OVRCameraRigにアタッチする必要がある。
ちなみにOculus用のイベントシステムを動かすにはレーザーポイント先を表示するための、OVRGazePointerがシーン内に必要。
IEventSystemHandlerを継承したインターフェース
イベント時になにかするコンポーネントは、このインターフェースを実装することでそれを実現します。
クリックされたときのイベントハンドラを定義しているIPointerClickHandler等です。
// 使い方の例
public class CubeClickEventHandler : MonoBehaviour, IPointerClickHandler {
public void OnPointerClick(PointerEventData pointerEventData)
{
Debug.Log("Game Object Clicked!");
}
}
シーケンス図
以下のような感じでイベントハンドラを呼び出している……と思います。
PlantUMLソース
unity -> EventSystem : Update()
note left : MonoBehaviourの\nUpdate()
EventSystem -> InputModule : Process()
EventSystem <-- InputModule: RaycastAll(point)
note right : マウス等座標等を渡して、\nRaycasterに指されたGameObjectを\n取得してもらう
EventSystem --> Raycaster : Raycast(point)
EventSystem <-- Raycaster : raycastRsult
EventSystem --> InputModule : raycastResult
InputModule -> EventData : 生成
activate EventData
note left : マウスボタン情報などは\nInputModuleが自前で取得して\nEventData作成、イベント発火
InputModule -> ExecuteEvents : Execute(target,eventData)
ExecuteEvents -> "イベントハンドラが\n設定されたComponent" : OnPointerClick()等
deactivate EventData
note right : IEventSystemHandlerを継承した\nintarfaceのメソッドを呼び出す