ARアプリ 選択したオブジェクトを動かせるようにしたい!2

AR

前回は選択したオブジェクトを移動させる事は出来たものの、理想の動きとは程遠いものでした

今回はそこを改善していこうと思います



考察

前回の段階では、オブジェクトの操作を司るスクリプトに、CreateObjectで取得したオブジェクト情報を与えることが出来ず、やむなくCreateObjectのUpdate内で移動処理をする流れになってしまいました

オブジェクトをクリックした時にそのオブジェクトを取得し、Input.GetMouseButton(0)の効果によりマウスボタンを押している間持続的にマウスの位置情報をオブジェクトに与えるというやり方をした結果、微妙な動き方をしてらっしゃいました

改善のために調べを進めていく中で、OnMouseDown()メソッドというものを発見しました

これはコライダー上でマウス ボタンを押したときに呼び出され、そのオブジェクトを取得できるというものです

これを使うことでオブジェクトの操作を司るスクリプト上で対象物を認識できるのではないかと思い、スクリプトに盛り込んでみることにしました

スクリプトの更新

以下がMoveスクリプト(オブジェクトの操作を司る)を更新したものになります

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class Move : MonoBehaviour
{
    public static GameObject movObj;
    //public Joystick joystick;
    
    public void OnMouseDown()
    {
        //UIをタップしたら飛ばす
        if (EventSystem.current.IsPointerOverGameObject()) return;
        movObj = this.gameObject;
        Debug.Log("オブジェクト名(movObj)=" + movObj);          
    }
   
    public void Z1()
    {
        movObj.transform.position += new Vector3(0, 0, 20 * Time.deltaTime);
    }
    public void Z2()
    {
        movObj.transform.position += new Vector3(0, 0, -20 * Time.deltaTime);
    }
    public void X1()
    {
        movObj.transform.position += new Vector3(-0.3f, 0, 0 * Time.deltaTime);       
    }
    public void X2()
    {
        movObj.transform.position += new Vector3(0.3f, 0, 0 * Time.deltaTime);
    }
    public void Y1()
    {
        movObj.transform.position += new Vector3(0, 0.5f, 0 * Time.deltaTime);       
    }
    public void Y2()
    {
        movObj.transform.position += new Vector3(0, -0.5f, 0 * Time.deltaTime);
    }
    public void R1()
    {       
        movObj.transform.eulerAngles = new Vector3(0, 20, 0);       
    }
    public void R2()
    {
        movObj.transform.eulerAngles = new Vector3(0, -20, 0); 
    }
}

public void OnMouseDown()
{
//UIをタップしたら飛ばす
if (EventSystem.current.IsPointerOverGameObject()) return;
movObj = this.gameObject;
Debug.Log(“オブジェクト名(movObj)=” + movObj);
}

この部分でオブジェクトを取得する予定です

オブジェクトを選択した時にコントロールボタンを表示させようと試みましたが、今度はUIManagerからパネル情報が取得できませんでした

プレハブオブジェクトにアタッチしたMoveスクリプトに空オブジェクトバージョンのUIManagerをアタッチしようとしたのですが、どうやらプレハブにもプログラム実行中に生成されるクローンにもアタッチ出来ないようです

そこで、コントロールボタンの表示はCreateObject側でやってみることにしました

以下が更新したCreateObjectスクリプトになります

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.HID;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.UI;
using UnityEngine.UIElements;

public class CreateObject : MonoBehaviour
{   
    public List<GameObject> fObjects = new List<GameObject>();
    public List<GameObject> aObjects = new List<GameObject>();
    public UIManager uimanager;
    
    public void Update()
    {              
        if (EventSystem.current.IsPointerOverGameObject()) return;//UIをタップした場合飛ばす
         
            if (Input.GetMouseButtonDown(0))           
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//クリックした場所にレイを飛ばす
                RaycastHit hit = new RaycastHit();

                if (Physics.Raycast(ray, out hit) != false)
                {                   
                    if (hit.collider.gameObject.CompareTag("d_obj"))
                    {
                        uimanager.menupanels[3].SetActive(false);
                        uimanager.menupanels[5].SetActive(true);
                    }
                    if (hit.collider.gameObject.CompareTag("arplane") && uimanager.Aobjnow > 9000)
                    {                       
                        Debug.Log("Fobjnow=" + uimanager.Fobjnow);
                        Debug.Log("オブジェクト名:" + fObjects[uimanager.Fobjnow]);
                        Instantiate(fObjects[uimanager.Fobjnow], hit.point, Quaternion.Euler(0, 90, 0));
                        uimanager.Aobjnow = 8000;
                    }
                    else if (hit.collider.gameObject.CompareTag("arplane") && uimanager.Fobjnow > 9000)
                    {                        
                        Debug.Log("Aobjnow=" + uimanager.Aobjnow);
                        Debug.Log("オブジェクト名:" + aObjects[uimanager.Aobjnow]);
                        Instantiate(aObjects[uimanager.Aobjnow], hit.point, Quaternion.Euler(0, 90, 0));
                        uimanager.Fobjnow = 8000;
                    }                  
                }
            }               
    }   
}

if (hit.collider.gameObject.CompareTag(“d_obj”))
{
uimanager.menupanels[3].SetActive(false);
uimanager.menupanels[5].SetActive(true);
}

この部分でコントロールボタンの表示をさせることにしました

クリックしたオブジェクトのタグがd_obj(オブジェクト消去用に全オブジェクトに付けてあるタグ)だった場合に実行するようにしています

menupanels[5]がコントロールボタン入りのパネルとなっています

前回のCreateObjectスクリプトと比較するとだいぶスッキリしたかと思います

実行

祈りを込めて実行してみます・・・

もふもふ
もふもふ

うまくいったもふ(´;ω;`)ウッ…

祈りが通じたようです

ここである事に気づきました

もしOnMouseDown()がマウス専用だったらこの成功が水の泡になると・・・

ビビりながらandroidにビルドしましたが、無事タップにも反応してくれました!



まとめ

Moveスクリプトで独自にオブジェクトを認識、CreateObjectスクリプトでUIManagerスクリプト上のコントロールパネルを管理するこで目的を達成することが出来ました

今後は「動かし方」を改善し、それ以外にも別の要素を追加していこうと思います

タイトルとURLをコピーしました