読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

前回終了したシーンから再開する

「モバイル端末はメモリが減ると他のアプリを落とす」

これはモバイルである場合は仕方ないし、最良の選択だと思う。ただ逆に、これが故に「あまりメモリを使いすぎるアプリは次第に起動されなくなる」なんて話もある。これも仕方ない。

実際、ちょっとプレイしたいなんて思って起動した後、
タイトルから一々操作するのは相当面倒くさい。ロードが長いと尚更。

とは言え、アプリが落ちないことはまずありえないし、
消費メモリを減らすと貧相なアプリが出来上がってしまう。
なので「ロード時間を極力短くする」方法を色々と模索していたわけだが、ある意味もっとシンプルな答えを聞いた。



■前回終了したシーンから再開する
シンプルな答えとは、
単純に終了時の状態を保持しておいて、前回終了した場所から再開する方法。

確かにそれなら無駄なロードも省けるのでプレイ再開までの時間を減らせる。
そして再開のコストが減るので、メモリ使いすぎで他のアプリに落とされるリスクに多少目を潰れる。

うーん、なるほど

201212102.png

ということで、ちょっと作ってみた。

デモ
http://db.tt/NUMYaur9

左上のボタンでシーン(ステージ)移動で、ブラウザを読み込み直しても前回のシーンから再開する感じ。本当は座標とかも保存しようと思ったけど、デモの為にそこまでするのもアレなんでオミット。



■終了時のシーンを保存する

幸い、Unityはシーン単位という非常にコレに適した作りをしている。
なので終了時のシーンを保存する事は非常に容易い。

まず「必ず最初に呼ぶシーン」を設定(仮名:Proxyシーン)する。
で、Proxyシーンにある適当な空のゲームオブジェクトに下のコードを書いたクラスをアタッチ。

void Start () 
{
DontDestroyOnLoad(gameObject);
Application.LoadLevel( PlayerPrefs.GetInt("SceneNo", 1));
}

void OnApplicationPause (bool isPause)
{
if( isPause )
{
PlayerPrefs.SetInt("SceneNo", Application.loadedLevel);

// ?.

PlayerPrefs.Save();
}
}

(Web版の場合はOnApplicationPause でなくOnApplicationQuitを使用)

Proxyシーンは起動時に確実に呼ばれるので、キャッシュをこのタイミングで取っておくと後々のロードが短くなるが、それをしすぎると前回終了したシーンから再開する意味が無いといので、リソースマネージャーに貯めて高速化する方針のほうが良いかもしれない。
まあ認証とか通信みたいなことをするなら、このタイミングで非同期キャッシュが自分の頭の中ではグッドアンサーなんじゃないかと思ってる。

Unity3Dで、体感ロード時間を減らす
http://qiita.com/items/d29775e37116f6040810

また、?の所でSLGであればパラメータ、アクションゲームであれば…まあ色々と保存しておくと、復帰時シーン以外の情報も復帰できるかもしれない。
その辺りはSerializerを使ってガリっと保存しておくと楽でいいかも。

[Unity3D]シーンをテキストとして保存・展開するSerializer
http://terasur.blog.fc2.com/blog-entry-299.html

ソシャゲ系はこういった作りにしてほしいなあ・・・(チラ



多分これを話していた御方はもっと別の事も考えていたかもしれないけど、解釈もありなはず。
あと「広告の表示時間が短くなる」って理由で反対されるかも。