168 lines
3.6 KiB
C#
168 lines
3.6 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace HQFPSWeapons
|
|
{
|
|
public class Spring
|
|
{
|
|
public Vector3 Position { get { return m_LerpedPosition; } }
|
|
|
|
public float Scale { get; set; }
|
|
|
|
public float LerpSpeed { get; set; }
|
|
|
|
private Vector3 m_Stiffness;
|
|
|
|
private Vector3 m_Damping;
|
|
|
|
private Type m_Type;
|
|
private Transform m_Transform;
|
|
|
|
private Vector3 m_Position;
|
|
private Vector3 m_LerpedPosition;
|
|
|
|
private Vector3 m_RestPosition;
|
|
private Vector3 m_Velocity;
|
|
private Vector3[] m_DistributedForce = new Vector3[100];
|
|
|
|
|
|
public Spring(Type type, Transform transform = null, Vector3 restVector = default(Vector3))
|
|
{
|
|
Scale = 1f;
|
|
|
|
m_Type = type;
|
|
m_Transform = transform;
|
|
|
|
m_RestPosition = restVector;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
m_Position = Vector3.zero;
|
|
m_Velocity = Vector3.zero;
|
|
|
|
for (int i = 0; i < 100; i ++)
|
|
m_DistributedForce[i] = Vector3.zero;
|
|
}
|
|
|
|
public void Adjust(Vector3 stiffness, Vector3 damping)
|
|
{
|
|
m_Stiffness = stiffness;
|
|
m_Damping = damping;
|
|
}
|
|
|
|
public void Adjust(Data data)
|
|
{
|
|
m_Stiffness = data.Stiffness;
|
|
m_Damping = data.Damping;
|
|
}
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
// Handle distributed forces.
|
|
if(m_DistributedForce[0] != Vector3.zero)
|
|
{
|
|
AddForce(m_DistributedForce[0]);
|
|
|
|
for(int i = 0; i < 100; i ++)
|
|
{
|
|
m_DistributedForce[i] = i < 99 ? m_DistributedForce[i + 1] : Vector3.zero;
|
|
if(m_DistributedForce[i] == Vector3.zero)
|
|
break;
|
|
}
|
|
}
|
|
|
|
UpdateSpring();
|
|
UpdatePosition();
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (LerpSpeed > 0f)
|
|
m_LerpedPosition = Vector3.Lerp(m_LerpedPosition, m_Position, Time.deltaTime * LerpSpeed);
|
|
else
|
|
m_LerpedPosition = m_Position;
|
|
|
|
UpdateTransform();
|
|
}
|
|
|
|
public void AddForce(SpringForce force)
|
|
{
|
|
if(force.Distribution > 1)
|
|
AddDistributedForce(force.Force, force.Distribution);
|
|
else
|
|
AddForce(force.Force);
|
|
}
|
|
|
|
public void AddForce(Vector3 forceVector)
|
|
{
|
|
m_Velocity += forceVector;
|
|
|
|
UpdatePosition();
|
|
}
|
|
|
|
public void AddForce(Vector3 forceVector, int distribution)
|
|
{
|
|
if(distribution > 1)
|
|
AddDistributedForce(forceVector, distribution);
|
|
else
|
|
AddForce(forceVector);
|
|
}
|
|
|
|
public void AddDistributedForce(Vector3 force, int distribution)
|
|
{
|
|
distribution = Mathf.Clamp(distribution, 1, 100);
|
|
|
|
AddForce(force / distribution);
|
|
|
|
for(int i = 0; i < Mathf.RoundToInt(distribution) - 1; i++)
|
|
m_DistributedForce[i] += force / distribution;
|
|
}
|
|
|
|
private void UpdateSpring()
|
|
{
|
|
m_Velocity += Vector3.Scale((m_RestPosition - m_Position), m_Stiffness);
|
|
m_Velocity = Vector3.Scale(m_Velocity, Vector3.one - m_Damping);
|
|
}
|
|
|
|
private void UpdatePosition()
|
|
{
|
|
m_Position = MATH_UTILS.GetNaNSafeVector3((m_Position + m_Velocity) * Scale);
|
|
}
|
|
|
|
private void UpdateTransform()
|
|
{
|
|
if(m_Type == Type.DontUpdate)
|
|
return;
|
|
|
|
if(m_Type == Type.OverrideLocalPosition)
|
|
m_Transform.localPosition = m_LerpedPosition;
|
|
else if(m_Type == Type.AddToLocalPosition)
|
|
m_Transform.localPosition += m_LerpedPosition;
|
|
else if(m_Type == Type.OverrideLocalRotation)
|
|
m_Transform.localEulerAngles = m_LerpedPosition;
|
|
else if(m_Type == Type.AddToLocalRotation)
|
|
m_Transform.localEulerAngles += m_LerpedPosition;
|
|
}
|
|
|
|
#region
|
|
public enum Type
|
|
{
|
|
DontUpdate,
|
|
OverrideLocalPosition,
|
|
AddToLocalPosition,
|
|
OverrideLocalRotation,
|
|
AddToLocalRotation
|
|
}
|
|
|
|
[Serializable]
|
|
public struct Data
|
|
{
|
|
public static Data Default { get { return new Data() { Stiffness = Vector3.one * 0.1f, Damping = Vector3.one * 0.25f }; } }
|
|
|
|
public Vector3 Stiffness;
|
|
public Vector3 Damping;
|
|
}
|
|
#endregion
|
|
}
|
|
} |