AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
SceneLauncher.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using UnityEngine;
6 using UnityEngine.SceneManagement;
7 
8 namespace HoloToolkit.Unity
9 {
10  public class SceneLauncher : Singleton<SceneLauncher>
11  {
12  [Serializable]
13  private class SceneMapping
14  {
15  public string ScenePath = string.Empty;
16 
17  [Tooltip("This toggle enables or disables the generation of a button for this specific scene.")]
18  public bool IsButtonEnabled = false;
19  }
20 
21  [SerializeField]
22  [Tooltip("The button scene mapping to keep track of which scenes are enabled in the scene launcher. This list of scenes is generated from the build window's active scenes.")]
23  private SceneMapping[] sceneMapping = null;
24 
25  [Tooltip("Location of the center of the grid of buttons in Unity space.")]
26  public GameObject ButtonSpawnLocation = null;
27 
28  [Tooltip("Prefab used as a button for each scene.")]
29  public SceneLauncherButton SceneButtonPrefab = null;
30 
31  [Tooltip("Number of rows in the grid of buttons. As more scenes are added, they will spread out horizontally using this number of rows.")]
32  public int MaxRows = 5;
33 
34  private int SceneLauncherBuildIndex { get; set; }
35  private Vector3 sceneButtonSize = Vector3.one;
36 
37  private void OnValidate()
38  {
39  Debug.Assert(SceneButtonPrefab != null, "SceneLauncher.SceneButtonPrefab is not set.");
40  }
41 
42  protected override void Awake()
43  {
44  // If we have already initialized,
45  // then we've created a second one.
46  if (IsInitialized)
47  {
48  Destroy(gameObject);
49  }
50  else
51  {
52  base.Awake();
53  }
54  }
55 
56  private void Start()
57  {
58  if (SceneButtonPrefab == null)
59  {
60  return;
61  }
62 
63  SceneLauncherBuildIndex = SceneManager.GetActiveScene().buildIndex;
64 
65  // Determine the size of the buttons. Instantiate one of them so that we can check its bounds.
66  SceneLauncherButton sceneButtonForSize = Instantiate(SceneButtonPrefab);
67  var sceneButtonForSizeCollider = sceneButtonForSize.GetComponent<Collider>();
68 
69  if (sceneButtonForSizeCollider != null)
70  {
71  sceneButtonSize = sceneButtonForSizeCollider.bounds.size;
72  }
73 
74  for (int sceneIndex = 0; sceneIndex < sceneMapping.Length; ++sceneIndex)
75  {
76  if (sceneMapping[sceneIndex].IsButtonEnabled)
77  {
78  CreateSceneButton(ButtonSpawnLocation, sceneIndex);
79  }
80  }
81 
82  Destroy(sceneButtonForSize.gameObject);
83  }
84 
85  private void CreateSceneButton(GameObject buttonParent, int sceneIndex)
86  {
87  string sceneName = sceneMapping[sceneIndex].ScenePath;
88  sceneName = sceneName.Substring(sceneName.LastIndexOf("/", StringComparison.Ordinal) + 1);
89  sceneName = sceneName.Replace(".unity", "");
90  var scene = SceneManager.GetSceneByBuildIndex(sceneIndex);
91  Debug.Assert(SceneManager.GetSceneByName(sceneName) == scene);
92 
93  SceneLauncherButton sceneButton = Instantiate(SceneButtonPrefab, GetButtonPosition(sceneIndex, sceneMapping.Length), Quaternion.identity, buttonParent.transform);
94  sceneButton.SceneIndex = sceneIndex;
95  sceneButton.SceneName = sceneName;
96  sceneButton.MenuReference = ButtonSpawnLocation;
97  }
98 
99  private Vector3 GetButtonPosition(int sceneIndex, int numberOfScenes)
100  {
101  int yCount = Mathf.Min(numberOfScenes, MaxRows);
102  int xCount = (numberOfScenes - 1) / yCount + 1;
103  int x = sceneIndex % xCount;
104  int y = sceneIndex / xCount;
105  Debug.Assert(x < xCount && y < yCount);
106 
107  // Center a grid of cells in a grid.
108  // The top-left corner is shifted .5 cell widths for every row/column after the first one.
109  var topLeft = new Vector3((xCount - 1) * -0.5f, (yCount - 1) * 0.5f, 0.0f);
110  var cellFromTopLeft = new Vector3(x, -y, 0.0f);
111  // Scale by size of the button.
112  var positionOffset = Vector3.Scale(topLeft + cellFromTopLeft, new Vector3(sceneButtonSize.x, sceneButtonSize.y, 1.0f));
113 
114  return ButtonSpawnLocation.transform.position + positionOffset;
115  }
116 
117  public void LaunchSceneLoader()
118  {
119  Debug.LogFormat("SceneLauncher: Returning to SceneLauncher scene {0}.", SceneLauncherBuildIndex);
120  SceneManager.LoadSceneAsync(SceneLauncherBuildIndex, LoadSceneMode.Single);
121  ButtonSpawnLocation.SetActive(true);
122  }
123  }
124 }
override void Awake()
Base Awake method that sets the Singleton&#39;s unique instance. Called by Unity when initializing a Mono...
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14