CinemachineInputAxisDriver.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using UnityEngine;
  3. using Cinemachine.Utility;
  4. namespace Cinemachine
  5. {
  6. [Serializable]
  7. public struct AxisBase
  8. {
  9. /// <summary>The current value of the axis</summary>
  10. [NoSaveDuringPlay]
  11. [Tooltip("The current value of the axis.")]
  12. public float m_Value;
  13. /// <summary>The minimum value for the axis</summary>
  14. [Tooltip("The minimum value for the axis")]
  15. public float m_MinValue;
  16. /// <summary>The maximum value for the axis</summary>
  17. [Tooltip("The maximum value for the axis")]
  18. public float m_MaxValue;
  19. /// <summary>If checked, then the axis will wrap around at the min/max values, forming a loop</summary>
  20. [Tooltip("If checked, then the axis will wrap around at the min/max values, forming a loop")]
  21. public bool m_Wrap;
  22. public void Validate()
  23. {
  24. m_MaxValue = Mathf.Clamp(m_MaxValue, m_MinValue, m_MaxValue);
  25. }
  26. }
  27. [Serializable]
  28. public struct CinemachineInputAxisDriver
  29. {
  30. [Tooltip("Multiply the input by this amount prior to processing. Controls the input power.")]
  31. public float multiplier;
  32. [Tooltip("The amount of time in seconds it takes to accelerate to a higher speed")]
  33. public float accelTime;
  34. [Tooltip("The amount of time in seconds it takes to decelerate to a lower speed")]
  35. public float decelTime;
  36. [Tooltip("The name of this axis as specified in Unity Input manager. "
  37. + "Setting to an empty string will disable the automatic updating of this axis")]
  38. public string name;
  39. [NoSaveDuringPlay]
  40. [Tooltip("The value of the input axis. A value of 0 means no input. You can drive "
  41. + "this directly from a custom input system, or you can set the Axis Name and "
  42. + "have the value driven by the internal Input Manager")]
  43. public float inputValue;
  44. /// Internal state
  45. private float mCurrentSpeed;
  46. const float Epsilon = UnityVectorExtensions.Epsilon;
  47. /// Call from OnValidate: Make sure the fields are sensible
  48. public void Validate()
  49. {
  50. accelTime = Mathf.Max(0, accelTime);
  51. decelTime = Mathf.Max(0, decelTime);
  52. }
  53. public bool Update(float deltaTime, ref AxisBase axis)
  54. {
  55. if (!string.IsNullOrEmpty(name))
  56. {
  57. try { inputValue = CinemachineCore.GetInputAxis(name); }
  58. catch (ArgumentException) {}
  59. //catch (ArgumentException e) { Debug.LogError(e.ToString()); }
  60. }
  61. float input = inputValue * multiplier;
  62. if (deltaTime < Epsilon)
  63. mCurrentSpeed = 0;
  64. else
  65. {
  66. float speed = input / deltaTime;
  67. float dampTime = Mathf.Abs(speed) < Mathf.Abs(mCurrentSpeed) ? decelTime : accelTime;
  68. speed = mCurrentSpeed + Damper.Damp(speed - mCurrentSpeed, dampTime, deltaTime);
  69. mCurrentSpeed = speed;
  70. // Decelerate to the end points of the range if not wrapping
  71. float range = axis.m_MaxValue - axis.m_MinValue;
  72. if (!axis.m_Wrap && decelTime > Epsilon && range > Epsilon)
  73. {
  74. float v0 = ClampValue(ref axis, axis.m_Value);
  75. float v = ClampValue(ref axis, v0 + speed * deltaTime);
  76. float d = (speed > 0) ? axis.m_MaxValue - v : v - axis.m_MinValue;
  77. if (d < (0.1f * range) && Mathf.Abs(speed) > Epsilon)
  78. speed = Damper.Damp(v - v0, decelTime, deltaTime) / deltaTime;
  79. }
  80. input = speed * deltaTime;
  81. }
  82. axis.m_Value = ClampValue(ref axis, axis.m_Value + input);
  83. return Mathf.Abs(inputValue) > Epsilon;
  84. }
  85. float ClampValue(ref AxisBase axis, float v)
  86. {
  87. float r = axis.m_MaxValue - axis.m_MinValue;
  88. if (axis.m_Wrap && r > Epsilon)
  89. {
  90. v = (v - axis.m_MinValue) % r;
  91. v += axis.m_MinValue + ((v < 0) ? r : 0);
  92. }
  93. return Mathf.Clamp(v, axis.m_MinValue, axis.m_MaxValue);
  94. }
  95. /// <summary>
  96. /// Support for legacy AxisState struct
  97. /// </summary>
  98. /// <param name="deltaTime"></param>
  99. /// <param name="axis"></param>
  100. /// <returns></returns>
  101. public bool Update(float deltaTime, ref AxisState axis)
  102. {
  103. var a = new AxisBase
  104. {
  105. m_Value = axis.Value,
  106. m_MinValue = axis.m_MinValue,
  107. m_MaxValue = axis.m_MaxValue,
  108. m_Wrap = axis.m_Wrap
  109. };
  110. bool changed = Update(deltaTime, ref a);
  111. axis.Value = a.m_Value;
  112. return changed;
  113. }
  114. }
  115. }