Spring.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using System;
  2. using UnityEngine;
  3. namespace HQFPSWeapons
  4. {
  5. public class Spring
  6. {
  7. public Vector3 Position { get { return m_LerpedPosition; } }
  8. public float Scale { get; set; }
  9. public float LerpSpeed { get; set; }
  10. private Vector3 m_Stiffness;
  11. private Vector3 m_Damping;
  12. private Type m_Type;
  13. private Transform m_Transform;
  14. private Vector3 m_Position;
  15. private Vector3 m_LerpedPosition;
  16. private Vector3 m_RestPosition;
  17. private Vector3 m_Velocity;
  18. private Vector3[] m_DistributedForce = new Vector3[100];
  19. public Spring(Type type, Transform transform = null, Vector3 restVector = default(Vector3))
  20. {
  21. Scale = 1f;
  22. m_Type = type;
  23. m_Transform = transform;
  24. m_RestPosition = restVector;
  25. }
  26. public void Reset()
  27. {
  28. m_Position = Vector3.zero;
  29. m_Velocity = Vector3.zero;
  30. for (int i = 0; i < 100; i ++)
  31. m_DistributedForce[i] = Vector3.zero;
  32. }
  33. public void Adjust(Vector3 stiffness, Vector3 damping)
  34. {
  35. m_Stiffness = stiffness;
  36. m_Damping = damping;
  37. }
  38. public void Adjust(Data data)
  39. {
  40. m_Stiffness = data.Stiffness;
  41. m_Damping = data.Damping;
  42. }
  43. public void FixedUpdate()
  44. {
  45. // Handle distributed forces.
  46. if(m_DistributedForce[0] != Vector3.zero)
  47. {
  48. AddForce(m_DistributedForce[0]);
  49. for(int i = 0; i < 100; i ++)
  50. {
  51. m_DistributedForce[i] = i < 99 ? m_DistributedForce[i + 1] : Vector3.zero;
  52. if(m_DistributedForce[i] == Vector3.zero)
  53. break;
  54. }
  55. }
  56. UpdateSpring();
  57. UpdatePosition();
  58. }
  59. public void Update()
  60. {
  61. if (LerpSpeed > 0f)
  62. m_LerpedPosition = Vector3.Lerp(m_LerpedPosition, m_Position, Time.deltaTime * LerpSpeed);
  63. else
  64. m_LerpedPosition = m_Position;
  65. UpdateTransform();
  66. }
  67. public void AddForce(SpringForce force)
  68. {
  69. if(force.Distribution > 1)
  70. AddDistributedForce(force.Force, force.Distribution);
  71. else
  72. AddForce(force.Force);
  73. }
  74. public void AddForce(Vector3 forceVector)
  75. {
  76. m_Velocity += forceVector;
  77. UpdatePosition();
  78. }
  79. public void AddForce(Vector3 forceVector, int distribution)
  80. {
  81. if(distribution > 1)
  82. AddDistributedForce(forceVector, distribution);
  83. else
  84. AddForce(forceVector);
  85. }
  86. public void AddDistributedForce(Vector3 force, int distribution)
  87. {
  88. distribution = Mathf.Clamp(distribution, 1, 100);
  89. AddForce(force / distribution);
  90. for(int i = 0; i < Mathf.RoundToInt(distribution) - 1; i++)
  91. m_DistributedForce[i] += force / distribution;
  92. }
  93. private void UpdateSpring()
  94. {
  95. m_Velocity += Vector3.Scale((m_RestPosition - m_Position), m_Stiffness);
  96. m_Velocity = Vector3.Scale(m_Velocity, Vector3.one - m_Damping);
  97. }
  98. private void UpdatePosition()
  99. {
  100. m_Position = MATH_UTILS.GetNaNSafeVector3((m_Position + m_Velocity) * Scale);
  101. }
  102. private void UpdateTransform()
  103. {
  104. if(m_Type == Type.DontUpdate)
  105. return;
  106. if(m_Type == Type.OverrideLocalPosition)
  107. m_Transform.localPosition = m_LerpedPosition;
  108. else if(m_Type == Type.AddToLocalPosition)
  109. m_Transform.localPosition += m_LerpedPosition;
  110. else if(m_Type == Type.OverrideLocalRotation)
  111. m_Transform.localEulerAngles = m_LerpedPosition;
  112. else if(m_Type == Type.AddToLocalRotation)
  113. m_Transform.localEulerAngles += m_LerpedPosition;
  114. }
  115. #region
  116. public enum Type
  117. {
  118. DontUpdate,
  119. OverrideLocalPosition,
  120. AddToLocalPosition,
  121. OverrideLocalRotation,
  122. AddToLocalRotation
  123. }
  124. [Serializable]
  125. public struct Data
  126. {
  127. public static Data Default { get { return new Data() { Stiffness = Vector3.one * 0.1f, Damping = Vector3.one * 0.25f }; } }
  128. public Vector3 Stiffness;
  129. public Vector3 Damping;
  130. }
  131. #endregion
  132. }
  133. }