Swampdog part21 -Raycastで名称取得-

はじめに

これまで以下の機能を実装してきました。

  • カーソルを作成
  • カーソルに骨を認識させる
  • ラベルを作成
  • ラベルが視界内に収まるようにする
  • ラベルがこちらに正対するようにする

 

今回はラベル内のテキストをカーソルが当たったオブジェクトの名称に置き換えることを目指します。

 

デバッグ機能の確認

ここからは値が取得できているか確認しながら進めたいので、デバッグ機能について勉強します。

 

とりあえず、適当なスクリプトを「Assets -> Scripts」に作ります。

DebugTestとでも名付けます。

using System.Collections;
using System.Collections;
using System.Collections.Generic;using UnityEngine;
public class DebugTest : MonoBehaviour {
 // Use this for initialization
 void Start () {
        Debug.Log("debug worked");
 }
 // Update is called once per frame
 void Update () {
 }
}

これだけ。

 

適当にDebugManagerでもCreate Emptyで作成してスクリプトを当てます。

エミュレータを起動して確認。

取れているみたいですね。

 

RaycastHitからコライダーの名称を取得

Raycastでは視線がコライダーにヒットすると、hitInfo(RaycastHitクラス)の中にコライダーに関する情報が格納されます。

 

まずはコライダーの名称をデバッグで取得してみます。

Unityってどのオブジェクトにスクリプトを当てるか決まりあるんですかね?

RayCastからのコライダーを取得するスクリプトはCursorに適用するのが自然だと思いますが、その後Labelのテキストを書き換えるのはどうすれば?

 

とか考えながら。

調べていたらコライダーがアタッチされているオブジェクトの名前が取れそうでした。

これでコライダーが適用されているオブジェクトの名称を取得できるかなとテスト。

 var objectName = hitInfo.collider.attachedRigidbody.name;
 Debug.Log(objectName);

 

Visual StudioのHoloLensエミュレータを起動。

「出力」からデバッグメッセージを確認。

debug workedは確認できましたが、

 

それ以降は延々と以下のエラー。

Exception thrown: 'System.NullReferenceException' in Assembly-CSharp.dll
NullReferenceException: Object reference not set to an instance of an object.
 at WorldCursor.Update()
 at WorldCursor.$Invoke6Update(Int64 instance, Int64* args)
 at UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64* args, IntPtr method) 
(Filename: <Unknown> Line: 0)

 

調べたら似たような記事を発見。

 

varかstringかの違い?それは関係ないか。

それよりもRaycast()でTrueの時に実行しているはずなのにSystem.NullReferenceExceptionが発生している。

attachedRigidbodyの使い方が怪しい。よく考えたらリジッドボディは設定していないはず。

修正。

 var objectName = hitInfo.collider.gameObject.name;
 Debug.Log(objectName);

 

オブジェクト名取得できました。

同じ名前のが多いのでわかりにくいですが、カーソルが別の骨に当たったらちゃんとそいつの名前を取得しているようです。

 

親のオブジェクト名取得

親子関係は以下のような形です。

欲しいのは「grp1」ではなくその上の「肋軟骨l1」です。

 

先ほどのコードを親のオブジェクト名取得に変えます。

 var objectName = hitInfo.collider.gameObject.transform.parent.gameObject.name;
 Debug.Log(objectName); 

 

親子関係についてはここら辺を参考にしました。

 

カーソルが当たっている部位の名前が取得できました。

 

次はラベルのテキストをこの名称で置き換えます。

 

テキストの置換

以下の記事を参考にしました。

 

こんな感じでカーソルから目的のオブジェクト名を取得して書き換えてみます。

できるといいなぁ。

using UnityEngine;

public class ReplaceLabel : MonoBehaviour {
  GameObject cursorObj;
  // Use this for initialization
  void Start () {
    cursorObj = GameObject.Find("Cursor");
  }

  // Update is called once per frame
  void Update () {
    WorldCursor wc = cursorObj.GetComponent<WorldCursor>();
    GetComponent<TextMesh>().text = wc.objectName;
  }
}

 

エミュレータで確認。

 

できました。

 

次回

次回はこのラベルをAir Tapしたときに詳細説明が表示されるようにします。

今日はよい感じに開発できました。満足。

 

余談ですが、アイキャッチが代わり映えしない。。。

コメントを残す