Switching from AR to MR

Being able to switch scenes and maintain state is common task, but it seems to require a bit of work in Unity. Open up the Unity editor to the Navigation scene and complete the following:

  1. Open up the Assets/HoloCore/Scripts folder and create a new script called Singleton. Go to the book's downloaded source Code/Chapter_10 folder, copy the contents of the Singleton.cs file, and paste it into your new script. A Singleton is common pattern in Unity for creating an object you only want one of and when you never want that object destroyed. If you are new to Singleton, it will be in your best interest to spend some time and review the class.
  2. Create a new script in the same folder called SceneController and replace the generated code with the following:
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using Wrld;
using Wrld.Space;
namespace Packt.HoloCore
{
public class SceneController : Singleton<SceneController>
{
protected SceneController() { }
}
}
  1. SceneController is a Singleton with a SceneController. That circular reference may be a little confusing, so it is best to think of as a SceneController that is a Singleton which holds the SceneController type. Inside the class, we need to define a protected default constructor in order to force access through the Instance. We will look at how to use Instance shortly.
  2. Enter the following right after the constructor:
public LatLongAltitude position;
  1. Next, we will add a single property to hold the position where the camera was last fixed. That way, when we switch scenes, we can just pass the position property back to the scene so that it can determine where to setup. LatLongAltitude is a spatial data type that holds the position of the camera in latitude, longitude, and altitude.
  2. Add the following new method, LoadScene, with the following code:
public void LoadScene(string scene, Camera mapCamera)
{
if (Api.Instance.CameraApi.HasControlledCamera)
{
mapCamera = Api.Instance.CameraApi.GetControlledCamera();
}
if(mapCamera == null) throw new ArgumentNullException("Camera", "Camera must be set, if map is not controlled.");

position = Api.Instance.CameraApi.ScreenToGeographicPoint(new Vector3(mapCamera.pixelHeight/2, mapCamera.pixelWidth/2, mapCamera.nearClipPlane), mapCamera);

SceneManager.LoadScene(scene, LoadSceneMode.Single);
}
  1. LoadScene, is where all the work happens. We will call LoadScene on the SceneController, passing in the scene name we want to load at the current map or WRLD camera. Inside the method, we first test to see whether the current map is being controlled; if it is, we just ignore the camera and use the controlled camera. Next, we test whether the mapCamera is null; if it is, we want to exit with an error. Otherwise, we extract the current position with ScreenToGeographicPoint. This method extracts the camera's main screen focal point, which we assume is at half pixel width and height of the screen; mapCamera.nearClipPlane sets the front of view frustum or camera if you recall from our earlier discussions, which equals the altitude of the camera above ground level, or the map in this case. At the end of the method, we use SceneManager, which is the Unity helper class for loading scenes. We call LoadScene with the option to replace the scene using LoadSceneMode.Single.

That completes our SceneController. Now, the useful thing about being a Singleton is that we never have to physically add the component, because it is now always considered available. WRLD bases most of their Unity API on this pattern as well. We do still have to add some further code that can be activated from our scene.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.187