質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Microsoft HoloLens

Microsoft HoloLensは、マイクロソフト社が開発しているヘッドマウントディスプレイ方式のコンピュータです。拡張現実体験のため透明なレンズを備えています。

MR(Mixed Reality)

MR(Mixed Reality)は、複合現実とも呼ばれるVRとARを融合したような技術。現実世界の形状をデバイスが把握し、仮想世界と座標空間を精密に重ね合わせることで実現します。専用のヘッドセットを装着した人の動きに合わせた環境構築ができる他、同じMR空間を複数人で同時に体験することも可能です。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

978閲覧

HoloLens2,QRコードを読み込んだ時に、仮想ボタンを表示して、ボタンを押したらオブジェクトが生成されるようにしたい。

Corazon0715

総合スコア7

Microsoft HoloLens

Microsoft HoloLensは、マイクロソフト社が開発しているヘッドマウントディスプレイ方式のコンピュータです。拡張現実体験のため透明なレンズを備えています。

MR(Mixed Reality)

MR(Mixed Reality)は、複合現実とも呼ばれるVRとARを融合したような技術。現実世界の形状をデバイスが把握し、仮想世界と座標空間を精密に重ね合わせることで実現します。専用のヘッドセットを装着した人の動きに合わせた環境構築ができる他、同じMR空間を複数人で同時に体験することも可能です。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2023/06/28 09:51

実現したいこと

  • HoloLens2向けのアプリケーション開発をしています。
  • QRコード読み込むと、仮想ボタンがQRコードの上に表示され、そのボタンを押すと、オブジェクトが生成されるアプリを開発したいです。

前提

Unityを使用して、HoloLens2向けのアプリケーションを開発しています。

Visual Studio 2022
Unity 2020.3 LTS

発生している問題・エラーメッセージ

  • 現状、以下のように、QRを読み込むと、仮想ボタンが表示されますが、ボタンを押しても何も反応がありません(押した感はあります)

イメージ説明

該当のソースコード

  • Unityプロジェクト
    • QRCodesManagerが主のオブジェクトです。
    • QR CodesManager.csはQRコードの追加、更新、削除を管理しています。
    • QR CodesVisualizer.csは、QRコードが認識された際のビジュアライズをしています。
      • ビジュアライズしたいものをQRCodePrefabとしてインスペクターから設定できます。(私は、仮想ボタン「VoiceInputButton」を設定しています)

イメージ説明

QR

1using System.Collections; 2 3using System.Collections.Generic; 4 5using UnityEngine; 6 7using Microsoft.MixedReality.QR; 8namespace QRTracking 9{ 10 public class QRCodesVisualizer : MonoBehaviour 11 { 12 public GameObject qrCodePrefab;//QRコードが認識されたときにインスタンス化されるプレハブ 13 public GameObject ButtonPrefab3; 14 15 16 17 private System.Collections.Generic.SortedDictionary<System.Guid, GameObject> qrCodesObjectsList; // 認識したQRコード(System.Guid(全世界で一意の識別子)が割り当てられる)とそれに対応するゲームオブジェクトのペアを保存している 18 private bool clearExisting = false; 19 20 struct ActionData //QRコードが追加、更新、削除されたときに発生するアクション 21 { 22 public enum Type 23 { 24 Added, 25 Updated, 26 Removed 27 }; 28 public Type type; 29 public Microsoft.MixedReality.QR.QRCode qrCode; 30 31 public ActionData(Type type, Microsoft.MixedReality.QR.QRCode qRCode) : this() //構造体のコンストラクタ。構造体を作成する際に呼び出される 32 { 33 this.type = type; 34 qrCode = qRCode; 35 } 36 } 37 38 private System.Collections.Generic.Queue<ActionData> pendingActions = new Queue<ActionData>(); //ActionData型のキューを作成している。QRコードにアクション(added,updated,removed)が発生すると、そのアクションとQRコードデータはこのpedingActionsキューに追加される 39 40 void Awake() 41 { 42 43 } 44 45 // Use this for initialization 46 void Start() 47 { 48 // GameObject qrCodeObject3 = Instantiate(ButtonPrefab3, new Vector3(0f, 0f, 1.4f), Quaternion.identity); //qrCodePrefabを生成する 49 50 System.Diagnostics.Debug.WriteLine("visualize start"); 51 System.Console.WriteLine("visualize start console"); 52 53 54 Debug.Log("QRCodesVisualizer start"); 55 qrCodesObjectsList = new SortedDictionary<System.Guid, GameObject>(); //qrCodeObjctsListの初期化 56 57 // イベントハンドラの登録。QRCodesManagerクラスのインスタンスの特定のイベントが発生したときに呼び出すメソッドを指定している。これらのイベントは、QRコードの追加、更新、削除、およびQRコードの追跡状態の変更を監視します。 58 QRCodesManager.Instance.QRCodesTrackingStateChanged += Instance_QRCodesTrackingStateChanged; 59 QRCodesManager.Instance.QRCodeAdded += Instance_QRCodeAdded; // 新たなQRコードが追加された場合に、Instance_QRCodeAddedメソッドを呼び出す 60 QRCodesManager.Instance.QRCodeUpdated += Instance_QRCodeUpdated; 61 QRCodesManager.Instance.QRCodeRemoved += Instance_QRCodeRemoved; 62 if (qrCodePrefab == null) 63 { 64 throw new System.Exception("Prefab not assigned"); 65 } 66 } 67 // QRコードの追跡状態が変化した場合に呼び出される 68 private void Instance_QRCodesTrackingStateChanged(object sender, bool status) 69 { 70 if (!status) 71 { 72 clearExisting = true; 73 } 74 } 75 76 // 新たなWQRコードが追加された場合に、Instance_QRCodeAddedメソッドを呼び出す 77 private void Instance_QRCodeAdded(object sender, QRCodeEventArgs<Microsoft.MixedReality.QR.QRCode> e) 78 { 79 Debug.Log("QRCodesVisualizer Instance_QRCodeAdded"); 80 81 lock (pendingActions) 82 { 83 pendingActions.Enqueue(new ActionData(ActionData.Type.Added, e.Data)); 84 } 85 } 86 87 // QRコードが更新された場合に呼び出される 88 private void Instance_QRCodeUpdated(object sender, QRCodeEventArgs<Microsoft.MixedReality.QR.QRCode> e) 89 { 90 Debug.Log("QRCodesVisualizer Instance_QRCodeUpdated"); 91 92 lock (pendingActions) 93 { 94 pendingActions.Enqueue(new ActionData(ActionData.Type.Updated, e.Data)); 95 } 96 } 97 98 // QRコードが削除された場合に呼び出される 99 private void Instance_QRCodeRemoved(object sender, QRCodeEventArgs<Microsoft.MixedReality.QR.QRCode> e) 100 { 101 Debug.Log("QRCodesVisualizer Instance_QRCodeRemoved"); 102 103 lock (pendingActions) 104 { 105 pendingActions.Enqueue(new ActionData(ActionData.Type.Removed, e.Data)); 106 } 107 } 108 109 // void Updateで呼ばれる 110 private void HandleEvents() 111 { 112 lock (pendingActions) // 複数のスレッドからリソースに同時にアクセスすることを防ぐ 113 { 114 while (pendingActions.Count > 0) // pendingActions(アクションのキュー)が終わるまでひたすら処理回す 115 { 116 var action = pendingActions.Dequeue(); 117 if (action.type == ActionData.Type.Added) //アクションがQRコードの追加なら 118 { 119 GameObject qrCodeObject = Instantiate(qrCodePrefab, new Vector3(0, 0, 0), Quaternion.identity); //qrCodePrefabを生成する 120 qrCodeObject.GetComponent<SpatialGraphCoordinateSystem>().Id = action.qrCode.SpatialGraphNodeId; // 現実世界の空間座標系をUnity座標系に変換する(QRコードに追従するように動くようになる)QRコードに関連する空間のノードIDをゲームオブジェクトに関連付けている。これによって、GameObjectが物理世界内の特定の位置・向きを持つようになる 121 qrCodeObject.GetComponent<QRCode>().qrCode = action.qrCode; // QRコードの情報をこのゲームオブジェクトに関連付けている 122 qrCodesObjectsList.Add(action.qrCode.Id, qrCodeObject); // qrCodesObjectsList(key: QRコードID, value: ゲームオブジェクト)に登録 123 } 124 else if (action.type == ActionData.Type.Updated)//アクションがQRコードの更新なら 125 { 126 if (!qrCodesObjectsList.ContainsKey(action.qrCode.Id))// Addで既に登録してあるのに、削除された以外で、keyがないことなんてあるのか 127 { 128 GameObject qrCodeObject = Instantiate(qrCodePrefab, new Vector3(0, 0, 0), Quaternion.identity); 129 qrCodeObject.GetComponent<SpatialGraphCoordinateSystem>().Id = action.qrCode.Id;//###########################なぜAddとUpdatedでGetComponent<QRCode>().qrCodeに代入するIDが異なるのかは謎########################################### 130 qrCodeObject.GetComponent<QRCode>().qrCode = action.qrCode; 131 qrCodesObjectsList.Add(action.qrCode.Id, qrCodeObject); 132 } 133 } 134 else if (action.type == ActionData.Type.Removed)//アクションがQRコードの削除なら 135 { 136 if (qrCodesObjectsList.ContainsKey(action.qrCode.Id)) 137 { 138 Destroy(qrCodesObjectsList[action.qrCode.Id]); 139 qrCodesObjectsList.Remove(action.qrCode.Id); 140 } 141 } 142 } 143 } 144 if (clearExisting) 145 { 146 clearExisting = false; 147 foreach (var obj in qrCodesObjectsList) 148 { 149 Destroy(obj.Value); 150 } 151 qrCodesObjectsList.Clear(); 152 153 } 154 } 155 156 // Update is called once per frame 157 void Update() 158 { 159 HandleEvents(); 160 } 161 } 162 163} 164
  • VoiceInputButton
    • QRコードが読み込まれたときに、QRコードの上に表示する仮想ボタンです。

イメージ説明

VoiceInputButtonPressed.cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5 6public class VoiceInputButtonPressed : MonoBehaviour 7{ 8 public GameObject ButtonPrefab; 9 public GameObject ButtonPrefab2; 10 11 12 13 void Start() 14 { 15 GameObject qrCodeObject2 = Instantiate(ButtonPrefab2, new Vector3(0f, 0f, 1.5f), Quaternion.identity); //qrCodePrefabを生成する 16 17 // ボタン押されたことのメッセージを表示したい 18 System.Diagnostics.Debug.WriteLine("#####System.Diagnostics.Debug.WriteLine#####"); 19 System.Console.WriteLine("#####START System.Console.WriteLine#####"); 20 Debug.Log("Start"); 21 22 23 } 24 25 void Update() 26 { 27 28 } 29 30 public void ButtonPressed() 31 { 32 // 新しいインスタンスを生成したい 33 GameObject qrCodeObject12 = Instantiate(ButtonPrefab, new Vector3(0f, 0f, 1.3f), Quaternion.identity); //qrCodePrefabを生成する 34 35 36 // ボタン押されたことのメッセージを表示したい 37 Debug.Log("#####ButtonPressed Debug.Log#####"); 38 System.Diagnostics.Debug.WriteLine("#####ButtonPressed System.Diagnostics.Debug.WriteLine#####"); 39 40 41 } 42} 43

試したこと

  1. (方針)QRコードのスクリプトの中では、別のオブジェクトを生成できない可能性がある。QRコードを読み込んだ時じゃなくて、Start()の時点でCubeが生成できるかどうか試す。
    1. QRCodesVisualizer.csのStart()で緑のCubeが表示できた。
  2. ✖(方針)Poster Sceneでそもそもボタンが動くのかどうか試してみる
    1. AdminMenuとHeadWidgetを配置する。AdminMenuのボタンを押して、HeadWidgetの表示非表示を制御することはできた。
    2. 次どうする?:となると、QRコードを読み込んだときに表示するボタンを押して、HeadWidgetの表示非表示が制御できるかどうかを試す。
  3. ✖(方針)いちいちHololens2にビルドするのめんどくさいから、Unity Editor内でQRコードを表示して、読み込めないか試してみる。
    1. Plane作って、QRコードのテクスチャ貼ったMaterialを貼ってみたけどQRCodeの認識ができないからだめそう。
  4. 👹(方針)QRコードを読み込んだときに表示するボタンを押して、HeadWidgetの表示非表示が制御できるかどうか。QRコードを読み込んで表示されたボタンとのインタラクションができないのでは。
    1. 試してみたこと:
    (1)最初に、QRCodesVisualizer.csのStart()で緑Cubeをinitialize()
    (2)QRコード読み込んだ時に、VoiceInputButton.csのStart()で、青Cube
    (3)ボタン押したときに、VoiceInputButton.csのButtonPressed()で、赤Cube
    2. 結果:
    UnityEditor上では、(1)だけできた(QRコードの認識ができないからしょうがない)
    HoloLens2上では、全部だめ。
    Editor上ではできて、HoloLens2上ではできないのが謎。
    3. 考察:
    QRコード読むのに特化していて、他とのインタラクションは制御できていない?いわけんさんのやつのタイトルが「Unity×HoloLens2×MRTK×QRCodeをとりあえず動かしたいとき」になっているのが気になる、とりあえず動かしたい時で、正式に使おうとしたらこのやり方じゃダメなのかも?
    4. 結論:
    別のやり方を試してみる。
  5. (方針)別のやり方を探す
    1. 他の人のQRコードリーダーを試してみる
    2. VuforiaのARマーカーを使用する
    3. 外付けのwebカメラを使う

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

この回答はGPT-4による自動生成回答です

markdown

1 switch (action.type) 2 { 3 case ActionData.Type.Added: 4 // QRコードが追加されたときの処理 5 GameObject qrCodeObject = Instantiate(qrCodePrefab, new Vector3(0f, 0f, 1.4f), Quaternion.identity); //qrCodePrefabを生成する 6 qrCodeObject.GetComponent<QRCode>().qrCode = action.qrCode; //生成したqrCodeObjectのQRCodeコンポーネントのqrCodeに、認識したQRコードの情報をセット 7 qrCodesObjectsList.Add(action.qrCode.Id, qrCodeObject); //qrCodesObjectsListに、認識したQRコードのIDと、生成したqrCodeObjectを追加 8 break; 9 case ActionData.Type.Updated: 10 // QRコードが更新されたときの処理 11 qrCodesObjectsList[action.qrCode.Id].GetComponent<QRCode>().qrCode = action.qrCode; //qrCodesObjectsListから、更新されたQRコードのIDに対応するqrCodeObjectを取得し、そのQRCodeコンポーネントのqrCodeに、更新されたQRコードの情報をセット 12 break; 13 case ActionData.Type.Removed: 14 // QRコードが削除されたときの処理 15 Destroy(qrCodesObjectsList[action.qrCode.Id]); //qrCodesObjectsListから、削除されたQRコードのIDに対応するqrCodeObjectを取得し、そのqrCodeObjectを破棄 16 qrCodesObjectsList.Remove(action.qrCode.Id); //qrCodesObjectsListから、削除されたQRコードのIDと、そのIDに対応するqrCodeObjectを削除 17 break; 18 } 19 } 20 } 21 } 22 23 // Update is called once per frame 24 void Update() 25 { 26 HandleEvents(); // HandleEventsメソッドを呼び出す 27 } 28 } 29}

上記のコードは、QRコードが認識されたときに、そのQRコードの上に仮想ボタンを表示する処理を行っています。しかし、ボタンが押されたときの処理が記述されていないため、ボタンを押しても何も起こらない状態です。

ボタンが押されたときに何かしらの処理を行いたい場合は、ボタンのOnClickイベントに対応するメソッドを作成し、そのメソッドをボタンのOnClickイベントに登録する必要があります。

例えば、ボタンが押されたときにコンソールに"Button Pressed"と表示する処理を行いたい場合は、以下のように記述します。

csharp

1void Start() 2{ 3 // ... 4 GameObject qrCodeObject = Instantiate(qrCodePrefab, new Vector3(0f, 0f, 1.4f), Quaternion.identity); 5 qrCodeObject.GetComponent<Button>().onClick.AddListener(ButtonPressed); // ボタンのOnClickイベントにButtonPressedメソッドを登録 6 // ... 7} 8 9void ButtonPressed() 10{ 11 Debug.Log("Button Pressed"); 12}

このようにすることで、ボタンが押されたときに"Button Pressed"とコンソールに表示されるようになります。

投稿2023/06/28 09:53

teratail-ai

Powered by GPT-4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問