Scene Loadingサンプル
概要
シーンローディングサンプルは、開発者が本番用に独自のシーンローディングをどのように作成できるかの説明を目的とした技術サンプルです。アドレス指定可能なシーンやしミューレション開始前のシーンのプリロードについても説明しています。
Quantum用にシーンをローディング
Quantumでのシーンローディングには2つの重要な部分があり、これら2つの個別のロジックが互いにコミュニケーションする必要があります。
シミュレーションマップ
マップ
にはゲームプレイを推進するための決定論的なシミュレーションで使用されるシーンについての情報が含まれています。Map
は frame.Map = {YourMap}
によってシミュレーションから直接変更できます。Quantumは以前のものをすべてアンロードし、新しいものをロードします。
*マップベイキング*の詳細はこちらを参照してください。ただし留意すべき重要な点は、これはシミュレーション側に限定されるということです。デフォルトで提供されるシーンローダーを使用していない場合、Unityは反応しません。
Unityシーン
プレイヤーに正しいビジュアルを提供するには、Map
での変更への反応が必要です。
ここで重要な責務を果たすのがシーンローダーです。Frame
が定義したMap
を常に確認し、変更を検知するとすぐに対応するUnityシーンをロードします。
アドレス指定可能なシーン
アドレス指定可能なシーンは、通常のシーンローディングプロセスと大きく異なる必要はありません。ただし、シーンのAssetReference
参照をもつ必要があります。
Map
の変更が検知されると関連するシーンがアドレス指定可能かを簡潔に確認し、 アドレス指定可能な場合にはAddressables.LoadSceneAsync()
関数を使用してロードします。
C#
// Map change detected
if (CheckAddressableScene(map, out var sceneAssetRef))
{
// Addressable scene loading.
yield return LoadAddressableScene(map.Scene, sceneAssetRef);
} else
{
// Normal scene loading.
yield return SceneManager.LoadSceneAsync(map.Scene, LoadSceneMode.Additive);
}
C#
/// <summary>
/// Check if a map scene is addressable.
/// </summary>
private bool CheckAddressableScene(Map map, out AssetReference sceneAssetRef)
{
foreach (var addressablesScene in _addressablesScenes)
{
if (map.SceneGuid == addressablesScene.AssetGUID)
{
sceneAssetRef = addressablesScene;
return true;
}
}
sceneAssetRef = null;
return false;
}
C#
private IEnumerator LoadAddressableScene(string sceneName, AssetReference sceneAssetRef)
{
var instance = Addressables.LoadSceneAsync(sceneAssetRef, LoadSceneMode.Additive);
yield return instance;
// Storing for unload logic.
_addressablesScenesHandler.Add(sceneName, instance.Result);
}
まずシーンをロード
デフォルトの挙動では、シミュレーション開始後にシーンをロードします。ただし必要に応じ、先にシーンをロードすることもできます。 このサンプルのアプローチは3つのステップにもとづいています。
- ローカルプレイヤーが現在ルームにいるか、またシミュレーションがまだ開始していないかを確認します。
- すべてのクライアントがシーンを読み込んだ点を確認した場合のみ、
Start Game
ボタンを有効化します。 - 初回のマップが変更され、必要に応じて関連するシーンをロードしたかを確認します。
C#
// If the simulation is not started yet and LoadFirst is true, check if all clients already loaded the scene or if there's a change on the selected map.
private void Update()
{
if (!LoadFirst) return;
// (1)
var inRoom = UIMain.Client != null && UIMain.Client.InRoom;
var inGame = QuantumRunner.Default && QuantumRunner.Default.IsRunning;
if (inGame || inRoom == false) return;
// (2)
MasterCheckStart();
// (3)
if (UIMain.Client.CurrentRoom.CustomProperties.TryGetValue("MAP-GUID", out var mapGuid))
{
var map = UnityDB.FindAsset<MapAsset>((long)mapGuid).Settings;
if (_currentMap == map || _busy) return;
// If the map has changed and each client will load it before the simulation starts, set the scene loaded property to false.
var playerProperties = UIMain.Client.LocalPlayer.CustomProperties;
playerProperties["SCENE_LOADED"] = false;
UIMain.Client.LocalPlayer.SetCustomProperties(playerProperties);
LoadScene(map);
}
}
Back to top