Academy Holograms 101のスクリプトについての(ほぼ自分用の)メモ書きです。
・WorldCursor.cs
Gazeを可視化し、Gazeの先にオブジェクトがあればカーソルの形状を変化させる、というものです
using UnityEngine; public class WorldCursor : MonoBehaviour { private MeshRenderer meshRenderer; // Use this for initialization void Start() { // Grab the mesh renderer that's on the same object as this script. meshRenderer = this.gameObject.GetComponentInChildren<meshRenderer>(); } // Update is called once per frame void Update() { // Do a raycast into the world based on the user's // head position and orientation. var headPosition = Camera.main.transform.position; var gazeDirection = Camera.main.transform.forward; RaycastHit hitInfo; if (Physics.Raycast(headPosition, gazeDirection, out hitInfo)) { // If the raycast hit a hologram... // Display the cursor mesh. meshRenderer.enabled = true; // Move the cursor to the point where the raycast hit. this.transform.position = hitInfo.point; // Rotate the cursor to hug the surface of the hologram. this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal); } else { // If the raycast did not hit a hologram, hide the cursor mesh. meshRenderer.enabled = false; } } }
まず、カーソルは通常状態とヒット状態(オブジェクトに視線が当たっている状態)の2つの形状を親子関係にしていて、通常は子のヒット状態は見えないようになっています。見える/見えないというのは、MeshRendererの有効/無効、に対応しているので、子のMeshRendererを取得しています。
そしてUpdate()内で、視線の先にオブジェクトがあるか判定します。
HoloLensは、装着しているユーザーの位置=カメラの位置、になり、視線の向き=カメラの向き、になります。VR/MRらしい考え方で楽しいですね。それぞれheadPosition、gazeDirectionに格納します。
判定は、Physics.Raycastを使用します。これはHoloLensに限らず、Unity 3Dで当たり判定をするときの常套手段で、「レーザービームを撃って当たったか確かめる」イメージになります。
シーンにあるすべてのコライダーに対して、 origin の位置から direction の方向に maxDistance の距離だけレイを投じます。
そして、カーソルを面に合わせて回転させています。hitInfoからは、当たり判定が発生した場所の面の傾きを得ることができますので、カーソルもそれと同じように回転させています。
レイキャストによる情報を得るための構造体
実際にToolkitに入っているCursorプレファブは、ObjectCursor.cs内で更にGazeManagerを使って上記のことを行っているのでけっこう複雑なのですが、読む手がかりにはなるかと思います。