athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

HoloLensで新しいオブジェクトを生成してみる

こんにちは、情報システム部の高野です。
前回は、起動時にすでに存在するオブジェクトへの操作を試しましたが
今回は、新しくオブジェクトを生成する方法を試してみました。

前回の「カメラを変更する」までは手順は同じなので省略します。

カーソルとジェスチャーの設定をする

前回と同様ですが、InputManagerDefaultCursor
Hierarchyウィンドウにドラッグ&ドロップしておきます。
ここまででHierarchyウィンドウは下図のようになります。
f:id:taktak1974:20170515114532p:plain

3Dオブジェクトのプレハブを用意する

新しいオブジェクトを生成するには生成元のプレハブを作成しておく必要があります。*1
Hierarchyウィンドウの「Create」メニューから
「3D Object」→「Cube」を選択します。
InspectorウィンドウでScaleをすべて0.1に変更しておきます。

オブジェクトに色を付ける

ProjectウィンドウのAssetsフォルダにMaterialsというフォルダを作成します。
Materialsフォルダ内で右クリックし「Create」→「Material」を選択します。
今回は名前をGreenにしInspectorウィンドウの「Albedo」を緑っぽくしておきます。
作成したMaterialをHierarchyウィンドウ内のCubeにドラッグ&ドロップします。

オブジェクトに重力を与える

Cubeを選択した状態でInspectorウィンドウを開きます。
「Add Component」ボタンをクリックしRigidbodyを検索して選択します。

プレハブ化する

ProjectウィンドウのAssetsフォルダにPrefabsフォルダを作成します。
作成したPrefabsフォルダにHierarchyウィンドウからCubeをドラッグ&ドロップします。
これでCubeプレハブが作成されました。
HierarchyウィンドウからはCubeを削除しておきます。

動的に3Dオブジェクトを生成する

空のGameObjectを作成する

Hierarchyウィンドウの「Create」メニューから「Create Empty」を選択し空のGameObjectを作成します。
作成したGameObjectは名称をObjectManagerに変更しておきます。

オブジェクト生成用のスクリプトを作成する

ProjectウィンドウのAssetsフォルダにScriptsフォルダを作成します。
作成したScriptsフォルダの中にC#Scriptを作成し名称をObjectManagerに変更します。
作成したObjectManagerスクリプトObjectManagerオブジェクトに関連付けます。
(ドラッグ&ドロップでもInspectorからAdd ComponentでもOKです)
InspectorウィンドウでObjectManagerスクリプトを右クリックし「Edit Script」でVisualStudioを起動します。
コードを以下のように変更します。

using HoloToolkit.Unity.InputModule;
using UnityEngine;

public class ObjectManager : MonoBehaviour, IInputClickHandler
{
    public GameObject obj;

    private void Start()
    {
        InputManager.Instance.PushFallbackInputHandler(gameObject);
    }

    public void OnInputClicked(InputClickedEventData eventData)
    {
        var pos = Camera.main.transform.position;
        var forword = Camera.main.transform.forward;

        Instantiate(obj, pos + forword, new Quaternion());
    }
}

Instantiateメソッドで指定したオブジェクトを生成することができます。
生成する座標はどの向きを向いていても目の前に落としたかったので
上記のようにしてみました。
(もっといい方法もあるのかもしれませんが、Unity力0なので分かってません。)
このままではフィールドobjがnullのままなのでUnityに戻って設定します。
InspectorウィンドウにObjectManagerを表示します。
ObjectManagerスクリプトに「Obj」というプロパティが増えていると思います。*2
f:id:taktak1974:20170515134246p:plain
そこに作成しておいたCubeプレハブをドラッグ&ドロップします。
下図のようになります。
f:id:taktak1974:20170515134353p:plain


最後に床が検知できるようにSpatialMappingHierarchyウィンドウにドラッグ&ドロップします。
ここまでできたらビルドして実行してみましょう。
※ビルドから実行の流れも前回の記事を見てください。

うまくいっていればAirTapするとCubeが目の前に現れて下に落ちます。
こんな感じで足元にCubeが散らかります。
f:id:taktak1974:20170515143411j:plain

ちょっと動きを付けてみる

このままだと目の前にオブジェクトが生成された瞬間に下に落ちてしまいます。
ちょっと味気ないので少し改良してみます。

UnityでCubeプレハブを選択しInspectorウィンドウを開きます。
現状、Rigidbodyの「Use Gravity」にチェックが入っているので外します。
ProjectウィンドウのScriptsフォルダにCubeManagerというC#スクリプトを作成します。
CubeプレハブのInspectorで「Add Component」からCubeManagerスクリプトを選択します。
スクリプトをVisualStudioで開いて以下のように変更します。

using System;
using UnityEngine;

public class CubeManager : MonoBehaviour
{
    DateTime? createTime;

    // Use this for initialization
    void Start()
    {
        createTime = DateTime.Now;
    }

    // Update is called once per frame
    void Update()
    {
        if (createTime != null)
        {
            if ((DateTime.Now - createTime.Value).Seconds > 1)
            {
                GetComponent<Rigidbody>().useGravity = true;
                createTime = null;
            }
            else
            {
                var qua = gameObject.transform.rotation;
                qua.z += 0.1f;
                gameObject.transform.rotation = qua;
            }
        }
    }
}

1秒間は目の前に浮いているようにしています。
浮いている間は、z方向に回転します。


最終的にはこのような感じになります。

20170515holo


今回は以上です。
次回はできればオブジェクトを掴んで移動に挑戦したいです。(できればね)



弊社ではエンジニアを募集しています。
興味がある方は下記からエントリお願いします。
athome-inc.jp

*1:他の方法もあるかもしれませんが、今のところこの方法しか分かっていないです

*2:VisualStudioで保存しておかないと表示されないので注意が必要です