のしメモ アプリ開発ブログ

Unityアプリとかロボットとか作ってるときに困ったこととかメモ

HoloLensにビルド時にエラー

Unityで生成したプロジェクトをHoloLensの実機にビルドする際に下記のエラーがでました。

DEP6701 : Bootstrapping failed with unexpected error: 'Wrong format: Unrecognized date-time format.'

う~ん。よくわからん!

対処法

とりあえずVisualStudioを更新してみることに。

Visual Studio 2015 Update 3をインストーラーをダウンロードしてきて更新します。
この辺をインストール。
f:id:noshipu:20170201050650p:plain

インストール後にビルドしたら直りました。

HoloLens+Unity開発 入力の取得まとめ編

HoloLensが届きました!
こんな感じでVRで作っていた「Makebox」の移植をしてみました。Unityで開発できて、開発環境も揃っているので楽しいですよ!

今回は「HoloToolKit-Unityを使用した入力の取得方法」をまとめてみました。
これができるようになれば、後はUnityのコードをがりがり書くだけで色々な表現ができるようになるはずです。

HoloToolKitの導入はこちらを参照してください。

HoloToolkit-Unity/GettingStarted.md at master · Microsoft/HoloToolkit-Unity · GitHub

以下のオブジェクトがシーンに存在する状態で使用してください

HoloLensCamera.prefab
InputManager.prefab
DefaultCursor.prefab
EventSystem

紹介する機能

機能 モジュール名 コールバックのタイミング
入力 IInputHandler 対象へのInputDown / 対象へのInputUp
クリック IInputClickHandler 対象へのクリック
フォーカス IFocusable 対象とGazeが重なったとき / 対象からGazeが外れたとき
手の検出 ISourceStateHandler 対象を見ている状態で手が認識されているとき / 対象を見ている状態で手が認識から外れたとき
ホールド IHoldHandler 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した
ドラッグ(操作) IManipulationHandler 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキングが外れた
ドラッグ(ナビゲーション) INavigationHandler 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキングが外れた
音声の検出 ISpeechHandler 対象を見ながらしゃべった時のテキストを返す

※ IManipulationHandler、INavigationHandlerの違いについて
Manipulationは空間でものを動かしたり、何か書いたりしている基本的な動かすことに向いている。
Navigationはジョイスティックのようなもので、閾値(-1~1)も設定されているので、UIとかで使ったりするのに向いている。
詳細は下記
https://developer.microsoft.com/en-us/windows/holographic/Gestures.html#manipulation

※「対象」というのはスクリプトとコライダーがアタッチされているゲームオブジェクトを指します。
またSetGlobalListenerを同じオブジェクトにアタッチすることで、どこを見ていてもコライダーをつけずにイベントを発火することが可能です。

概要

それぞれのモジュールを継承することで、任意のコールバックが呼ばれるような仕組みとなっています。
Monobehaviourを継承したら、StartやUpdateが呼ばれるような感じで、Inputの際も定義したコールバックが呼ばれます。

使い方

InputModuleをusing

using HoloToolkit.Unity.InputModule;

使用するモジュールを継承(複数可)

public class InputTest : MonoBehaviour, IInputHandler, IInputClickHandler, IFocusable

コールバックを定義する

IInputHandler

public void OnInputUp(InputEventData eventData)
{
    Debug.LogFormat("OnInputUp\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

public void OnInputDown(InputEventData eventData)
{
    Debug.LogFormat("OnInputDown\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}
IInputClickHandler

public void OnInputClicked(InputClickedEventData eventData)
{
    Debug.LogFormat("OnInputClicked\r\nSource: {0}  SourceId: {1} TapCount: {2}", eventData.InputSource, eventData.SourceId, eventData.TapCount);
}
IFocusable

public void OnFocusEnter()
{
    Debug.Log("OnFocusEnter");
}

public void OnFocusExit()
{
    Debug.Log("OnFocusExit");
}

ISourceStateHandler

public void OnSourceDetected(SourceStateEventData eventData)
{
    Debug.LogFormat("OnSourceDetected\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

public void OnSourceLost(SourceStateEventData eventData)
{
    Debug.LogFormat("OnSourceLost\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

手の検知はあんまり知られてなさそう。仕組み的に指さし->パーの検知ができる。ちょっと何かに使えるかも?

IHoldHandler

public void OnHoldStarted(HoldEventData eventData)
{
    Debug.LogFormat("OnHoldStarted\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

public void OnHoldCompleted(HoldEventData eventData)
{
   Debug.LogFormat("OnHoldCompleted\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

public void OnHoldCanceled(HoldEventData eventData)
{
   Debug.LogFormat("OnHoldCanceled\r\nSource: {0}  SourceId: {1}", eventData.InputSource, eventData.SourceId);
}

IManipulationHandler

public void OnManipulationStarted(ManipulationEventData eventData)
{
    Debug.LogFormat("OnManipulationStarted\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnManipulationUpdated(ManipulationEventData eventData)
{
    Debug.LogFormat("OnManipulationUpdated\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnManipulationCompleted(ManipulationEventData eventData)
{
    Debug.LogFormat("OnManipulationCompleted\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnManipulationCanceled(ManipulationEventData eventData)
{
    Debug.LogFormat("OnManipulationCanceled\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

INavigationHandler

public void OnNavigationStarted(NavigationEventData eventData)
{
    Debug.LogFormat("OnNavigationStarted\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnNavigationUpdated(NavigationEventData eventData)
{
    Debug.LogFormat("OnNavigationUpdated\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnNavigationCompleted(NavigationEventData eventData)
{
    Debug.LogFormat("OnNavigationCompleted\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

public void OnNavigationCanceled(NavigationEventData eventData)
{
    Debug.LogFormat("OnNavigationCanceled\r\nSource: {0}  SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}",
        eventData.InputSource,
        eventData.SourceId,
        eventData.CumulativeDelta.x,
        eventData.CumulativeDelta.y,
        eventData.CumulativeDelta.z);
}

ISpeechHandler


使用される単語をどれか一つのオブジェクトにあらかじめ登録しておく必要があります。
SpeechInputSourceを任意のオブジェクトにアタッチし、単語を登録する。
f:id:noshipu:20170128041538p:plain

public void OnSpeechKeywordRecognized(SpeechKeywordRecognizedEventData eventData)
{
    Debug.Log(eventData.RecognizedText.ToLower());
}

最後に

これでインタラクションコンテンツが作れるようになるのではないでしょうか。
また、間違った記載がありましたら、コメントやTwitter等でご指摘ください。

VRアプリ「Makebox」をリリースしました!

VR空間で3Dモデリングを簡単に行えるVRアプリをOculus Storeでリリースしました!
直感的な操作で簡単に3Dモデルの制作をすることが可能です。

Oculus Storeのダウンロードリンクは以下から
https://www.oculus.com/experiences/rift/1569582573068780/

特徴

■ 3Dモデリングを簡単にできる

VR空間で積み木感覚で直感的に3Dモデリングが可能です。

■ 作ったモデルをWebに共有できる

Makeboxで制作した3DモデルをアプリからWebにアップロードすることが可能です。
アップロードしたモデルは簡単に共有でき、モバイルVRで見ることもできます。

MakeboxのWebサイトはこちら:
https://make-box.com

■ 3Dモデルをファイルに書き出しできる

作ったモデルをobjファイルとして書き出し、他の3Dモデリングツールで編集可能!「Unity」や「UE4」のゲームエンジンにそのまま取り込んで使用することもできます。

Unityに取り込む動画:

UE4に取り込む動画:

もちろん、書き出したモデルを3Dプリンタで印刷することも可能です。
誰でも簡単にモデリングができるので、プロトタイプの作成に向いています。

■ 毎日お題が更新される

毎日変わるお題に挑戦することができます。
作りたいものがなくても、気軽にお題に沿った3Dモデルを作れます。
もちろん。自由に3Dモデリングを楽しむこともできます。

アプリ概要

アプリ名: Makebox
価格: $9.99
対応機種: Oculus Rift CV1, Oculus Touch
Oculus Store:
https://www.oculus.com/experiences/rift/1569582573068780/

Makebox公式サイト:
https://make-box.com

ViRD公式サイト:
http://vird.co.jp


ぜひぜひダウンロードして使ってみてできたらフィードバックください!

2016の振り返りと2017年でやりたいことメモ

年明けましたね。あけましておめでとうございます。
2016年に作っていたものとか、大きめな買い物とかをふり返ろうと思います。

2016

1月

・GearVR + GalaxyS6edge購入

2月

3Dプリンタ買う

・沖縄のハッカソンのコーチ役的なポジションで行ってきた

・UnityVRの勉強がてら、PRIME BIRD作り始める
OcuFesで展示する

楽天声優ハッカソンにでる
Live2Dのキャラクターがしゃべってくれるみたいなやつを出す。
東芝賞とUnity賞をもらう。

3月

・お仕事でTHETAアプリリリース

・「cluster.」でLTする(VR内での初講演)

・ロボットハンド作りはじめる

4月

・VRで遠隔で操作できるロボットを作り始める
VRCアワードに提出、一次選考は通過する。

・GearVRアプリ「PRIME BIRD」リリース

5月

・ロボットハンドを調整
・Live2Dアプリ「NURIEW」を開発開始

6月

・OculusRift CV1がやっと届く

・Japan VR Hackathon
JAPUZZLEを作り、NEURONグローブ賞もらう

・Live2D Awardの作品「Live2Dロボ(仮)」を公開

・Live2D Awardの作品「 NURIEW」を公開

7月

・結婚!
高校の頃から付き合ってるデザイナーさんと入籍する。
結婚式はVR / AR絡めてなにかやりたい。

・起業!
2016年7月1日に株式会社ViRDを設立する。未だに社員は1人の模様。
http://vird.co.jp/
VR技術で世界をIntegrationするようなプロダクトを作りたいと思って設立したものの、色々作って迷走なような。

・Live2D Award 2016でクリエイティブ賞を受賞
かっこいい盾もらった!

・SPAJAMで前年度優勝者として参加
一人ハッカソンでGearVRとGoogle Translation APIを使った自動翻訳機みたいなの作る。
codeiq.jp

・HTC Viveの購入

・Unity VR ExpoにViveアプリの「LABOTA」を出展
Good Contentsで4位という結果に。(Vive購入から10日で、作って展示してる…)

・Gear360購入

・Gear360をUnityで動かすネタを書く

・Japan VR Hackathonの賞品のNEURONが届く


8月

・MakerFaireに「LABOTA」を展示

9月

・THETAアプリ「VANISH360」のリリース

10月

・ちょっとした展示が辛くてゲーミングノート買う
GS43VR (画像はおまけのブロック)


11月

・「VANISH360」がTHETA Developersコンテストで賞もらう

・Oculusアプリケーションの「Makebox」を開発開始

12月

・Oculus Touchが届く

・OculusTouchアプリの「Makebox」のアルファテスト開始

・熱海の温泉開発合宿で締め

2017年の目標

2016年は模索や、試しや、起業、結婚など、身を固める感じだったので、今年は攻めていきたい。
具体的には、
・Makeboxで10万人のユーザー数を集める
・自社アプリで1億の売り上げを出す
・VRコンテンツ開発会社として知られる企業になる

2016年はふらふらしてたけど、Makeboxに集中してがんばるぞー!