zombie_mp/Assets/HQ FPS Weapons/Scripts/Equipment/Physics/Spring.cs
Sewmina Dilshan 68183e5317 initial
2021-08-23 13:28:33 +05:30

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
}
}