(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!

    

シーンを移動するとInputがリセットされる件【Unity】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 5.4.1f1, 5.5.0b6


はじめに

今回はUnityの入力を簡単に処理できるInputクラスの話です。



タイトルの通り、このInputはシーンを移動するとリセットされる場合があります。


例えば、以下のようにキーボードのAとSを押すとログが表示され(Input.GetKeyで取得)、

ボタンを押したらシーンを移動するという場合に、


f:id:kan_kikuchi:20161017133117p:plain


複数の入力があると、シーン移動後は一つの入力しか受け取れません。

以下の例ではAとSキーを入力したまま、シーン移動をしていますが、

Sキーの入力しか取れていないのが分かると思います。


f:id:kan_kikuchi:20161017133531g:plain


なお、キーの入力が受け取れなくなった場合、

指を離してもInput.GetKeyUpも取得出来ないため、指を離したかどうかも分かりません。


仕様?バグ?

仕様かバグなのかよく分からず、ネット上にもそれらしい情報を見つけれられなかったので、

Unityの日本語ヘルプデスクで聞いてみました。



頂いた回答を要約すると以下のような感じでした。

  • シーンがロードされるタイミングですべての入力がリセットのは仕様
  • ゲームの種類等にも依るが、各レベル、ステージ等でシーンを分けることは推奨されず、一つのシーンにすべて詰め込むほうがよい。


Inputがリセットされるのが仕様という事なので、

一つだけ入力が受け取れていた事の方がバグだったっぽいです。

なお、一つのシーンに詰め込む件の参考文献とその要約は以下の通りです。

すべてのスクリーンやアセット、GameObjectを一つのシーンに展開し、現在使用するレベル、ステージで使用するGameObject等をアクティブにし、カメラ座標を移動、固定、使用しなくなったGameObject等を無効化したほうが効率がよい

How to use Application.LoadLevel() without resetting Input axes? : Unity3D



上記の方法でも確かにInputがリセットされる事はなくなりますが、

非表示にしているテクスチャなどのリソースもメモリ上には存在するので、

ある程度、規模の大きいゲームには向かない方法です。


シーンを移動しない実装方法

  • シーンを移動してもInputを継続して受け取りたい。
  • けど、上記のように全部マップ(ステージ)作成して切り替えはしたくない。
  • かと言って、適宜マップの破棄と生成するのはめんどくさい 。



と言った私におすすめな方法が、

メインシーンとその他のシーンを作成し、 他のシーンのロードとアンロードをするという方法です。

以下の画像がその例で、マップ移動時にシーンが一度破棄されているのが分かると思います。


f:id:kan_kikuchi:20161021070938g:plain


これならメインシーンは移動していないので、入力が継続して受け取れて、

マップ切り替えの度にマップシーン全体が破棄されるので、

シーン移動している時とほぼ同じような感覚で実装が行えます。


なお、シーンの追加と破棄は以下のようなコードです。

//SceneManagerを使うには using UnityEngine.SceneManagement: が必要
SceneManager.LoadScene("シーン名", LoadSceneMode.Additive);//シーン追加 
SceneManager.UnloadScene("シーン名");//シーンの破棄 


また、シーンを破棄しても、リソースの破棄はしてくれないらしいので、

UnloadScene後にResources.UnloadUnusedAssetsをした方がいいかもしれません。

SceneManager.UnloadScene("シーン名"); 
Resources.UnloadUnusedAssets(); 


さらにシーンを追加後、プログラムから新たにゲームオブジェクトを生成すると、

メインシーンの方に生成されてしまい、マップシーンを破棄した時に一緒に破棄出来なくなるため、

生成したオブジェクトはマップシーン内に最初からいるオブジェクトの子に配置しましょう。


f:id:kan_kikuchi:20161020072441j:plain


おわりに

現在開発中のピコンティアではマップ移動した時に移動キーを入力しなさなきゃいけない、

という致命的な問題に繋がっていたので、解決できて一安心している今日この頃です(:3っ)∋〜