イネ科

すっぺらぴっちょん

Unity製のAndroidアプリをリリースしたお話(VRMascot)

はじめに

簡易的なAndroid向けのVRMビューアが欲しかったので、作ったというお話です。 多機能なアプリはいくつかリリースされているのですが、シンプルに見たいだけというニーズを満たせるものは無いように思いました。無いのなら作るしかない。作ればよい。アァァッ。

play.google.com

追記:
2019/5/28 プライバシーポリシーを追加したら停止処置を受けました。異議申し立て中。
2019/5/29 アプリ内リンクのTwitterとBoothが性的コンテンツ扱いされていたようで、却下される。アプリの性的コンテンツを徹底排除して再度リリース。今のところ停止されず。

機能について

思いつき駆動開発なので、最小限で実装。

  • ストレージ内のVRMファイルの読み込み
  • 頭をタッチした時に反応してくれる
  • 胸をタッチした時に反応がある
  • 最初に読み込むモデルはStreamingAssetに配置(Replaceが楽そうという理由。これが後ほどボトルネックに。)

胸をタッチする実装は、今までの開発で得た知見を組み込みたかった為。

タッチ操作の決め方

マウス処理の流用が予想以上にダメすぎたので、Touchを使用して実装。Touch処理完全に理解した。

指1本スワイプ>視点変更
指2本 ピンチインアウト>縮小拡大
指4本 スワイプ>水平垂直移動
指一本タップ>Ray関係

指3本の処理を使っていないのは、スワイプがAndroidスクリーンショット操作と被ってしまうから。

待機アニメーションと表情の制御について

待機アニメーションについては、シンプルに呼吸をしている感じを出すものを作成し、それを適用したのみ。 表情に制御についてはアダルトVRMアプリ向けに書いたコードを流用し、なめらかになるように改善。 少し表情を遷移させてあげるだけでも、ドキドキ感、アナログハック感が出てくる。

VRMのBlendShapeを良い感じに遷移させてみる - イネ科

カメラワークについて

FOV5設定(かわいく見える)のカメラをストレス無く操作できるように、パラメータを調整。拡大の処理についてはモデルに近づきすぎると反対側にカメラが移動してしまうので、移動制限の処理を組み込んで 回避1している。
バストアップや、全体表示時のカメラポジションについては、Headのボーン位置、VRMモデルの身長をメッシュから算出している。

//身長を計算するやつ。コメントアウト部分についてはあえて残している。
    public float GetSkinnedMeshRendererHeight(){
        float maxHeight = 0.0f;
        // var allSkinnedMeshRenderer = mainVRM.GetComponentsInChildren<SkinnedMeshRenderer>(true);
        var allSkinnedMeshRenderer = mainVRM.GetComponentsInChildren<Renderer>(true);
        for (int i = 0; i < allSkinnedMeshRenderer.Length; i++)
        {
            // float height = allSkinnedMeshRenderer[i].bounds.size.y;
            float height = allSkinnedMeshRenderer[i].bounds.center.y + allSkinnedMeshRenderer[i].bounds.extents.y;
            if(height > maxHeight){
                maxHeight = height;
            }
        }
        return maxHeight;
    }

胸のタッチ処理について

2019/5/29 新リリース版では機能を排除(停止対策) f:id:sesleria:20190524020247p:plain:h300f:id:sesleria:20190524020256p:plain:h300

胸の周囲に設置したコライダーへのタッチ判定をScreenPointToRayで取得。タッチした箇所のVRMSpringBoneColliderGroupを調整して、胸を揺らしている。
※以下の記事に書いてある、囲い込み法を組み込み。

UnityでVRMモデルの胸を揺らす知見 - イネ科

頭のタッチ時の処理についてもコライダーを仕込んでいる。細かく制御する場合は、部位ごとにコライダーを仕込んでタグとか名前で判定してあげれば良さそう。

StreamingAssetから読み込む際の遅延対策

起動時にStreamingAssetからVRMファイルを読み込む際、数秒かかってしまう事が判明。以下のようにSliderで作成したプログレスバーを表示することにより、ユーザーに不安を与えないように。読み込みが終わったタイミングでStopCoroutineで止めてあげれば、「案外早かったな?」感も出せて一石二鳥。

//やっつけコルーチン
    IEnumerator ProgressAnime(){
        progressBar.gameObject.SetActive(true);
        float shinchoku = 0.0f;
        while(shinchoku <= 1.0f){
            shinchoku += 0.01f;
            progressBar.value = shinchoku;
            yield return new WaitForSeconds(0.02f);
        }
    }

2回目以降の起動についてはオプション設定から、最後に開いたVRMファイルを自動的に読み込むように変更可能。ストレージからの直接読み込み処理については高速だった為、プログレスバーは非表示に。「デフォルトで入っている私のモデルを見続ける人はいない」という希望的観測に基づく実装。

アプリの公開

25$支払い可能なクレジットカード、スクリーンショットを数枚、GooglePlay用のバナー、アプリケーションのアイコン(32bit 透過 512*512)を用意しておく。 ビルド時の証明書設定やGooglePlayConsoleへの登録についてはぐぐったら知見が大量に出てくる。

64bit対応

APKをアップロードしたところ、64bitに対応しましょうと警告が。こちらの記事を参考に、ビルド設定を変更する。1.2GBくらいのSymbolファイルも一緒に出力されるようになるので、ビルドに必要な時間は増える。

2019 年 8 月 1 日以降、Google Play で公開するアプリは 64 ビット アーキテクチャをサポートする必要がある。

developer.android.com

そして謎のリジェクト

これは本当に謎です。念のため1.01のモジュールをアップしなおしたのですが、公開ページの修正でリリースが完了してしまい、1.0.0の公開直後にアップデートが走るという悲しい結果になりました。

最後に

アプリを起動して、せすれりあちゃん(中身♂設定)を表示しておくだけでスマホが使用不可能になり、作業が捗ることは間違いありません。つまりみんな私をすこれよ!!胸触られても怒らないからね!


  1. ベクトル距離で制限をかけるだけだと反対側に突き抜けてしまう。