Unityのマップ切り替え
Unityでマップ切り替えしたい場面は多々あると思う(例えばRPGで屋外→家の内部に入る場合など)。
そのためには別のシーンに切り替える必要があるのだが、ゲームオブジェクトや値などは基本的に消えてしまうので注意が必要。
そこで、マップ切り替えの重要性とやり方について紹介していく。
Unityのマップ切り替え目次
マップ切り替えの重要性マップ分割
シーンの登録
スクリプト・ゲームオブジェクト制作
目次にもどる
マップ切り替えの重要性
最近はオープンワールド系ゲーム(マップを切り替えない)も流行っている(例えば原神やライフアフターなど)。
この仕組みは移動の際のストレスを軽減でき、広大な世界をリアルに体感できるのが特徴。
一方で問題も多々ある。最大の問題となるのが、マップ切り替えしないなら一つのマップ(1つのシーン)を大きく作ることになるためゲームの処理が重くなってしまうということ。
また、以前の記事の明るさ調整なども、屋外と屋内内部で分けたほうがやりやすい。
明るさ調整よって、オープンワールドにこだわる人以外は、マップを分割して作って(シーンを複数作って)マップ切り替えする形式にするのがおすすめだ。
目次にもどるマップ分割
ここからはマップ切り替えのやり方について紹介していく。まずはマップ分割からだ。
自分のサイトではこれまでに山と施設を作ってきた。
地形の作り方(山)Probuilderのインストール・使い方・基本(施設)
この山と施設を分割しようと思う。
プロジェクトビューにある現在のシーンをコピーして2つに増やし、一つ目のシーンをmountainと名付けて山を残し、施設を構成するゲームオブジェクトを削除した。
同様に、2つ目のシーンをfacilityと名付け施設を残し、山を構成するゲームオブジェクトを削除した。
目次にもどるシーンの登録
次にmountain→facilityのようにシーンを切り替えるための準備を行う。切り替えるには2つのシーンを登録する必要がある。
画面の上部メニューからFile→Build Settingsのように選択する。
以下のような画面が出る。mountainとfacilityの2つのシーンを「Scenes In Build」へドラック&ドロップする。
これでシーンの登録が完了した。
目次にもどるスクリプト・ゲームオブジェクト制作
操作キャラについてはプレハブ化した上で削除。
マップ切り替えの際は、シーン切り替えを行った上で新たに操作キャラをプレハブから指定位置に作成する。
シーン切り替え元に配置するMapmoveのスクリプトは以下の通り。
インスペクター欄ではシリアライズの値を入力。今回は以下の通り
Mapmovedataでは対応するdataを指定。dataはScriptableObjectで作成している。ScriptableObjectは非常に便利なので、わからない場合はぜひ以下の記事で確認してみてほしい。
ScriptableObjectを使用したステータス管理今回は別のシーンへ値を渡す必要があるのでScriptableObjectに値を保存した上で、シーン切り替え後に値を使用する方法をとる。dataの項目は位置と向きの2つのみ。
シリアライズの内容に戻ろう。
Mapsceneには切り替え先のシーン名を入力する。Movepositionには切り替え先の操作キャラの位置、Moverotationには切り替え先の操作キャラの向きを入力しておく。
スクリプトの内容に戻ろう。
最初のvoid OnTriggerEnter(Collider other)はこのスクリプトをつけたゲームオブジェクトに別のゲームオブジェクトが侵入したらイベントを起こす。
OnTriggerについては主人公や敵の攻撃を実装する記事でも使用している。ColliderやOnTriggerや当たり判定がわからない場合は先にこちらの記事を確認してほしい。
ダメージ判定・処理の作り方次にif (other.tag == "Player")としている。操作キャラのゲームオブジェクトにPlayerのタグをつけておけば、この記述で操作キャラがこのスクリプトをつけたゲームオブジェクトに侵入したことがわかる。
処理の中身は特に難しくないと思う。シリアライズで記述したシーン移動先位置と向きをScriptableObjectで作ったmapmovedataに保存した上で、SceneManager.LoadScene(movescene)と記述しmovesceneのシーンへ切り替えている。
続いて一つ目のシーンのmountainでCube(大きさを調整しやすいのでおすすめ)を作成した上でMapmoveのスクリプトをアタッチしよう。
CubeにはBox Colliderのコンポーネントが最初からついている。そのIs Triggerにチェックをつけよう。Cubeをすり抜けることが可能になる。
加えて、スクリプトに記述したOnTriggerEnterを使用するには操作キャラとCubeのどちらかにRigidbodyをつける必要がある。今回は操作キャラにRigidbodyがついている想定なのでCubeにつける必要はない。
Cubeがそのままの外観ではプレイヤーから壁だと判断されてしまう。そこでMesh Rendererのコンポーネントのチェックを外してしまおう。操作キャラからはCubeが見えなくなる。
そのCubeを今回は山の道を塞ぐように大きさ・位置を調整して配置してみた。
山→施設のような移動を行う予定なので、施設のマップシンボルが必要になる。何でもいいが今回は以下のフリーアセット(2024年3月現在無料)を使うことにした。
上記の施設素材(建物内部のドアや棚などはいらないので削除してもいい)を山に配置。施設の前にCubeが来るような位置にした。これで操作キャラがCubeに入ったらfacilityのシーンに移動できる。
後はfacilityのシーンに以下のスクリプトを記述し、何でもいいので適当なゲームオブジェクトを作成してアタッチしよう(今回の処理に関係ある重要部分のみ記載)。
これでfacility移動後には操作キャラが作成され、シーン切り替え前に指定した位置・角度で配置される。
最低限の機能は整ったが、移動が速すぎる印象。フェードイン・フェードアウトを加えるとより臨場感のあるマップ切り替えになる。次の記事で紹介予定。