シーンワークフローを改善(シーンを同時に複数表示)
複数のシーンをロード、アンロードすることで、1つのシーン上に同時に複数のシーンオブジェクトを存在させることができます。
チーム開発で複数のメンバーがそれぞれのシーンで開発するなどに使えます
チーム開発のコツ
ScriptableObject を使ってみる
リンク先のビデオチュートリアルも興味深いものになっています
Addressable Asset Systemを使ってみる
今回は、リンク先の情報をアレンジしています。サンプルシーンも確認してみましょう
サンプルシーン
キャプチャ
Managerオブジェクト
SceneLoaderオブジェクト
Addressables Groups
作成手順詳細は、リンク先を確認してください
コード
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
public class SceneSelector : MonoBehaviour
{
[SerializeField]
SceneLoader sceneLoader;
public AssetReference titleScene;
public AssetReference gameScene;
public AssetReference endScene;
AsyncOperationHandle<SceneInstance> handle = new AsyncOperationHandle<SceneInstance>();
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
sceneLoader.ChangeTo(titleScene);
}
else if (Input.GetKeyDown(KeyCode.B))
{
sceneLoader.ChangeTo(gameScene);
}
else if (Input.GetKeyDown(KeyCode.C))
{
sceneLoader.ChangeTo(endScene);
}
else if (Input.GetKeyDown(KeyCode.Space))
{
Load();
}
else if (Input.GetKeyDown(KeyCode.U))
{
sceneLoader.Unload(handle);
}
}
private async void Load()
{
handle = await sceneLoader.Load(endScene);
}
}
次のコードはシーンウィンドウに存在するシーンの管理をListで行っているため、少し複雑になっています。
これは、複数のシーンの追加削除をアクティブに行うためです。それに伴っての付随するコードが含まれています
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
public class SceneLoader : MonoBehaviour
{
List<AsyncOperationHandle<SceneInstance>> handles = new List<AsyncOperationHandle<SceneInstance>>();
SynchronizationContext context;
private void Start()
{
context = SynchronizationContext.Current;
}
public void ChangeTo(AssetReference sc)
{
Task.Run(() =>
{
context.Post(async _ =>
{
foreach (var handle in handles)
{
await Addressables.UnloadSceneAsync(handle).Task;
}
handles.Clear();
await Load(sc);
}, null);
});
}
public void Unload(AsyncOperationHandle<SceneInstance> handle)
{
if (!handles.Contains(handle)) return;
Addressables.UnloadSceneAsync(handle).Completed += p =>
{
if (p.Status == AsyncOperationStatus.Succeeded)
{
handles.Remove(handle);
}
};
}
public async Task<AsyncOperationHandle<SceneInstance>> Load(AssetReference sc)
{
var handle = new AsyncOperationHandle<SceneInstance>();
await Task.Run(() =>
{
context.Post(async _ =>
{
handle = Addressables.LoadSceneAsync(sc, LoadSceneMode.Additive);
await handle.Task;
handle.Completed += p =>
{
if (p.Status == AsyncOperationStatus.Succeeded)
{
handles.Add(handle);
}
};
}, null);
});
return handle;
}
}
ディスカッション
コメント一覧
まだ、コメントがありません