LotosLabo

プログラミング技術とか気になった情報を載せていきます

UnityからSafariViewを表示させる

Appleさんから外部ブラウザへ飛ばさないように。
WebViewかSafariViewで表示してくれ!
と来ていたので、試してみました。

◆ SafariViewってなに?

iOS9から使用できるWebViewの機能を持った、アプリ内からWeb画面を表示できるもの。
Safariブラウザとの見た目の違いは、完了ボタンがついたり、Urlが変更できないことぐらい?


◆試してみる

まず今回やることとしては、iOS9未満ではSafariViewが使用できないので、外部ブラウザで表示します。
iOS9以上はSafariViewを表示するものとしていきます。

また、Unity上でApplication.OpenURL(ブラウザで指定したURLを開く処理)を呼んだ際に、
iOSのネイティブ側でフックする処理があれば、iOS9のときは自動でSafariViewに飛ばすよという処理を書けたのですが、
見つからなかったので、Unityとネイティブでごにょごにょ書いていきました。


今回やったことのまとめです。

1.iOSネイティブ側でSafariViewを表示する処理を記述
2.iOSネイティブ側でSafariViewをUnity側から呼び出す処理を記述
3.Unity側でiOS9以上のときはネイティブからSafariViewを表示する処理を呼び出す、それ以外は通常のOpenURLを呼ぶ


以下、サンプルコードです。



【Unity側】


ボタン押したときに指定したURL(Googleさん)を開くようにしています。
iOSのバージョンですがUnityのAPIからでは、バージョン入りの端末名のみしか取れず、
確かiOSのバージョンによって名前が異なっていたような気がしたので、
ネイティブからiOSのバージョンを取得する処理を書いて呼び出しています。

f:id:lo25131:20170621035313p:plain:w300



iOS側】


※SafariViewを表示するにあたり、フレームワークも必要となるので
Unity上でSafariViewClass.mmを選択して、Framework dependenciesから
Rarely used frameworksのSafariServicesにチェックを入れてください。


見た目こんな感じ(iPad
f:id:lo25131:20170621040422p:plain:w600



◆まとめ

アプリ内から外部ブラウザへ誘導させるような挙動はAppleさんからNGとされているので、
WebViewで表示するか、iOS9以降であればSafariViewでの表示が推奨とされているようです。
今回 Unity Safariviewとかで検索しても出てこなかったので、記事を書かせていただきましたが、
少しでも参考になってもらえるとありがたいです。

また、今回iOSのネイティブ処理を書くのが初めてだったので、
ここはこうした方がいいとかあればご教示いただけると幸いです。


VRZONEに行ってきました

f:id:lo25131:20160609211641p:plain


今回体験したのは、4つ。
順番に脱出病棟、高所恐怖症体験、アーガイルシフト、スキーロデオ


まずVRZONEに入ると、Suicaのチャージ機のような機械がお出迎えしてくれました。
f:id:lo25131:20160609212029p:plain


VRZONEではコンテンツを体験するためにバンダイナムコポイント(バナポイント)が必要になります。
そのため、ポイントをチャージするカードとポイントをチャージしてからようやく体験することができるのです。

今回も多くの方がこの機械を利用されていて列ができていたので、VRZONEに行く前にあらかじめ、
バナパスポートカードとバナポイントをチャージして置くことをおすすめします。
カードはゲームセンターなどでも販売しています。



【脱出病棟】

f:id:lo25131:20160609212728p:plain


ホラー系のVRコンテンツ


今回は4人で体験してきました。
椅子に座りながらレバーの操作で、車いすを操縦させ病棟を脱出していくのですが、
椅子に座ってることもあり前から来てもほぼ逃げれない状態でした。


最初に脱出ルートを選び道順に沿って前進していくのですが、
所々に人をギコギコしちゃってる人や、死体袋?がぶら下がってたりと
心臓バクバクさせながら、いつ襲ってきてもいいように待ち構えてました。

しかし、いざ来るともう叫ばずにはいられない。
おっさん4人で叫びまくってました。

右手に懐中電灯を構えているのですが、これが唯一の心強い味方で、
流石に途中で点かなくなったりしないよな と少し不安になりながら
もブルンブルン振り回してました。

個人的に一番怖かったところとしては、曲がり角やドアを開ける瞬間でした。
来るとわかってるんですが、思わず腰を引いてしまうほどの怖さでした。

最終的に脱出付近まで行ったんですが、
最後の最後でゲームオーバーになってしまいました。
あの引っ掛けは酷いです…


体験していて所々見渡してみたのですが、解像度はバリバリ高いって感じではないですが、
光の明暗をはっきりさせていて、音や周りの雰囲気にこだわっていた気がします。
また敵のギコギコアニメーションも必見です。

ただ少々最初の説明の文字がボヤケていたかなと感じました。


終わった後一時間ぐらい心臓バクバクしてました…



【高所恐怖症】


f:id:lo25131:20160609221106p:plain


高所体験を味わうコンテンツ

上空200mにある板の上を歩いて、猫を救います。
ただこの板が普通に歩いてもグラグラするので、VR内でその上を歩こうとすると
バランスをとることすら難しくなります。

ただ私自身高所恐怖症ではないので、
それほど怖さと高いところにいるんだなとは感じませんでした。
あまり下を見ずに体験しなかったというところもあるかもしれません。

そもそも最初にここの上を渡っているんだなと自覚してしまったため、
怖さがかなり激減してました。
怖さというより、バランスを取ることだけに集中してました。



このコンテンツではプレイヤーが動くため、機器のコードが絡まないようにと
スタッフの方がせっせせっせとコードを移動したりしながらやっていました。
ただ、たまにプレイヤーに触っちゃってる時があるので、それは気をつけて欲しいところです。


猫に関しては、リアルではこれ。
f:id:lo25131:20160609223329p:plain


ですが、VR内ではちゃんとした猫でした、
ただ早く振り回すとトラッキングが遅れてトランザム状態になってました。


4人共無事に渡り切ることができてしまったので、
落ちるシーンを見ることができなくて残念です。




【アーガイルシフト】

ロボゲー

f:id:lo25131:20160609225107p:plain


コックピット中の視点から、ロボットを操作して敵を撃退するゲームです。

操作としてはロボット自身を前進後退はできないものの、専用の椅子に取り付けられている
二つのレバーで銃を動かして、ボタンを押すことで射撃ができます。

f:id:lo25131:20160609230343p:plain


このコンテンツで一番魅力的だったのは、隣に座ってるアイネちゃんというパートナーの女の子でした。
ものすごく近いところまで近づいてくるので、実は触れるんじゃないだろうか。と
胸の近くに手を伸ばしてみましたが、無理でした。


ゲームとしては、敵に対してレバーのボタンを押して射撃するのですが、
ロックオンマーク?がどの敵にもついてて、誘導弾なのかとおもいきや
自分で狙わなくてはならなくて、目の前にきて爆破というのが多かったと感じました。

また、コックピットの中をよく見せるため、視点の大半がコックピットとアイネちゃんなので、
その隙間の窓から敵を覗いて撃つというのは正直難しいところがありました。

シューティングを楽しむというよりは、アイネちゃんをみて楽しむのが目的なのかも…


全体的にですが、FPSが少しだけ低いのかなと…
首を左右に振ってみましたが多少ですが遅延を感じました。
またコントローラーの入力からの動きにも結構な遅延があったため改善していって欲しいところです。


ナレーターのおねぇさんが美人でした。
声がよかった。ほんとうに



【スキーロデオ】

スキーゲー

f:id:lo25131:20160609231942p:plain


実際にスキーをしているかのように感じるゲームです。


ダイエットマシンのスカイウォーカーみたいなものに乗って、
足を左右に動かすことで左右に方向の切り替えをしながら、斜面を滑っていきます。


壁や崖から落ちずにずっと滑っていると、かなりのスピードが出てとても疾走感がありました。
また、前から風が送られてくることで、本当にスキーをしている感じがあります。

ただ操作がとても難しく、思うように曲がってくれないのでみなさん壁にぶつかったり、
崖から落ちまくってるようです。
ちなみに私はクリアしました。

今回体験した中では、ゲームをやってるという感じが一番出てました。
繰り返しやってもっと難しいステージとかにも挑戦してみたいです。



まとめ

全体的にクオリティが高く、これはお金を払っても十分なコンテンツだったと思います。

ただ一つ、回転率を上げるためか機器を装着して調整する時間もスピーディに行っているため、
人によっては機器に設定されているIPDと自分のIPDが合わず、ぼやけたまま体験している方がいました。

その少しのぼやけがVR酔いにも繋がる恐れも無きにしもあらずなので、
装着の時にはスピーディかつ丁寧に、また、体験者がぼやけたまま体験をさせないようにも
何らかの対策が必要だと思います。

最後に、ホラーゲームが苦手な方は脱出病棟はオススメできません。
後から身体の節々が痛くなります。

Unity5.3.5だとGoogleVRSDKでuGUIが表示されない件

Unity5.3.5、5.3.4p6でuGUIのUIを表示しようとしたのですが、うまく表示されません。

前のバージョンの現在確認できたところでUnity5.3.4p1、Unity5.3.4では表示されました。

一応、Stereo ControllerのUpdate Streo Cameraをクリックすると一瞬表示はされます。
原因がいまいちわからないので、とりあえず表示されるバージョンを使ってきましょうか。

Unityでジェスチャーによる文字・形の認識

Unityでマウスジェスチャーによる文字や形の認識する方法を探してみました。

要はこういうこと。


f:id:lo25131:20160224010559p:plain

お絵かきした形や文字を認識して、文字として出力させたい。


1.「Gesture Recognizer」

f:id:lo25131:20160224005329j:plain
https://www.assetstore.unity3d.com/jp/#!/content/47326


AssetStoreで販売されている、マウスジェスチャによって形を認識するAssetです。
あらかじめ認識しておきたい形を記録しておき(座標情報など)、
そのデータを基づいて形を認識しています。


使ってみた感想としては、形、文字両方の認識を行ったのですが、
形に関しては書き始めの位置があっていれば、高確率で正しく認識されました。
ただ、文字(今回は数字を認識)に関しては、似たような形が多いせいか、
誤認識がよく見られました。

もし、ゲームなどに導入するときには、これは音声認識でもそうだと思いますが、
認識精度を上げるために検出可能なジェスチャーを少なくしておくことをおすすめします。

紹介させていただいたのはサンプルのゲーム付きの方ですが、スクリプトのみの方も
AssetStoreで配信されています。

サンプルのコードをそのまま用いればすぐコンテンツへの導入も可能なので、
是非試してみてください。$15の価値はあると思います。




2.「手書き文字認識API


Docomoさんで紹介されている手書き文字認識APIです。
文字の筆跡データをもとに、文字を認識します。


一文字のみの認識となります。
認識にはHTTP通信でXML/JSONで取得が可能です。



【利用方法】

PUXさんのデベロッパーサイトにて登録を行い、
APIキーを発行します。
ユーザ登録時に、評価版APIキーを発行するかどうか聞かれるので、その時に発行します。



ユーザ登録後、APIキーとドメイン名がメールにて届くので、
それを基に通信を行います。

APIの詳しい利用方法については、Docomoさんのデベロッパーサポートサイト
に記載されていますので、そちらをご参照ください。


実際に使用してみた感想としては、送るパラメータによって、
認識して欲しい文字を絞れるので、欲しい情報をより正確に取得することができると思います。
すこし雑に書いたとしても認識してくれるので精度は結構高いと思います。

しかし、オンライン環境でしか動作しないところがネックですね…




まとめ


上記で紹介した二つは、AndroidiOSの両方の環境で動作することも確認できました。
ただスマホタブレット手書きとなると、正確に文字を書くコンテンツを開発するとなると
ユーザはペンと大きい画面を有したタブレットが必要になってきますね。

今回はUnityで3DSでの開発ができるようになる?!という情報があったので、
Unityで手書き認識を試してみました。この技術を用いて脳トレや学習アプリ的なものを作ってみたいですね。


参考にさせていただいたサイト様


ユニティちゃんを自由に喋らせた

はじめに

こんなの作りました。




昨年12月に提供が開始された「VOCALOID SDK for Unity」を使用して作ってみました。

テキストボックスに入力された文字列を取得して、リアルタイムで合成して発声させています。
また、文字列の母音を取得して、SDユニティちゃんにリップシンクさせるようにしています。

開発にあたって

まず公式で公開されているSampleProjectを参考に、自分で発声させたい音声を決めて、
Playback合成RealTime合成を行ってみました。
そこからリファレンスを眺めたり、試しに卑猥な言葉も喋らせたりもしてみました。

また、声高を変えて歌わせてもみた(うまくいってはいない


そしてこれを使って何かゲームを作れないかと考えてみたのですが……



思いつかない。。




とりあえず音ゲーかなと思ったのですが、リアルタイムの魅力をどこに引き出すのか?
と疑問に思って考えるのをやめました。

で、そんなときにとあるリプライを頂きました。



これだ!!
Unityちゃんをデスクトップに置いて、
言葉(卑猥な言葉)を自由に喋らせるようにできれば…


開発開始!


とりあえずSDUnityちゃんを用意して、アニメーション、リップシンク、瞬きを行うようにしました。

次にテキストの入力部分についてですが、ユニティちゃんが喋れるのはひらがなだけです。
例えば、漢字、英語、記号といった文字はうまく発音してくれません。


その対策としてまずは根本から、uguiのテキストボックス(Input Field)でContent Typeを「Name」に設定しました。
これで日本語とアルファベットしか入力できなくなりました。


次に漢字に関してですが、こちらについては別途記事にて紹介させていただきました。


lo25131.hatenablog.com


このAPIを使うことでひらがなに変換することが可能になりました。


もちろんこれだけではうまく発音してくれません。

「きゃきゅきょ」のような文字は、文字数として、6文字ですが
実際に発音するときは「き」と「ゃ」を一緒に含めて発音するため、発音数は3文字となります。
その影響で合成発音時にズレが生じて最後に余って発音されてしまいました。

また同様に「っ」のような文字も実際に発音しないので、これも発音カウントに含めてはなりません。


このような対策も含めて3日(1日2時間)ぐらいで完成しました。



まとめ

YoutubeではUnityの環境から撮影したものですが、DeskTopMascotMakerを使用することで、
DeskTopにSDUnityちゃんを配置して、入力した言葉を喋れるようにすることに成功しました。

しかしまだ当然満足はいっていません
夢はAIアバターの作成…


とりあえずこの2週間ほどVOCALOID SDK for Unityをずっと触ってましたが、
実際にUnityで曲を作るとなると、やはりVocaloidDTMの知識が必要となってきます。
また現時点では歌詞のノートへの追加がすべてプログラムで行うので、かなり手間がかかります。

もういっそのことUnity内でVocaloid Editor作ろうかなとも考えたのですが、それは時間があったときに作れればいいなと

ライセンス


f:id:lo25131:20140607195201p:plain

このコンテンツは、『ユニティちゃんライセンス』で提供されています。


本コンテンツにはヤマハ株式会社の
VOCALOID SDK for Unity」が使用されています。
VOCALOID(ボーカロイド)」ならびに「ボカロ」はヤマハ株式会社の登録商標です。



supported by goo

VOCALOID SDK for UnityでSDユニティちゃんをリップシンクさせる

はじめに

VOCALOID SDK for Unityのサンプルコードには、
Unityちゃんをリップシンクできるコードがありましたので、
それをSDユニティちゃんでもリップシンクできるようにしてみました。


変更点

LipSyncController.csのvoid Awake()内の記述を変更します。


変更前の記述

_skinnedMeshRenderer = GameObject.Find("MTH_DEF").GetComponent<SkinnedMeshRenderer>();

blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.A, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.MTH_A")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.I, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.MTH_I")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.U, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.MTH_U")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.E, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.MTH_E")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.O, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.MTH_O")));



変更後の記述

_skinnedMeshRenderer = GameObject.Find("_face").GetComponent<SkinnedMeshRenderer>();

blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.A, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("face.MTH_a")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.I, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("face.MTH_i")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.U, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("face.MTH_u")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.E, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("face.MTH_e")));
blendShapeList.Add(new BlendShape(YVF.YVFVowelIDJapanese.O, _skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("face.MTH_o")));


このように書き換えることでSDユニティちゃんでもリップシンクが可能になります。

ライセンス表記

f:id:lo25131:20140607195201p:plain

このコンテンツは、『ユニティちゃんライセンス』で提供されています。


本コンテンツにはヤマハ株式会社の
VOCALOID SDK for Unity」が使用されています。
VOCALOID(ボーカロイド)」ならびに「ボカロ」はヤマハ株式会社の登録商標です。

Unityでひらがな化APIを利用する

はじめに


gooラボさんのひらがな化APIを利用して、
漢字、カタカナ、ローマ字をひらがなに変換してみました。


こんなかんじになります

例:

<変換前>  爽健美茶     ソウケンビチャ  soukenbitya
<変換後>  そうけんびちゃ  そうけんびちゃ  そうけんびちゃ

用意するもの


gooラボさんのAPIを利用するには、Githubのアカウントが必要となります。
上記のURLからアクセスし、「利用方法」からGithubにアクセスし、
アプリケーションIDを取得してください。


またアプリケーションやブログ等に公開するにあたって、
gooラボさんのクレジット表記も必要となります。



POSTでAPIを叩いて、Json形式で取得します。

Object→JsonJson→Objectには今回はLitJsonを使用します。
(Unity5.3より追加されたJsonUtilityはまだ調べてないので…)


LitJsonをダウンロードし、srcディレクトリ以下をpluginsディレクトリに入れてください。

今回は0.9.0を使います。
LitJSON


using UnityEngine;
using LitJson;
using System.Text;
using System.Collections;
using System.Collections.Generic;

public class PostHiraganaAPI : MonoBehaviour {

    /// <summary>
    /// GooラボApplicationID.
    /// </summary>
    private const string APPLICATION_ID = [上記のGithubにアクセス時に取得したIDを利用];

    /// <summary>
    /// ひらがな化API.
    /// </summary>
    private const string HIRAGANA_API = "https://labs.goo.ne.jp/api/hiragana";

    /// <summary>
    /// ひらがな.
    /// </summary>
    private string m_hiragana;

    /// <summary>
    /// ひらがな変換リクエスト.
    /// </summary>
    /// <param name="Sentence">変換したい文字列.</param>
    /// <param name="ConvertType">変換タイプ(1:ひらがな、2:カタカナ).</param>
    public IEnumerator HiraganaPostRequest(string Sentence, int ConvertType) {

        // JsonDataの作成.
        JsonData data = new JsonData();

        // アプリケーションID.
        data["app_id"] = APPLICATION_ID;

        // 対象文字列.
        data["sentence"] = Sentence;

        // 変換タイプ(ひらがな、カタカナ).
        switch(ConvertType){
            case 1:
                data["output_type"] = "hiragana";
                break;
            case 2:
                data["output_type"] = "katakana";
                break;
        }

        string postJsonStr = data.ToJson();

        Debug.Log("send post json: " + postJsonStr);
        
        // bodyを作成.
        byte[] postBytes = Encoding.Default.GetBytes (postJsonStr);
    
        // ヘッダー.
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers["Content-Type"] = "application/json; charaset-UTF8";

        Debug.Log("send post json: " + postJsonStr);

        // リクエストを送信.
        WWW result = new WWW(HIRAGANA_API, postBytes, headers);
        yield return result;

        if (result.error != null) {
            Debug.Log("Post Failure…");
        } else{
            Debug.Log("Post Success!");
            Debug.Log("result: " + result.text);

            JsonData jsonParser = JsonMapper.ToObject(result.text);

            // パース.
            m_hiragana = jsonParser["converted"].ToString();

            Debug.Log(m_hiragana);
        }
    }
}




また、ひらがな化APIを使用する際に、Unityのプロジェクトは
「WebPlayer」以外のプラットフォームにしてください。
WebPlayerだと「SecurityException: No valid crossdomain policy available to allow access
というクロスドメインのエラーが出てしまうので気をつけてください。


どんな風に変換されるか試しに利用してみたいという方は、
上記gooラボさんのページより、利用することができますので
そちらをご覧ください。


クレジット



supported by goo