再びPhotonを使ったゲーム作りを再開しましょう。
ひと月前に、Photonのプロジェクトを三か月ぶりに立ち上げ警告文を消すだけで終わった前回の作業。
ちなみに、Photonがまた更新されていたので、まったく同じ作業をもう一度やるはめになりましたよ!
それでは今回は、このプロジェクトのシーン管理システムを作っていきましょう。
シーンの切り替えなどはちゃんとシステム化しておいたほうがいいですからね。
とはいえ、どういう風にシーンを管理をしましょうか。
一度前回のゲームジャムで作ったシーン管理システムを見直してみましょうか。
この記事にはUnity5.6.0f3を使用しています。
- 私はこのシーン管理クラスでゲームジャムを乗り切りました
- シーンの情報はScriptableObjectを使って管理!
- フェードシステムは去年の福島ゲームジャムの使いまわし!
- SceneControllerにAudioを持たせる大技!
- 今回のプロジェクトでは?
私はこのシーン管理クラスでゲームジャムを乗り切りました
さて直近作ったゲームと言えば、今年の一月末に参加したゲームジャムの作品ですね。
このゲームのシーン管理はこんな感じで作っていました。
SceneController.cs SceneController.cs
SceneTable.cs SceneTable.cs
シーンの情報はScriptableObjectを使って管理!
各シーンの情報は先日にも書いたScriptableObjectを使って管理しています。
各シーンの識別はenum
を使い、さらに以前作ったEnumListLabel
を使用して、アセット上でどのシーンなのか分かりやすくしています。
シンプルな作りで使いやすい形にはなっているのですが、この各シーンの識別にenum
を使う点はどうなのでしょうか。
シーンをロードする際など、スクリプト上で各シーンを識別する際に、シーンのファイル名を直接扱っていると、文字列であるため打ち間違えてもコンパイルエラーにはならないし、シーン名が変わったらそのシーン名を使っているスクリプトをすべて書き直す必要があります。
enum
を使えば上記点をクリアできるのですが、いくつか欠点が。
シーンを増やす場合、このenum
も一緒に増やす必要があるということ。
シーンを増やすのにスクリプトも書き換えねばならないのは、ちょっと面倒くさいなぁ。
そしてEnumListLabel
との相性の問題から、enum
に追加する場合、今まであるenum
の間に挿入すると、テーブルが壊れてしまうという欠点が……。
現に実際に使っていたenum
も、最初の方はゲームの遷移順に記述されているけど、途中からバラバラになっていってるのがわかります。
Logoとかすげぇ下の方に書いてるもんなぁ。
今回のゲームでは改善してみたいな。
フェードシステムは去年の福島ゲームジャムの使いまわし!
シーンがパッと切り替わるより、フェードがあった方が見栄えがいい!
そしてフェードシステムは、以前纏めましたから、それを組み込むだけ。簡単!
ただこれにも欠点が……。
SceneController
のChangeSceneProcess()
を見てみるとシーンの切り替え手順として、
- フェードアウト
- シーン読み込み
- フェードイン
となっています。
問題なのは、フェードインの最中にはすでにシーンが読み込み終わっているので、読み込まれたシーンは元気いっぱいにUpdate()
が呼ばれまくっているということです。
ゲームジャムの作品でキャラクターの選択シーンがあるのですが、フェード中にキャラクター選択のアニメーションが開始してしまい、フェードが明けた後にはすでにアニメーションが終わっているという悲劇が……。作ってくれた学生さんすまない。
フェードが明けてから、シーン内のUpdaete()
が掛かるように工夫する必要がありますね。
SceneControllerにAudioを持たせる大技!
ゲームジャムのシーン管理システム振り返ってみて、一番気になったところがここだよ。
SceneController
がAudioSource
を持っている点だよ。
private AudioSource m_bgmAudio = null; private FadeController m_fadeController = null; private string m_beingChangedSceneName = null; private void Awake() { m_bgmAudio = gameObject.AddComponent<AudioSource>(); m_bgmAudio.loop = true; gameObject.AddComponent<AudioListener>(); }
えーと、スクリプトを見る限り、シーン切り替え時にこのAudioSource
を使って各シーンのBGMを鳴らしているというわけだね。
そういえば、シーンのScriptableObject
にもBGM用のアセットデータを持つプロパティがあったよ。それと組み合わせているわけか。
ただ、この作りだとオプションでBGMの音量を調整するメニューを作った際に、BGMの音量を変えるためにSceneController
にアクセスし始めるという不可思議システムになってしまう!
この部分は今回作るゲームでは廃止しよう。
音を管理するコントローラーにその手の処理は任せるとします。
この件はゲームジャム専用処理ということで……。
あっ!
よく見たらAudioListener
までSceneController
にくっつけてるじゃないか!
鳴らした音を実際に聴けるようにするには、シーン中にAudioListener
が必要なのですが、AudioListener
は一つあればいいんです。
大抵は3Dサウンドのためなどに、カメラとかに付けている場合もあるのですが、ただSceneController
には付けないだろう。
しかも我らがUnity様は、シーン中にAudioListener
が複数あると、烈火のごとくログを吐き出すという仕様があるというのに。
このスクリプトだけで、当時どんだけ自分がテンパっていたかがわかるよ。
今回のプロジェクトでは?
うーん、振り返ってみるといろいろ使いにくい点なども見えてきました。
今回のプロジェクトはゲームジャムやぷちコンみたいに締め切りがあるわけではないので、少しシーン遷移について考えてみます。
そもそもこのシーン管理システムの大元は二年ぐらい前から使っているものなので、複数シーン対応とか考えていませんからねー。
折角なのでその辺も使ったシステムを作っていきましょう。