//tips
//ロビーのボタンとシーンの複製
ロビーからroomを新規作成し、入室する際、roomに紐づけられた遷移シーンはどのように用意すれば良いのかを考える。
現状は1組のペアなので全てSampleScene3に遷移させているが、多様なルーム名に対して、順番に遷移先シーンを割り当てていく必要がある。
シンプルな方法は大量の遷移先シーンを決められたボタンを事前に作成しておき、名前の部分だけ編集できるようにしておけば良い。
ただ、ボタン削除などの方法も見かけるので、各ペアを配列に入れ、配列番号の早い順に空シーンが割り当てられるような仕組みを考えていきたい。
これには先日確認したStackに近い先入先出しのQueueキューが使えそうに思える。
下記がシンプルな例。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class QueueTest : MonoBehaviour {
void Start () {
Queue<string> queue = new Queue<string>(){};
queue.Enqueue(“ne”); //登録
queue.Enqueue(“ushi”);
queue.Enqueue(“tora");
queue.Enqueue(“u”);
Debug.Log("queue.Count:" + queue.Count); //4
foreach (string name in queue) {
Debug.Log("name:" + name); //name:~~でneから順に表示
}
while (queue.Count > 0) {
Debug.Log("queue.Dequeue():" + queue.Dequeue());//neから順に取り出し
}
Debug.Log("queue.Count:" + queue.Count);
}
}
一旦ボタンを作成し、押されたボタンの順番にシーンに飛ぶ流れを考えていく。まず遷移先の1,2,3シーンを作成。
オブジェクトを格納したリストのAddや.RemoveAt,
配列だけでも対応できそうな気がしたのでそちらでのコードも先に書いたが、どうにもリスト、配列内のindex番号[1]を常に削除するという操作がひどくややこしいやり方になることがわかったので、大人しくQueueを使用して進めていく。
Queueであれば、index番号[1]などを取得する方法を考えなくても、常にリストの先頭にあるものを対象に操作を行えるはず。
下記スクリプトを作成し、ボタンを押した際に先頭の登録を削除し、削除した値を用いてシーン遷移先に指定を行うスクリプトと遷移後のシーンから戻ってくるスクリプトを記載したがなぜか dequeueでキューから削除されない現象が発生。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneListManager : MonoBehaviour
{
public Queue<int> queue = new Queue<int>();
public int dequeue ;
void Start()
{
// 値を追加
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
Debug.Log("キューに登録されている数: " + queue.Count);
}
public void OnRemove()
{
dequeue = queue.Dequeue();
Debug.Log("Dequeueした値: " + dequeue);
string Scene = dequeue.ToString(); //scenes[1]
SceneManager.LoadSceneAsync(Scene, LoadSceneMode.Single);
foreach (var item in queue)
{
Debug.Log("Dequeue後: " + item);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneMoveGO : MonoBehaviour
{
void Start()
{
Invoke("OnSceneMove", 2);
}
// Update is called once per frame
void Update()
{
}
public void OnSceneMove()
{
SceneManager.LoadSceneAsync("GameObjectMaster",LoadSceneMode.Single);
}
}
本来なら1,2,3という形で遷移先のシーンが表示されるはず。invokeで帰ってきた際にstartメソッドが再度実行されることが問題ではないかと考えて修正。
Startメソッドではなくボタンを押してキューを登録する形に変更し、登録ボタンを新たに作成した。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneListManager : MonoBehaviour
{
public Queue<int> queue = new Queue<int>();
public int dequeue ;
public void Onregister()
{
// 値を追加
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
Debug.Log("キューに登録されている数: " + queue.Count);
}
public void OnRemove()
{
dequeue = queue.Dequeue();
Debug.Log("Dequeueした値: " + dequeue);
string Scene = dequeue.ToString(); //scenes[1]
SceneManager.LoadSceneAsync(Scene, LoadSceneMode.Single);
}
}
そうすると別途下記エラーの発生。
InvalidOperationException: Queue empty.
System.Collections.Generic.Queue`1[T].ThrowForEmptyQueue () (at <d2957de1c3fd4781a43d89572183136c>:0)
System.Collections.Generic.Queue`1[T].Dequeue () (at <d2957de1c3fd4781a43d89572183136c>:0)
SceneListManager.OnRemove () (at Assets/SceneListManager.cs:24)
UnityEngine.Events.InvokableCall.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
先頭のキューを削除したら他のものが繰り上がり順々にdequeue = queue.Dequeue();が行われると考えていたが違うのだろうか。
マイクロソフトの記述の参考例で下記のものがあったので、dequeue = queue.Peek();、queue.Dequeue();と修正してみたが同じエラー。確認中。
https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic.queue-1?redirectedfrom=MSDN&view=net-5.0
foreach( string number in numbers )
{
Console.WriteLine(number);
}
Console.WriteLine("\nDequeuing '{0}'", numbers.Dequeue());
Console.WriteLine("Peek at next item to dequeue: {0}",
numbers.Peek());
Console.WriteLine("Dequeuing '{0}'", numbers.Dequeue());