|
|
- namespace VRTK
- {
- using System.Collections;
- using System.Linq;
- using System.Reflection;
- using UnityEngine.EventSystems;
-
- public class VRTK_EventSystem : EventSystem
- {
- protected EventSystem previousEventSystem;
- protected VRTK_VRInputModule vrInputModule;
-
- private static readonly FieldInfo[] EVENT_SYSTEM_FIELD_INFOS = typeof(EventSystem).GetFields(BindingFlags.Public | BindingFlags.Instance);
- private static readonly PropertyInfo[] EVENT_SYSTEM_PROPERTY_INFOS = typeof(EventSystem).GetProperties(BindingFlags.Public | BindingFlags.Instance).Except(new[] { typeof(EventSystem).GetProperty("enabled") }).ToArray();
- private static readonly FieldInfo BASE_INPUT_MODULE_EVENT_SYSTEM_FIELD_INFO = typeof(BaseInputModule).GetField("m_EventSystem", BindingFlags.NonPublic | BindingFlags.Instance);
-
- protected override void OnEnable()
- {
- previousEventSystem = current;
- if (previousEventSystem != null)
- {
- previousEventSystem.enabled = false;
- CopyValuesFrom(previousEventSystem, this);
- }
-
- vrInputModule = gameObject.AddComponent<VRTK_VRInputModule>();
- base.OnEnable();
- StartCoroutine(SetEventSystemOfBaseInputModulesAfterFrameDelay(this));
- }
-
- protected override void OnDisable()
- {
- base.OnDisable();
- Destroy(vrInputModule);
-
- if (previousEventSystem != null)
- {
- previousEventSystem.enabled = true;
- CopyValuesFrom(this, previousEventSystem);
- SetEventSystemOfBaseInputModules(previousEventSystem);
- }
- }
-
- protected override void Update()
- {
- base.Update();
-
- if (current == this)
- {
- vrInputModule.Process();
- }
- }
-
- #if UNITY_5_5_OR_NEWER
- protected override void OnApplicationFocus(bool hasFocus)
- {
- //Don't call the base implementation because it will set a pause flag for this EventSystem
- }
- #endif
-
- private static void CopyValuesFrom(EventSystem fromEventSystem, EventSystem toEventSystem)
- {
- foreach (FieldInfo fieldInfo in EVENT_SYSTEM_FIELD_INFOS)
- {
- fieldInfo.SetValue(toEventSystem, fieldInfo.GetValue(fromEventSystem));
- }
-
- foreach (PropertyInfo propertyInfo in EVENT_SYSTEM_PROPERTY_INFOS)
- {
- if (propertyInfo.CanWrite)
- {
- propertyInfo.SetValue(toEventSystem, propertyInfo.GetValue(fromEventSystem, null), null);
- }
- }
- }
-
- private static IEnumerator SetEventSystemOfBaseInputModulesAfterFrameDelay(EventSystem eventSystem)
- {
- yield return null;
- SetEventSystemOfBaseInputModules(eventSystem);
- }
- private static void SetEventSystemOfBaseInputModules(EventSystem eventSystem)
- {
- /*
- BaseInputModule has a private field referencing the current EventSystem. That field is set in
- BaseInputModule.OnEnable only. It's used in BaseInputModule.OnEnable and BaseInputModule.OnDisable
- to call EventSystem.UpdateModules.
- This means we could just disable and enable every enabled BaseInputModule to fix that reference.
-
- But the StandaloneInputModule (which is added by default when adding an EventSystem in the Editor)
- requires EventSystem. Which means we can't correctly destroy the old EventSystem first and then add
- our own one.
- We therefore update that private reference directly here.
- */
- foreach (BaseInputModule module in FindObjectsOfType<BaseInputModule>())
- {
- BASE_INPUT_MODULE_EVENT_SYSTEM_FIELD_INFO.SetValue(module, eventSystem);
- }
-
- eventSystem.UpdateModules();
- }
- }
- }
|