Nreal / 3Dモデル表示と平面検出とコントローラ操作
「Nreal」で「3Dモデル表示」と「平面検出」と「コントローラ操作」を行います。
・Unity 2019.3.0f1
・Unity SDK 1.2.1
1. 開発ツールの準備
「Nreal入門 / HelloMRの実行」と同様です。
2. プロジェクトの準備
「Nreal入門 / HelloMRの実行」と同様です。
3. ユニティちゃんの準備
「ユニティちゃんを操作してみる」と同様です。
4. 3Dモデル表示
3Dモデル表示のみを行います。
(1) ユニティちゃんを配置。
Position = (0, -0.5, 1.5)
Rotation = (0, 180, 0)
(2) 「Directional Light」の配置。
Position = (0, -0.5, 1.5)
Rotation = (0, 180, 0)
(2) HierarchyウィンドウにNRSDK/Prefabs/NRCameraRigをドラッグ&ドロップ。
(3) 「Main Camera」を削除。
ビルドして実行すると、アプリ開始位置の1.5m前に、ユニティちゃんが表示されます。
5. 平面検出
検出できた平面の可視化を行います。
(1) Hierarchyウィンドウで「Empty Object」を生成し、名前に「PlaneDetector」を指定。
(2) ゲームオブジェクト「PlaneDetector」に新規スクリプト「PlaneDetector」を追加し、以下のように編集。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NRKernal;
// 平面検出
public class PlaneDetector : MonoBehaviour
{
// 検出平面のプレハブ
public GameObject DetectedPlanePrefab;
// 現フレームで追跡開始した平面のリスト
private List<NRTrackablePlane> m_NewPlanes = new List<NRTrackablePlane>();
// 更新時に呼ばれる
public void Update()
{
// 現フレームで追跡開始した平面の取得
NRFrame.GetTrackables<NRTrackablePlane>(m_NewPlanes, NRTrackableQueryFilter.New);
// 現フレームで追跡開始した平面の可視化
for (int i = 0; i < m_NewPlanes.Count; i++)
{
GameObject planeObject = Instantiate(DetectedPlanePrefab, Vector3.zero, Quaternion.identity, transform);
planeObject.GetComponent<NRTrackableBehaviour>().Initialize(m_NewPlanes[i]);
}
}
}
(3) コンポーネント「PlaneDetector」の「Detect Plane Prefab」に「NRSDK/Demos/HelloMR/Prefabs/PolygonPlaneVisualizer」をドラッグ&ドロップ。
ビルドして実行した後、床を見渡すと検出された平面が表示されます。
6. コントローラ操作
コントローラを追加し、レイで平面を指しながらTouchpadをクリックすることで、モデルを追加します。
(1) HierarchyウィンドウにNRSDK/Prefabs/NRInputをドラッグ&ドロップ。
(2) ゲームオブジェクト「PlaneDetector」に新規スクリプト「HelloMRController」を追加し、以下のように編集。
using UnityEngine;
using NRKernal;
public class HelloMRController : MonoBehaviour
{
// レイが平面に当たったときに配置するモデル
public GameObject AndyPlanePrefab;
// フレーム毎に呼ばれる
void Update()
{
// Touchpadクリック時に呼ばれる
if (NRInput.GetButtonDown(ControllerButton.TRIGGER))
{
// コントローラのレイの原点の取得
Transform laserAnchor = NRInput.AnchorsHelper.GetAnchor(NRInput.RaycastMode == RaycastModeEnum.Gaze ?
ControllerAnchorEnum.GazePoseTrackerAnchor : ControllerAnchorEnum.RightLaserAnchor);
// レイと平面の衝突判定
RaycastHit hitResult;
if (Physics.Raycast(new Ray(laserAnchor.transform.position, laserAnchor.transform.forward), out hitResult, 10))
{
if (hitResult.collider.gameObject != null &&
hitResult.collider.gameObject.GetComponent<NRTrackableBehaviour>() != null)
{
var behaviour = hitResult.collider.gameObject.GetComponent<NRTrackableBehaviour>();
if (behaviour.Trackable.GetTrackableType() == TrackableType.TRACKABLE_PLANE)
{
// インスタンスの生成
Instantiate(AndyPlanePrefab, hitResult.point, Quaternion.identity, behaviour.transform);
}
}
}
}
}
}
(3) コンポーネント「HelloMRController」の「Andy Plane Prefab」に「NRSDK/Demos/HelloMR/Logo/Models/Mascot」をドラッグ&ドロップ。
レイで平面を指しながらTouchpadをクリックした時に追加するモデルを指定します。
ビルドして実行した後、レイで平面を指しながらTouchpadをクリックすると、モデルが追加されます。