HoloLens 用 Toolkit で注視した対象を半透明のフォーカス状態にする
※ これは 2016/08/05 Unity HoloLens Technical Preview ver.5.4.0f3(Windows版) 時点の情報です
最新版では動作が異なる可能性がありますのでご注意ください
前回 は HoloToolkit で注視位置を表すカーソルを表示してみました
今回はさらに注視されていてカーソルが当たっているときに、フォーカスしていることがわかりやすいように対象を半透明にする実装を試してみたいと思います
まずは準備として Project の Assets フォルダ直下から [Create]-[Folder] のコンテキストメニューを選び、3つのフォルダを追加します
フォルダ名はそれぞれ 「Materials」「Scenes」「Scripts」という名前*1にしておきます
現状のシーン状態を保存するため、[File]-[Save Scene as...] のメニューを開き、Assets/Scenes に「Main」という名前でシーンファイルを保存します
このシーンファイルを作っておかないと、Unity Editor を終了した時に作業状態が保存されないのでご注意
次に Project の Assets/Materials フォルダ直下で [Create]-[Material] のコンテキストメニューを開き、「Panel」という名前でマテリアルを追加します
このマテリアルは GameObject に色や柄をつけるために表面に貼り付けるようなものになります、
作ったマテリアルは Rendering Mode を「Fade」にし、Main Maps の Albedo の色として #99CC66FF の緑色を指定しておきます
Rendering Mode を「Fade」にしないとこの後の手順通りにしても半透明にならないのでお忘れなく
マテリアルの設定が終わったらこれを Hierarchy 上の Panel に向けてドラッグドロップしてアタッチします
これで Panel の見た目が緑色になりました
ここまで終わったら注視された際の動作を記述するためスクリプトを追加します
Project の Assets/Scripts フォルダ直下に [Create]-[C# Script] のコンテキストメニューを開き、「TargetPanel」という名前で cs ファイルを追加します
スクリプトファイルを作ったらこれも Hierarchy 上の Panel に向けてドラッグドロップしてアタッチしておきます
コードの中身はこんな感じ
using UnityEngine; /// <summary> /// 注視対象となるパネル(Quad) /// </summary> [RequireComponent(typeof(Renderer))] [RequireComponent(typeof(Material))] public class TargetPanel : MonoBehaviour { /// <summary> /// パネルのレンダラー /// </summary> private Renderer meshRenderer = null; /// <summary> /// パネルのマテリアル /// </summary> private Material defaultMaterial = null; /// <summary> /// 初期処理 /// </summary> public void Awake() { this.meshRenderer = this.GetComponent<Renderer>(); this.defaultMaterial = this.meshRenderer.material; } /// <summary> /// 注視(フォーカスイン)イベントハンドラ /// </summary> /// <remarks> /// インタフェースや抽象型の継承として記述しない理由は、パフォーマンスのオーバーヘッドを軽減するためらしい /// </remarks> public void OnGazeEnter() { var color = this.meshRenderer.material.color; this.meshRenderer.material.color = new Color(color.r, color.g, color.b, 0.6f); } /// <summary> /// 注視はずれ(フォーカスアウト)イベントハンドラ /// </summary> /// <remarks> /// インタフェースや抽象型の継承として記述しない理由は、パフォーマンスのオーバーヘッドを軽減するためらしい /// </remarks> public void OnGazeLeave() { var color = this.meshRenderer.material.color; this.meshRenderer.material.color = new Color(color.r, color.g, color.b, 1f); } }
Awake() メソッドは Unity の暗黙的な最初に呼び出される初期化用メソッドで、OnGazeEnter()、OnGazeLeave() メソッドは HoloToolkit の暗黙的なイベントハンドラです
こういったメソッド名しばりの暗黙的なルールは間違うと機能しなくなるので危ういのですが、Unity 的にはパフォーマンスのオーバーヘッドを軽減するという理由でインタフェースや抽象型などの明示的な規約化をとっていないようです
やっていることは Panel オブジェクトの Renderer から Material をとってきて色を半透明にしたり、不透明に戻したりしているだけです
とにもかくにもビルドしてお試し実行
ちゃんと注視しているときだけ半透明になりました!
*1:Unity ではファイルの種類ごとに ~s というフォルダを Assets 直下に作り整理する習慣があるようです