概要
HTC Viveのヘッドマウントディスプレイには、フロントカメラが埋め込まれています。
このカメラは、メニュー表示時にカメラを起動し外の状況を確認したり、ゲーム画面自体にオーバーレイで周りの状況を表示して、HMDを脱がなくても色々とできるように、という配慮がなされています。
カメラ自体は通常のWebカメラと違いはないので、Unityからカメラの映像をテクスチャとして取り込み、それを利用することができます。
WebCamTexture
でも取得はできるようなのですが、SteamVRからもAPIが提供されているので、そちらを利用する方法をメモしておこうと思います。
なお、今回の記事はこちらのValveのコードを参考にしています(というかほぼコピー)。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ViveCam : MonoBehaviour { [SerializeField] private bool _undistorted = true; [SerializeField] private bool _cropped = true; [SerializeField] private bool _followTrakking = false; [SerializeField] private Transform _target; [SerializeField] private Material _material; #region ### MonoBehaviour ### private void OnEnable() { EnableSteamVRCamera(); } private void OnDisable() { DisableSteamVRCamera(); } private void Update() { UpdateCameraTexture(); } #endregion ### MonoBehaviour ### private void UpdateCameraTexture() { var source = SteamVR_TrackedCamera.Source(_undistorted); var texture = source.texture; if (texture == null) { return; } _material.mainTexture = texture; float aspect = (float)texture.width / texture.height; if (_cropped) { var bounds = source.frameBounds; _material.mainTextureOffset = new Vector2(bounds.uMin, bounds.vMin); float du = bounds.uMax - bounds.uMin; float dv = bounds.vMax - bounds.vMin; _material.mainTextureScale = new Vector2(du, dv); aspect *= Mathf.Abs(du / dv); } else { _material.mainTextureOffset = Vector2.zero; _material.mainTextureScale = new Vector2(1f, -1f); } _target.localScale = new Vector3(1f, 1f / aspect, 1); if (_followTrakking) { if (source.hasTracking) { var t = source.transform; _target.localPosition = t.pos; _target.localRotation = t.rot; } } } private void EnableSteamVRCamera() { var source = SteamVR_TrackedCamera.Source(_undistorted); source.Acquire(); // カメラが認識されていなかったらdisableにする if (!source.hasCamera) { enabled = false; } } private void DisableSteamVRCamera() { _material.mainTexture = null; var source = SteamVR_TrackedCamera.Source(_undistorted); source.Release(); } }
ポイントは、SteamVR_TrackedCamera
を使って該当カメラを有効化し、さらに有効な場合に、Update
メソッド内で、カメラの映像をTextureとして受け取ってそれを更新する、というものです。
外部カメラからの映像をなにかに使ったり、あるいはゲーム中の安全確保のために、一定距離近づいたら外部カメラ有効化してそれを表示する、みたいな使い方もできるかもしれません。
ということで、使い方を知りたかったのでメモとして書きとどめておきます。