using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; #if URP_PRESENT using UnityEngine.Rendering.Universal; #endif #if HDRP_PRESENT using UnityEngine.Rendering.HighDefinition; #endif #if ENABLE_VR || ENABLE_AR using UnityEngine.SpatialTracking; #if XRI_PRESENT #else namespace UnityEditor.XR.LegacyInputHelpers { internal static class MenuUtils { static readonly string kMainCamera = "MainCamera"; static readonly Vector3 kDefaultCameraPosition = new Vector3(0.0f, 1.0f, -10.0f); const float kDefaultCameraNearClip = 0.01f; static bool CreateSimpleXRRig(Camera xrCamera, out GameObject gameObj) { var xrRigGO = ObjectFactory.CreateGameObject("XRRig"); var cameraOffsetGO = ObjectFactory.CreateGameObject("Camera Offset"); Undo.SetTransformParent(cameraOffsetGO.transform, xrRigGO.transform, "Parent Camera Offset to XR Rig"); Pose camPose = new Pose(); // we only want to move the rig to the camera position if one is passed in. bool camExistsAndNeedsMoving = false; if (xrCamera == null) { var xrCameraGO = ObjectFactory.CreateGameObject("Main Camera", typeof(Camera)); xrCamera = xrCameraGO.GetComponent(); } else { camPose.position = xrCamera.transform.position; // if initial camera position, move to the floor if(camPose.position == kDefaultCameraPosition) { camPose.position.y = 0.0f; } camPose.rotation = xrCamera.transform.rotation; camExistsAndNeedsMoving = true; } Undo.SetTransformParent(xrCamera.transform, cameraOffsetGO.transform, "Parent Camera to Camera Offset"); // Override the near clip to better handle controllers near the face xrCamera.nearClipPlane = kDefaultCameraNearClip; xrCamera.transform.localPosition = Vector3.zero; xrCamera.transform.localRotation = Quaternion.identity; xrCamera.tag = kMainCamera; if (camExistsAndNeedsMoving) { xrRigGO.transform.position = camPose.position; xrRigGO.transform.rotation = camPose.rotation; } TrackedPoseDriver trackedPoseDriver = xrCamera.gameObject.GetComponent(); if (trackedPoseDriver == null) { trackedPoseDriver = Undo.AddComponent(xrCamera.gameObject); } trackedPoseDriver.SetPoseSource(TrackedPoseDriver.DeviceType.GenericXRDevice, TrackedPoseDriver.TrackedPose.Center); trackedPoseDriver.UseRelativeTransform = false; var coh = xrRigGO.AddComponent(); coh.cameraFloorOffsetObject = cameraOffsetGO; #if UNITY_2019_3_OR_NEWER coh.TrackingOriginMode = UnityEngine.XR.TrackingOriginModeFlags.Device; #else coh.trackingSpace = UnityEngine.XR.TrackingSpaceType.Stationary; #endif gameObj = xrRigGO; Selection.activeGameObject = xrRigGO; return true; } static Camera VerifyWeCanUpgrade() { Debug.Log("Determining if we can automatically upgrade this scene to use an XR Rig"); // rules are // only upgrade an empty scene with a directional light and a camera at the root node. var xrCameraList = Object.FindObjectsOfType(); Debug.Log("Checking number of cameras in the scene"); if (xrCameraList.Length > 1) { // if the camera exists, and isn't at the root node. bail. Debug.LogError("You have more than one camera in your scene. We are unable to automatically convert your scene. Please see the documentation on how to upgrade your scene."); return null; } else if (xrCameraList.Length == 0) { Debug.LogError("You have no cameras in your scene. We are unable to automatically convert your scene. Please see the documentation on how to upgrade your scene."); return null; } var xrCamera = xrCameraList.Length > 0 ? xrCameraList[0] : null; if (xrCamera != null) { Debug.Log("Checking Main Camera is at the root of the hierarchy"); if (!(xrCamera.tag == kMainCamera && xrCamera.transform != null && xrCamera.transform.parent == null)) { // if the camera exists, and isn't at the root node. bail. Debug.LogError("Your Main Camera is not at the root of your hierarchy. We are unable to automatically convert your scene. Please see the documentation on how to upgrade your scene."); return null; } Debug.Log("Checking camera components"); List componentList = new List(xrCamera.gameObject.GetComponents(typeof(MonoBehaviour))); if (componentList.Count != 0) { #if HDRP_PRESENT_10_0 if (!xrCamera.IsHDCamera()) #endif #if HDRP_PRESENT_10_1_OR_NEWER if (!ComponentUtility.IsHDCamera(xrCamera)) #endif #if URP_PRESENT_10_0 if (!xrCamera.IsUniversalCamera()) #endif #if URP_PRESENT_10_1_OR_NEWER if (!ComponentUtility.IsUniversalCamera(xrCamera)) #endif #if HDRP_PRESENT && !HDRP_PRESENT_10_1_OR_NEWER && !HDRP_PRESENT_10_0 if (!(componentList.Count <= 2 && componentList.Find(x => x.GetType() == typeof(HDAdditionalCameraData)))) #endif #if URP_PRESENT && !URP_PRESENT_10_1_OR_NEWER && !URP_PRESENT_10_0 if (!(componentList.Count <= 2 && componentList.Find(x => x.GetType() == typeof(UniversalAdditionalCameraData)))) #endif { Debug.LogError("Your Main Camera has additional components that we do not recognize. We are unable to automatically convert your scene. Please see the documentation on how to upgrade your scene."); return null; } } return xrCamera; } return null; } [MenuItem("GameObject/XR/Convert Main Camera To XR Rig", false, 10)] static void UpgradeToXRRig() { var xrCamera = VerifyWeCanUpgrade(); if (xrCamera != null) { GameObject vrCameraRig; CreateSimpleXRRig(xrCamera, out vrCameraRig); } } } } #endif #endif