Advertisement
Guest User

Untitled

a guest
Jan 29th, 2020
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using UnityEngine.InputSystem;
  4. using UnityEngine.InputSystem.LowLevel;
  5. using System.Linq;
  6. using System;
  7. using UnityEngine.InputSystem.Controls;
  8.  
  9. public class ControlRebindingUI : MonoBehaviour
  10. {
  11. public Button m_Button;
  12. public Text m_Text;
  13. public InputActionReference m_ActionReference;
  14. public int m_DefaultBindingIndex;
  15. public Button[] m_CompositeButtons;
  16. public Text[] m_CompositeTexts;
  17.  
  18. private InputAction m_Action;
  19. private InputActionRebindingExtensions.RebindingOperation m_RebindOperation;
  20. private int[] m_CompositeBindingIndices;
  21. private string m_CompositeType;
  22. private bool m_IsUsingComposite;
  23.  
  24. public void Start()
  25. {
  26. m_Action = m_ActionReference.action;
  27. if (m_Button == null)
  28. m_Button = GetComponentInChildren<Button>();
  29. if (m_Text == null)
  30. m_Text = m_Button.GetComponentInChildren<Text>();
  31.  
  32. m_Button.onClick.AddListener(delegate { RemapButtonClicked(name, m_DefaultBindingIndex); });
  33. if (m_CompositeButtons != null && m_CompositeButtons.Length > 0)
  34. {
  35. if (m_CompositeTexts == null || m_CompositeTexts.Length != m_CompositeButtons.Length)
  36. m_CompositeTexts = new Text[m_CompositeButtons.Length];
  37. m_CompositeBindingIndices = Enumerable.Range(0, m_Action.bindings.Count)
  38. .Where(x => m_Action.bindings[x].isPartOfComposite).ToArray();
  39. var compositeBinding = m_Action.bindings.First(x => x.isComposite);
  40. m_CompositeType = compositeBinding.name;
  41. for (int i = 0; i < m_CompositeButtons.Length && i < m_CompositeBindingIndices.Length; i++)
  42. {
  43. int compositeBindingIndex = m_CompositeBindingIndices[i];
  44. m_CompositeButtons[i].onClick.AddListener(delegate { RemapButtonClicked(name, compositeBindingIndex); });
  45. if (m_CompositeTexts[i] == null)
  46. m_CompositeTexts[i] = m_CompositeButtons[i].GetComponentInChildren<Text>();
  47. }
  48. }
  49. ResetButtonMappingTextValue();
  50. }
  51.  
  52. private void OnDestroy()
  53. {
  54. m_RebindOperation?.Dispose();
  55. }
  56.  
  57. private bool ControlMatchesCompositeType(InputControl control, string compositeType)
  58. {
  59. if (compositeType == null)
  60. return true;
  61.  
  62. if (compositeType == "2D Vector")
  63. return typeof(InputControl<Vector2>).IsInstanceOfType(control);
  64.  
  65. if (compositeType == "1D Axis")
  66. return typeof(AxisControl).IsInstanceOfType(control) && !typeof(ButtonControl).IsInstanceOfType(control);
  67.  
  68. throw new ArgumentException($"{compositeType} is not a known composite type", nameof(compositeType));
  69. }
  70.  
  71. private unsafe float ScoreFunc(string compositeType, InputControl control, InputEventPtr eventPtr)
  72. {
  73. var statePtr = control.GetStatePtrFromStateEvent(eventPtr);
  74. var magnitude = control.EvaluateMagnitude(statePtr);
  75.  
  76. if (control.synthetic)
  77. return magnitude - 1;
  78.  
  79. // Give preference to controls which match the expected type (ie get the Vector2 for a Stick,
  80. // rather than individual axes), but allow other types to let us construct the control as a
  81. // composite.
  82. if (ControlMatchesCompositeType(control, m_CompositeType))
  83. return magnitude + 1;
  84.  
  85. return magnitude;
  86. }
  87.  
  88. void RemapButtonClicked(string name, int bindingIndex = 0)
  89. {
  90. m_Button.enabled = false;
  91. m_Text.text = "Press button/stick for " + name;
  92. m_RebindOperation?.Dispose();
  93. m_RebindOperation = m_Action.PerformInteractiveRebinding()
  94. .WithControlsExcluding("<Mouse>/position")
  95. .WithControlsExcluding("<Mouse>/delta")
  96. .OnMatchWaitForAnother(0.1f)
  97. .OnComplete(operation => ButtonRebindCompleted());
  98. if (m_CompositeBindingIndices != null)
  99. {
  100. m_RebindOperation = m_RebindOperation
  101. .OnComputeScore((x, y) => ScoreFunc(m_CompositeType, x, y))
  102. .OnGeneratePath(x =>
  103. {
  104. if (!ControlMatchesCompositeType(x, m_CompositeType))
  105. m_IsUsingComposite = true;
  106. else
  107. m_IsUsingComposite = false;
  108. return null;
  109. })
  110. .OnApplyBinding((x, path) =>
  111. {
  112. if (m_IsUsingComposite)
  113. {
  114. m_Action.ApplyBindingOverride(m_DefaultBindingIndex, "");
  115. m_Action.ApplyBindingOverride(
  116. bindingIndex != m_DefaultBindingIndex ? bindingIndex : m_CompositeBindingIndices[0],
  117. path);
  118. }
  119. else
  120. {
  121. m_Action.ApplyBindingOverride(m_DefaultBindingIndex, path);
  122. foreach (var i in m_CompositeBindingIndices)
  123. m_Action.ApplyBindingOverride(i, "");
  124. }
  125. });
  126. }
  127. m_RebindOperation.Start();
  128. }
  129.  
  130. void ResetButtonMappingTextValue()
  131. {
  132. m_Text.text = InputControlPath.ToHumanReadableString(m_Action.bindings[0].effectivePath);
  133. m_Button.gameObject.SetActive(!m_IsUsingComposite);
  134. if (m_CompositeTexts != null)
  135. for (int i = 0; i < m_CompositeTexts.Length; i++)
  136. {
  137. m_CompositeTexts[i].text = InputControlPath.ToHumanReadableString(m_Action.bindings[m_CompositeBindingIndices[i]].effectivePath);
  138. m_CompositeButtons[i].gameObject.SetActive(m_IsUsingComposite);
  139. }
  140. }
  141.  
  142. void ButtonRebindCompleted()
  143. {
  144. m_RebindOperation.Dispose();
  145. m_RebindOperation = null;
  146. ResetButtonMappingTextValue();
  147. m_Button.enabled = true;
  148. }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement