たくあんポリポリ

勉強したことを載せていきます。最近、技術系の記事はZennに書いています。(https://zenn.dev/chittai)

Oculusのテクニカルレビューで指摘された内容と対応方法

前に作成したゲームを改良して、OculusStoreへのリリースまで実施してみた。(実際はコンテンツレビューでKeyのみのリリースとなってしまいましたが)

その時にテクニカルレビューでリジェクトされた際に指摘されたメッセージとその対応策について記載します。

使用した環境

  • Unity 2018.13f1 → Unity 2017.3.1f1

課題の説明

今回、受けた指摘と対応した内容を記載しました。

OverView Result 対応した内容
Headlocked menus and UI elements are generally uncomfortable for the user and should be avoided. A headlocked box with "Time" and "Targets" are displayed during gameplay. 常に表示しているUIをHMDの動きにピッタリ合わせて動いてはいないと思い、HMDが動いたあとになめらかにUIが追従するような実装に変更した。Quarternion.Lerpで回転をゆっくりにすることで対応。ただ、それでもだめだったので、HMDとUIは同期させてはだめだとわかり、UIは銃に追随するように変更した
The app runs and installs without crashing, freezing, or entering extended unresponsive states. Steps to reproduce: 1) The user boots the app. 2) Progresses to the main menu. 3) Exits the app via "Back" or "Oculus" button. 4) Boots the app for a second time. 5) An indefinite "Black Screen" appears. At this point, the user has to fully shutdown or restart their Oculus headset. どうしてもゲームを再度起動しようとするとクラッシュしてしまう。色々調べたがUnityのバグっぽかったので、Unityのバージョンを2017に落としたら改善された。
The app must request the minimum number of permissions required to function. Your app is asking for excessive user permissions or using user permissions inappropriately. -Access Microphone Please remove all unnecessary permissions. If your app requires any of the permissions listed above please explain in detail why your app needs the permission in order to function. 下記URLの通りに対応したら問題なく対応できた。スクリプトにあるクラスをみて自動で不要な権限が入ってしまうので、Micが使用されているスクリプトを削除するとOK。http://littlewing.hatenablog.com/entry/2018/09/04/170626

その他課題

ビルドの際に、Texture Compression を推奨通りにASTCにするとCrashしてしまう。そのため、ETC2にしてビルドした。
性能がでなかったため、Profilerで何に使用されているかを確認した。今回購入していたHighLightingSystemにかなりリソースを食っていたため使用しない方針にした。

f:id:c_taquna:20180924223932j:plain

感想

想定外の挙動をしたときにlogcatだけではわからず、バージョンを下げたりしたので色々と試しながらの対応が必要だった。そのへんの解決に異常に時間を取られてしまったので、今後は原因究明と切り分けは別で対応していきたい。
あと、リリースをすることはとても勉強になった。次はちゃんとStoreに並べたいと思う。

AtCoder Beginners Selection をやってみた

お勉強の一環として、AtCoderAtCoder Beginners Selection をやってみた。Unityを触るのとは少し勝手がちがったのだけれど、やはり何をしたくてそれをどうすればできるのかを考えるプロセスは変わらないなーと思った。

今回やったこと

AtCoder Beginners Selection の全問といてみた。
AtCoder Beginners Selection - AtCoder

感想

自分が書いたコードとまったく同じ目的をもって書かれた他の人のコードを読むことができる点は非常に良いなと思った。勉強方法として人のコードを読むけれど、自分ならこうしたけどこの人はこうしたんだーというのがしっかりと比較できるのは最高。自分の愚かさを再認識することができる。

正直できないところは人のコードを見るのも手だと思った。人のコードを読んで、何をしているのかをちゃんと考えてそれを写経するだけでも十分な勉強になる。あまりにハマりすぎたあとに人の回答をみると、疲れすぎてサボり心(次の問題にいこっかな~~)と戦う必要があるので、割と早めに見るのがよいと思う。今回は特にコード量が少ないものをピックアップして見てた。

すごいなと思ったのは、問題の性質を抽象化?して、実装しているもの。このケースはこうで~このケースは~とか書いていると、絶対終わっているコードになるなという思いとも戦う必要がでてくる。


ところどころ、そもそも言語選択や問題選択をミスってNGになっているのもあり、ちょっと勢いで提出してしまっている部分もあるので、もっとちゃんと詰めながらやっていきたい
f:id:c_taquna:20180822065637j:plain

VRMのBlendShapeをスクリプトから変更する

VRMでBlendShapeを操作して、キャラクターの表情を変更できるようにしました。Lerpを使ってなめらかに変更できます。

今回つくったもの

f:id:c_taquna:20180819092758g:plain

やりたいこと

BlendShapeの値を操作して、キャラクターの表情を変更させたくて、かつLerpでなめらかに変更することで生きた表情を作りたいと思いました。

使用したツール / 環境

  • Unity 2018.13f1
  • UniRx
  • UniVRM

全体像

Buttonを押すと ReactiveProperty の値が変更され、それを契機に表情を変更するメソッドを実行しています。

実装

github.com

表情の変更

こちらは、VRMのBlendShapeについて説明されているサイト。
ブレンドシェイプの設定 - dwango on GitHub

こちらは、VRMのBlendShapeをスクリプトから変更する方法が記載されているサイト。
BlendShapeを操作する - dwango on GitHub


今回、表情を変えるためにの実装は以下のコルーチン内で行っています。ReactivePropertyの値が変わる→表情を変更するためのメソッドを実行する→以下のコルーチンで表情を変更する。といった流れになっています。色々考えたのですが、Lerpで処理する場合これかなと。他にいい感じの実装方法ないかな。

        IEnumerator BlinkCoroutine(VRMBlendShapeProxy proxy)
        {
            float blinkParameter = 0;
            blinkParameter = Mathf.Clamp01(blinkParameter);

            while (blinkParameter <= 1)
            {
                proxy.SetValue(BlendShapePreset.Sorrow, Mathf.Lerp(0,1.0f,blinkParameter * 15));
                yield return null;

                blinkParameter += Time.deltaTime;
            }

以下の処理で、BlendShapeに値をセットしています。BlendShapePreset.Sorrow。表情の選択は、この"Sorrow"を変更して上げれば別の表情になります(Blinkとか)

proxy.SetValue(BlendShapePreset.Sorrow, Mathf.Lerp(0,1.0f,blinkParameter * 15));

感想

本当はまばたき→悲しみという表情の連鎖をさせたかったのが、それはまた別で。

VRMのキャラをランタイムで読み込んで、ボタンでモデルを変更できるようにした

今回は、VRMをランタイムで読み込み、ボタンによってキャラを変更できるようにしてみました。読み込み時にモーションも追加して、↑ボタンで走るモーションも追加されています。

  • 今回つくったもの
  • やりたいこと
  • 使用したツール / 環境
  • 実装
    • Button→モデルの表示
    • ランタイムでロードする処理
  • 感想

今回つくったもの

youtu.be

続きを読む

UniRxを使用したuGUIのデザインパターンを実装してみた

以下の記事を参考にUniRxを使用したuGUIのデザインパターンを実装してみました

www.slideshare.net

  • 今回やってみたこと
  • 使用した環境
  • MV(R)Pモデル
  • 感想

今回やってみたこと

記載したスライドを参考にUniRxを使用してMV(R)Pパターンの実装をしてみました。処理の内容は、RedButton,BlueButton,YellowButtonの3つのボタンを用意して、ボタンを押したらSphereの色が変わるようにしました。

これがデフォルトで
f:id:c_taquna:20180805073359j:plain

RedButtonを押すとこうなります
f:id:c_taquna:20180805073405j:plain

続きを読む

以前つくったゲームの処理の一部をUniRxで書き直してみた

前に作ったゲームをUniRxで一部処理を書き換えてみました。自分がどんな処理をUniRxで書き換えたのか記載します。

c-taquna.hatenablog.com

  • 使用した環境は以下
  • 今回やってみたこと
    • カウントダウンの処理を書き換え
    • ゲーム内の 処理の直列化
    • 感想
続きを読む

【メモ】Shader Graphを使ってみた

下記サイトを参考にShader Graphを使ってみた。確かに、パズルの様に組み合わせていくだけで色んな表現ができるので、使いこなせたら面白いなと思った。ただ、どういう風に考えれば再現できるのかなーと考え中。Shaderを使う人って何をどう考えて設計しているんだろう。。

negipoyoc.com

f:id:c_taquna:20180712232215j:plain

f:id:c_taquna:20180712232328j:plain

VRシューティングゲームを作った(3作品目)

今回、Unityで3つ目のVRゲームを作ってみました。今まで勉強してきたものに、自分にとって新しい要素をいくつか取り入れました。
Menu画面のレーザーポインタもそうですし、直接は見えないですが今回はOculusRiftだけではなくOculusGoでビルドして遊べることも確認済みです。

  • 今回作成したゲーム
  • 使用した環境は以下
  • 今回やってみたこと
    • メニュー画面
    • UIについて
      • メニュー画面のUI
      • リザルト画面のUI
    • ゲームのプレイ状態の判定
  • Oculus Go
  • 感想
  • GitHub

今回作成したゲーム

youtu.be

続きを読む

UnityでScene遷移時にstatic変数の値を引き継いでしまう問題に遭遇した時

UnityでSceneの遷移時に少しハマったのでメモします。あまり具体例とかないですが。

環境

使用した環境は以下

  • Unity 2018.1.3f1

何にハマったのか

各シーンにて、条件を満たすとSceneの遷移が起こるようになっていて以下の様に遷移してみた。

Menu→Play→Menu→Play

最初Menuから入って、その後Playに移って、クリアしたらMenuに戻ってまたPlayへと遷移していたのですが、2回目の遷移の時にゲームが始まった瞬間に終わってしまったり、Clearの時に表示されるUIが消えなかったりして思った様に動いてはくれませんでした。

何が原因だったのか

問題は2つあって、

  1. 原因となっていたのは、ゲームのプレイ状態(開始・プレイ中・終了のステータス)を保持する変数がstaticで定義されていて、Sceneが変わってもゲームのプレイ状態を引き継いでしまっていたことが問題でした。(クリア後にMenuに戻っても、ゲームのプレイ状態はクリアのままなので、次にPlayにいってもすぐに終了してしまう)
  2. もう一つは、同じ様にstaticで定義していたのだけれど、Start()の前、インスタンス変数を定義するところで初期化されている変数があったためSceneが始まった際にきれいに初期化されなかったことです。

例として、変更前と

public class PlayManager : MonoBehaviour {
    float _PlayTime = 20;

~~~

変更後

public class PlayManager : MonoBehaviour {
    float _PlayTime;

    void Start () {
        _PlayTime = 20;
    }

~~~

何を対応したのか

Scene遷移時にゲームのプレイ状態の初期化を入れたのと、もう一つはインスタンス変数として定義した変数はStart()の中で定義するようにしたこと。この当たりのstatic変数の扱いとかはUnityのベストプラクティス的なものがあるのかな?

Oculus Rift/Oculus Go でレーザーポインタを当てたオブジェクトの色を変える

Oculus Rift/Oculus Go でレーザーポインタを使用して見ようと思い、色々と勉強してみました。今回は、最終的にレーザーポインタがあたったオブジェクトの色を変更するところまで実行します。

  • 今回つくったもの
  • 環境
  • 前提条件
  • 追加処理の説明
  • Sphere の Collider の削除
  • 感想

こんな感じで、レーザーポインタがオブジェクトにあたった時に色を変えています。(赤→黄色)

今回つくったもの

f:id:c_taquna:20180705054350j:plain
f:id:c_taquna:20180705054347j:plain

続きを読む

Unity5ゲーム開発レシピ~ハマるゲーム制作のノウハウ~を読んだ

がんばってUnityを使おうと思ってたけど、やっぱ基礎ちゃんとしないといけなくね?ということで参考書を読んだ。結論からいうと今後も続けていきたい。

どんな本か

www.shoeisha.co.jp

Unity5でのゲーム制作におけるTIPSが載っています。最初からたどるとTPSのロボゲーが完成します。これはなかなか感動。

環境

使用した環境は以下

  • Unity 5.6.3p1

感想

ざっくりとした内容

まず、章ごとにやることが決められていて、一つずつステップを踏んでいく様になっている。一からたどればTPSのロボゲーが完成するし、こういこうことやりたいな~って時に開く逆引きの参考書としても優秀。

良い点

Unityは触ったことあるけど、あまり基礎から勉強したことない人にはうってつけな気がする。個人的に、ある程度コードが読めてUnityを触ったことある人で初心者を抜け出したいな~と思っている人は買ってみてもいいのではと思う。参考書にあるコードを写経して理解するだけでもなかなか学びがある感じ。特に、GUIでの操作も文字だけではなくちゃんとキャプチャがはられているので、すごくわかりやすい。

悪い点

Unity5が古いので、参考書の記載だとうまく動かない部分がある。そのため、適宜読み替える必要がある。本当に初心者の場合はその箇所に気がつけず嵌りそうなきがする。あと、やっていることと書いてあることが違ったりするので(結構多い)その部分も適宜読み替える必要がある。そういう点でも初心者向きではないかも。

書評

初心者向きではないが、Unityの使い方を学ぶ点では非常に学びがある。ただ、現在はUnity2018もでていることからかなり古い資料になってしまっている。来年には役にたたなくなっているかもしれないが、それでも今なら勉強の参考書として優秀だと思う。

SpeedTree materials need to be regenerated が出たときの対処法

Unityで下記メッセージが出た時に対処した方法を記載します。

SpeedTree materials need to be regenerated

環境

  • Unity 5.6.3p1

発生したタイミング

Assets -> Import Package -> Environment で Import が完了した直後

対処方法

下記4ファイルのInspectorで 「Apply&Generate Materials」をクリック

インポートした Asses -> Standard Assets -> Environment -> SpeedTree
-> Broadleaf -> Broadleaf_Desktop, Broadleaf_Mobile
-> Conifer -> Conifer_Desktop
-> Palm -> Palm_Desktop


f:id:c_taquna:20180616091454j:plain