void CreateControllerInfos() { VrControllers vrControllers = App.VrSdk.VrControls; if (vrControllers != null) { BaseControllerBehavior[] behaviors = vrControllers.GetBehaviors(); if (behaviors.Length != (int)ControllerName.Num) { Debug.LogErrorFormat("Expected {0} controllers, have {1}", (int)ControllerName.Num, behaviors.Length); } m_ControllerInfos = new ControllerInfo[behaviors.Length]; for (int i = 0; i < m_ControllerInfos.Length; ++i) { bool isLeft = i == 0; m_ControllerInfos[i] = App.VrSdk.CreateControllerInfo(behaviors[i], isLeft); } } }
// Destroy and recreate the ControllerBehavior and ControllerGeometry objects. // This is mostly useful if you want different geometry. // // TODO: this will always give the wand left-hand geometry and the brush right-hand geometry, // so InputManager.WandOnRight should probably be reset to false after this? Or maybe // SetControllerStyle should be smart enough to figure that out. public void SetControllerStyle(ControllerStyle style) { Debug.Log("Calling SetControllerStyle"); // Clear console parent in case we're switching controllers. if (ControllerConsoleScript.m_Instance != null) { ControllerConsoleScript.m_Instance.transform.parent = null; } // Clean up existing controllers. // Note that we are explicitly not transferring state. This is because, in practice, // we only change controller style when we're initializing SteamVR, and the temporary // controllers are largely disabled. Any bugs that occur will be trivial and cosmetic. // If we add the ability to dynamically change controllers or my above comment about // trivial bugs is not true, state transfer should occur here. // // In practice, the only style transitions we should see are: // - None -> correct style During VrSdk.Awake() // - None -> InitializingSteamVr During VrSdk.Awake() // InitializingSteamVr -> correct style Many frames after VrSdk.Awake() if (m_VrControls != null) { Destroy(m_VrControls.gameObject); m_VrControls = null; } m_NeedsToAttachConsoleScript = true; GameObject controlsPrefab; switch (style) { case ControllerStyle.Vive: controlsPrefab = m_SteamViveControlsPrefab; break; case ControllerStyle.Knuckles: controlsPrefab = m_SteamKnucklesControlsPrefab; break; case ControllerStyle.Cosmos: controlsPrefab = m_SteamCosmoControlsPrefab; break; case ControllerStyle.OculusTouch: { // This will probably not work once new headsets are released. // Maybe something like this instead? // isQuest = (UnityEngine.XR.XRDevice.model != "Oculus Rift CV1"); bool isQuestController = (UnityEngine.XR.XRDevice.refreshRate < 81f) || (App.Config.VrHardware == VrHardware.Quest); if (App.Config.m_SdkMode == SdkMode.Oculus) { controlsPrefab = isQuestController ? m_OculusQuestControlsPrefab : m_OculusRiftControlsPrefab; } else /* Assume SteamVR */ { controlsPrefab = isQuestController ? m_SteamQuestControlsPrefab : m_SteamRiftControlsPrefab; } break; } case ControllerStyle.Wmr: controlsPrefab = m_SteamWmrControlsPrefab; break; case ControllerStyle.Gvr: controlsPrefab = m_GvrPointerControlsPrefab; break; case ControllerStyle.None: controlsPrefab = m_NonVrControlsPrefab; m_NeedsToAttachConsoleScript = false; break; case ControllerStyle.InitializingSteamVR: controlsPrefab = m_SteamUninitializedControlsPrefab; m_NeedsToAttachConsoleScript = false; break; case ControllerStyle.Unset: default: controlsPrefab = null; m_NeedsToAttachConsoleScript = false; break; } #if UNITY_EDITOR // This is _just_ robust enough to be able to switch between the Rift and Touch // controllers. To force (for example) a Wmr controller when using a Touch will // probably require being able to specify an override style as well, because TB // might act funny if we spawn a Wmr prefab with style OculusTouch. // Additionally, the Logitech Pen override happens after this, so there's no way // to override it. // Wait for the "real" SetControllerStyle to come through. if (style != ControllerStyle.InitializingSteamVR) { GameObject overridePrefab = null; switch (App.Config.m_SdkMode) { case SdkMode.Oculus: overridePrefab = App.Config.m_ControlsPrefabOverrideOvr; break; case SdkMode.SteamVR: overridePrefab = App.Config.m_ControlsPrefabOverrideSteamVr; break; } if (overridePrefab != null) { Debug.LogWarning("Overriding Vr controls with {0}", overridePrefab); controlsPrefab = overridePrefab; } } #endif if (controlsPrefab != null) { Debug.Assert(m_VrControls == null); GameObject controlsObject = Instantiate(controlsPrefab); m_VrControls = controlsObject.GetComponent <VrControllers>(); if (m_VrControls == null) { throw new InvalidOperationException( string.Format("Bad prefab for {0} {1}", style, controlsPrefab)); } m_VrControls.transform.parent = m_VrSystem.transform; } if (m_VrControls != null) { if (m_NeedsToAttachConsoleScript && ControllerConsoleScript.m_Instance) { ControllerConsoleScript.m_Instance.AttachToController( m_VrControls.Brush); m_NeedsToAttachConsoleScript = false; } // TODO: the only case where this is necessary is when using empty geometry // for ControllerStyle.InitializingSteamVR. Can we keep track of "initializing" // some other way? m_VrControls.Brush.ControllerGeometry.TempWritableStyle = style; m_VrControls.Wand.ControllerGeometry.TempWritableStyle = style; } }