EnumをListとして変換(生成)する方法

久しぶりの投稿です。久々すぎるのでブログに慣れていくために、まずは簡単なことから書いていきます。

今回のテーマは Enum(列挙型)を List型として変換(生成)する方法です。これを使う場面はあまり無さそうな気もしますが、こないだ仕事で小規模のプロジェクトで決まったシナリオを順繰りに再生していくときに使いました。Enum にシナリオを順番に定義しているので、初めから順番に再生できますし、シナリオの増減や順番変更があったときも比較的修正範囲が少なくなったかなと思います。少し面倒なのは、シナリオが減った場合にEnumの定義をコメントアウトすると影響が出やすいので、変換(生成)するときにListに入らないようにするといった感じが良さそうでした。

では、簡単ですけどコードを以下に貼ります。誰かの参考になれば幸いです。

Oculus RiftとTouchを入れる鞄の紹介

ハイエンドのHMD機器はあまり持ち出すことは無いと思いますけど、いざ持ち出そうとしたときは「鞄が無い…」といった事態が起こるかと思います。無造作に入れるだけだったらどうとでもなりますが、精密機械でもあるので大事に扱いたいところではありますよね。

そこで Oculus RiftとTouch を入れて持ち運ぶ用の鞄を買ってみたところジャストサイズで入ったので、手元に良い感じの鞄が無い方や、容量やサイズ感を知りたい方など参考にしてみてください。

昔から言われていたように、一眼レフ用の鞄はおススメですね。

HAKUBA ショルダーバッグ ルフトデザイン ブロス L ブラック 12L SLD-BS-SBLBK

===

(入れる前の鞄)

中の仕切りはマジックテープでくっついているので、全部取ります。その仕切りは使わないので閉まって置いています。

(入れた後の鞄)

2つのセンサーを左右対称にして一番下に沈めます。その次に、Oculus Riftを入れて、ヘッドセットの内側辺りにTouchを入れるとけっこう綺麗に収まります。

「N」キーを使って空のScene/GameObject を作成する

空のSceneを高い頻度で作成することはそんなに無いと思いますが、空のGameObjectを作成することは結構多いかと思います。空のGameObjectを作成するときは、ヒエラルキーViewで右クリックして「Create Empty」すれば出来ます。

出来ますけど、それなりに頻度が高い手順は当然、Unity側でショートカットを用意してくれているわけです。このショートカットを使えば2クリックが、1クリックになるので地味に便利だと思います。知らなかったという方はぜひ使ってみてはいかがでしょうか。

空のGameObject作成: Ctrl + Shift + 「N」

選択中のGameObjectの子として、空のGameObjectを作成: Alt + Shift + 「N」

「N」キーは "New" の略で設定されているはずで、他のツール等も同じように「N」キーを使ったショートカットを用意しているので覚えやすいですし、割と汎用的だと思っています。ですが、自分だけでは無いと思いますけど、片手では上手く押し切れないという…。まぁ慣れというより、手の構造的な問題なはずです、きっと。無理そうな人はおとなしく両手を使った方が早いというか、安定します。

また、下記のように空のSceneを作成するのにもショートカットが用意されていて、GameObjectを作成するよりもシンプルになっていたりします。押し間違えには注意してください。

空のScene作成: Ctrl + 「N」

Time.timeScaleを変更した上でdeltaTimeを取る方法

一口にTime.timeScaleを取ってみても注意点は幾つかあると思いますけど、この記事ではTime.timeScaleの値を変更したときに、Time.deltaTimeも一緒にずれてしまうのでその計算方法についてです。

Time.deltaTimeと、Time.realtimeSinceStartup

ゲームなどでよくある制限時間などは、Time.deltaTimeを利用して計算することが多いです。しかし、Time.timeScaleを変更すると、そのTime.deltaTimeの時間の流れをも変えてしまいます。(どう変わるかは後述します)

まず、Time.timeScaleの値の意味合いは以下になります。

  • Time.timeScale = 1.0f (通常(1倍速))
  • Time.timeScale = 2.0f (2倍速)
  • Time.timeScale = 0.5f (0.5倍速)

そのため、Time.deltaTimeも上記の速度になるので、Time.timeScaleが1fでないと実際の時間(1倍速)とはずれてしまいます。それは困りますよね。『おれ、ゾーンにでも入っているのか…』みたいな気持ちにさせてしまうかもしれませんよね。まぁそれはそれでアリな気もしなくはないですけど。

ということで、この場合に使えるgetterが用意されているわけです。それが、Time.realtimeSincesStartupです。これは、ゲームの開始から実際の時間軸で起動時間を計測しているので、この起動時間を利用すればTime.timeScaleに影響せずにdeltaTimeが取れるようになります。

そこで、Time.timeScaleと、Time.deltaTime、Time.realtimeSincesStartupを検証してみました。検証に使ったスクリプトと結果は以下になります。この結果のように、Time.timeScaleの値を変更しているときは、Time.realtimeSincesStartupを使ってdeltaTimeを計算できますよーという話でした。(多少のズレはご愛嬌ということで…)

Galaxy x GearVRを初めて利用するときの手順

GearVRを使って、早速VRを試してみようと思ったところ「どうやってアプリをダウンロードすればいいんだ?」となったので、簡単にはなりますがその手順を残しておきます。(分かれば、本当何てことなかった…)

Galaxy端末をGearVRに接続してセットアップ

以上です!w

なぜ僕はそれに気付かなかったが恥ずかしいくらいです。最初は、Google PlayやGalaxy Apps にアプリがあってそれをダウンロードしてきてGearVRで見れる、そう思ってました。ですが、「VR」や「Oculus」といった単語で検索しても上手いこと出てきませんでした。

それで、ググってもGearVR用のアプリの紹介とか出てきてしまい、「今はそれじゃない!それをどこからダウンロードするんだよ!」という気持ちにもなりました。

一旦、心を落ち着かせて「とりあえずGearVRにGalaxy端末をセットでもしてみるか」という流れでセットしたところ、突如セットアップをする案内が流れ始めました!

なるほど。灯台下暗しでした。。

その後は手順に従い、必要なシステムを幾つかダウンロードして、Oculusアカウントの設定(持ってない人は作成)をして、Oculus Storeからアプリをダウンロードしてスタートすれば「GearVRにセットしてください」といったダイアログが出るので、その通りにすれば終わりです。

ちなみに、Oculus StoreのアプリはGearVRにセットしていなくても使えますよ。

では、快適なGearVR体験を楽しみましょう!

背景をスクロールさせて、移動しているように見せる方法

シューティングゲームや、キャラがひたすら走るようなゲームにおいて、背景(マップ)を作り込むのはけっこうしんどいですし現実的ではないと思います。

そういったゲームの場合、基本的に背景は変えずにプレイヤーをその場で移動させているように見せることが主流なんじゃないかと。(特に、カジュアルゲーム

ちょうど自分もいまそのような仕組みでゲームを作成していたので、整理がてら書いていきます。

背景をスクロールさせる

これに尽きます。というより、これしかありません。

背景をスクロールさせる」ことに、プレイヤーがその場に留まっていても移動している雰囲気を出すことが出来るようになります。いわゆる錯覚ですね。それで、プレイヤーにモーションを適用させてあげれば、あたかもそのマップを走り抜けているように見えると思います。

後は、どのように実装するかになりますが、Scriptで対応するのが簡単です。では、具体的にどんな実装になるかというと、下記の感じになります。

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(MeshRenderer))]
public class UVScroller : MonoBehaviour {

    public float ScrollSpeed = 2f;
    private MeshRenderer mr;

    float offset = 0f;

    // Use this for initialization
    void Start () {
        mr = GetComponent<MeshRenderer> ();
    }

    // Update is called once per frame
    void Update () {
        offset = Mathf.Repeat (Time.time * ScrollSpeed, 1f);
        // offset = 1f - offset; //逆向きに動かしたい場合
        mr.material.SetTextureOffset ("_MainTex", new Vector2 (0f, offset));
    }
}

このScriptをスクロールさせたい背景にアタッチしてあげれば大丈夫です。

そしたら、ちょっとだけ解説をば・・

  • Time.time(ゲーム開始からの時間(秒))に指定スピードを掛けてあげたのを、Mathf.Repeatの第一引数(計算元)に指定する
  • Mathf.Repeatの第二引数(レングス(イメージ的にはレンジかな・・?))を設定して、第一引数から第二引数で割った余りを「移動量」として設定する
  • SetTextureOffsetに、"_MainTex"を指定して、移動させる x, y の値に上記で算出した「移動量」を設定する

あとは適当に試してみてもらえれば良いかと。

ちなみに、背景をスクロールさせる方法として他にもシェーダーを頑張ることも出来ますが、特別な要件等がなければこの内容で問題ないかと思われます。

Render Textureを使って、擬似的に鏡を表現する方法

では早速、疑似的に鏡を表現する方法はというと、、

  1. 鏡として見立てるオブジェクトを配置(Cubeでも何でも平面ならOK)
  2. 「Assets->Create->Render Texture」と選択して作成
  3. 2.で作成した Render Texture のSizeを「1024 x 1024」に変更
  4. Hierarchyビューにある1.で作成したオブジェクトに、ProjectビューにあるRender Texture をドラッグアンドドロップで設定
  5. 「GameObject->Camera」を選択して、サブカメラを作成
  6. 5.で作成したサブカメラを、鏡の位置から写すように配置
  7. サブカメラの「Target Texture」に、2. で作成したRender Textureを設定
  8. 1. で作成した鏡の Scale.X の値を反転して、マイナス値に変更

ざっと、こんな形で擬似的な鏡が出来上がると思います。ここまで書いてふと気付きましたが、ノンコーディングでいけましたね。

あとは諸々細かい調整してもらえれば良いかと。例えば、Render Texture の Sizeを下げると画質が粗くなりますし、Camera の Size を変更すれば写す範囲が変わったり等々できます。

ただ、リアルタイムに描画することになるので負荷が高くなるのでその辺りは注意しておきたいですね。

その他、鏡を表現する方法としては「アセットを買う(あるのかな?)」か、「シェーダーで反射鏡面を表現」する方法があるかと思います。前者は置いといて、後者に関してはどこかから拝借してくるのがよい感じでしょうか。シェーダーはあまりよく分かってないですが、時間が出来たら調べてみようと考えています。鏡シェーダーはもしかしたらUnity標準で提供されているかもしれないですし。

それで、話は戻りますが、この擬似的に鏡を表現する方法は、ライブのバックスクリーンに映像を表示するのにも使えるみたいなのでそっちの用途が主流だと思われます。(その場合、Scale.Xの値を反転する必要はなさそうかなと)