CinemachineInputProvider.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #if CINEMACHINE_UNITY_INPUTSYSTEM
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.InputSystem;
  5. using UnityEngine.InputSystem.Users;
  6. namespace Cinemachine
  7. {
  8. /// <summary>
  9. /// This is an add-on to override the legacy input system and read input using the
  10. /// UnityEngine.Input package API. Add this behaviour to any CinemachineVirtualCamera
  11. /// or FreeLook that requires user input, and drag in the the desired actions.
  12. /// </summary>
  13. [HelpURL(Documentation.BaseURL + "manual/CinemachineAlternativeInput.html")]
  14. public class CinemachineInputProvider : MonoBehaviour, AxisState.IInputAxisProvider
  15. {
  16. /// <summary>
  17. /// Leave this at -1 for single-player games.
  18. /// For multi-player games, set this to be the player index, and the actions will
  19. /// be read from that player's controls
  20. /// </summary>
  21. [Tooltip("Leave this at -1 for single-player games. "
  22. + "For multi-player games, set this to be the player index, and the actions will "
  23. + "be read from that player's controls")]
  24. public int PlayerIndex = -1;
  25. /// <summary>Vector2 action for XY movement</summary>
  26. [Tooltip("Vector2 action for XY movement")]
  27. public InputActionReference XYAxis;
  28. /// <summary>Float action for Z movement</summary>
  29. [Tooltip("Float action for Z movement")]
  30. public InputActionReference ZAxis;
  31. /// <summary>
  32. /// Implementation of AxisState.IInputAxisProvider.GetAxisValue().
  33. /// Axis index ranges from 0...2 for X, Y, and Z.
  34. /// Reads the action associated with the axis.
  35. /// </summary>
  36. /// <param name="axis"></param>
  37. /// <returns>The current axis value</returns>
  38. public virtual float GetAxisValue(int axis)
  39. {
  40. var action = ResolveForPlayer(axis, axis == 2 ? ZAxis : XYAxis);
  41. if (action != null)
  42. {
  43. switch (axis)
  44. {
  45. case 0: return action.ReadValue<Vector2>().x;
  46. case 1: return action.ReadValue<Vector2>().y;
  47. case 2: return action.ReadValue<float>();
  48. }
  49. }
  50. return 0;
  51. }
  52. const int NUM_AXES = 3;
  53. InputAction[] m_cachedActions;
  54. /// <summary>
  55. /// In a multi-player context, actions are associated with specific players
  56. /// This resolves the appropriate action reference for the specified player.
  57. ///
  58. /// Because the resolution involves a search, we also cache the returned
  59. /// action to make future resolutions faster.
  60. /// </summary>
  61. /// <param name="axis">Which input axis (0, 1, or 2)</param>
  62. /// <param name="actionRef">Which action reference to resolve</param>
  63. /// <returns>The cached action for the player specified in PlayerIndex</returns>
  64. protected InputAction ResolveForPlayer(int axis, InputActionReference actionRef)
  65. {
  66. if (axis < 0 || axis >= NUM_AXES)
  67. return null;
  68. if (actionRef == null || actionRef.action == null)
  69. return null;
  70. if (m_cachedActions == null || m_cachedActions.Length != NUM_AXES)
  71. m_cachedActions = new InputAction[NUM_AXES];
  72. if (m_cachedActions[axis] != null && actionRef.action.id != m_cachedActions[axis].id)
  73. m_cachedActions[axis] = null;
  74. if (m_cachedActions[axis] == null)
  75. {
  76. m_cachedActions[axis] = actionRef.action;
  77. if (PlayerIndex != -1)
  78. {
  79. var user = InputUser.all[PlayerIndex];
  80. m_cachedActions[axis] = user.actions.First(x => x.id == actionRef.action.id);
  81. }
  82. }
  83. // Auto-enable it if disabled
  84. if (m_cachedActions[axis] != null && !m_cachedActions[axis].enabled)
  85. m_cachedActions[axis].Enable();
  86. return m_cachedActions[axis];
  87. }
  88. // Clean up
  89. protected virtual void OnDisable()
  90. {
  91. m_cachedActions = null;
  92. }
  93. }
  94. }
  95. #else
  96. using UnityEngine;
  97. namespace Cinemachine
  98. {
  99. [AddComponentMenu("")] // Hide in menu
  100. public class CinemachineInputProvider : MonoBehaviour {}
  101. }
  102. #endif