ツクロウヤ

Unityによるゲーム開発記

【Unity】uGUIと3Dでクリックされたオブジェクトの取得方法

今現在作っているゲームで編成画面を作成していましたが、
・ユニットアイコンを選択(uGUI)
・マップの特定位置を選択(3D)
と2種類のオブジェクトから何が選択されたかを取得する必要がありました。
UIの基礎的な部分に当たるかと思いますが、初めてやってみたので勉強がてらまとめてみました。

画像は仮仮ですが、画面としてはこんな感じ。

f:id:ArtAwA:20181113004240p:plain

実際どういう動きをしているかはこちらの記事を確認ください。

【開発記】進捗報告(11月:2回目) - ツクロウヤ

uGUIで押されたButtonを取得する方法

画像のユニットアイコンを並べている箇所はオブジェクトの構成としては以下のような形になっています。

f:id:ArtAwA:20181113010050j:plain

それぞれのオブジェクトには以下のような制御を行うComponentが設定されています。
「UI_PartyEditor」:UI_PartyEditor.cs
 編成全体の制御用Componet
「Contents」:ContentController.cs
 データリストを元にオブジェクトを複製し各データを設定

そして、この構成で以下のような流れで制御しています。
1.「UI_PartyEditor」から「Contents」にユニットの所持リストをバインド
2.「Contents」で所持リストを元に「BTN_Node」を複製
3. 複製した「BTN_Node」にユニット情報+押した際の挙動を設定
バインド云々は今回は割愛して、ボタンの取得は以下のようなコードで制御しています。
実際にはボタンの取得というよりはユニットのデータを取得しています。

【ユニットアイコンを押したときの挙動】

// -- UI_PartyEditor.cs --
void OnUnitSelect(Button button) {
    // 押したボタンのユニットの情報を取得
    m_SelectUnitData = button.GetComponent<UnitData>();
}

【各ボタンに挙動の設定】

// -- ContentCotroller.cs --
public void SetButtonListener(UnityAction<Button> action) {
    // m_NodeListは生成したBTN_Nodeのリストを格納しているもの
    if (m_NodeList.Count > 0) {
        foreach (var node in m_NodeList) {
            Button button = node.GetComponent<Button>();
            if (button != null) {
                button.onClick.AddListener(() => {
                    action(button);
                });
            }
        }
    }
}

3Dでクリックされたオブジェクトを取得する方法

3DのオブジェクトでもuGUIと同じように押されたときの挙動をUI_PartyEditorに定義して、選択箇所のEventに設定しています。
3Dの方のオブジェクト構成としては以下のような感じです。

f:id:ArtAwA:20181113022801j:plain

1.カメラの準備
まず押されるようにする準備として、メインカメラ(CAM_3D)に「Physics Raycaster」を付ける必要があります。

f:id:ArtAwA:20181113022623j:plain

2.クリック対象の準備
そしてクリック対象(SelectNode)に「Collider」と「EventTrigger」を設定します。
こちらのSelectNodeもuGUIのContentsと同じ形で複製してマップ情報(MapData)を設定しています。

f:id:ArtAwA:20181113022912j:plain

3.スクリプト
上記でPrefabの方の準備が出来たので、後は処理です。
3D(EventTrigger)の場合は少しオブジェクトの取るスクリプトが異なります。

【ユニットアイコンを押したときの挙動】

// -- UI_PartyEditor.cs --
void OnMapSelect(BaseEventData eventData) {
    // 押したオブジェクトの取得
    PointerEventData pointerEvent = (PointerEventData)_eventData;
    GameObject goClicked = pointerEvent.pointerPress;

    // 押したオブジェクトからマップ情報を取得
    MapData data = goClicked.GetComponent<MapData>();
}

【各3Dオブジェクトに挙動の設定】

// -- UI_PartyEditor.cs --
void SetMapEvent() {
// MapManager.Instance.UnitSetEventListは予めSelectNodeのEventTriggerを取得しているもの List<EventTrigger> triggers = MapManager.Instance.UnitSetEventList; if (triggers.Count > 0) { foreach (var trigger in triggers) { EventTrigger.Entry entry = new EventTrigger.Entry(); entry.eventID = EventTriggerType.PointerClick; entry.callback.AddListener(OnMapSelect); trigger.triggers.Add(entry); } } }

 おわりに

今回はこのような感じでUIでのクリックしたオブジェクトの取得を実装してみました。
実際には取得した後に編成部分の処理とかを入れています。

それでは今回はこの辺で
(´・ω・`*)ノシ