projectEli/Assets/NeoFPS/Core/Camera/AdditiveEffects/HeadDuck.cs
2022-11-06 20:28:33 -05:00

121 lines
3.3 KiB
C#

using UnityEngine;
using NeoSaveGames.Serialization;
using NeoSaveGames;
using NeoFPS.CharacterMotion;
using NeoFPS.CharacterMotion.Parameters;
using System;
namespace NeoFPS
{
[HelpURL("https://docs.neofps.com/manual/fpcamref-mb-headduck.html")]
public class HeadDuck : MonoBehaviour, IAdditiveTransform, INeoSerializableComponent
{
[SerializeField, Tooltip("The distance to duck the head downwards.")]
private string m_JumpChargeKey = "jumpCharge";
[SerializeField, Tooltip("The distance to duck the head downwards.")]
private float m_DuckHeight = 0.05f;
private static readonly NeoSerializationKey k_DuckKey = new NeoSerializationKey("duck");
private IAdditiveTransformHandler m_Handler = null;
private FloatParameter m_ChargeParameter = null;
private float m_CurrentDuck = 0f;
private float m_TargetDuck = 0f;
public Quaternion rotation
{
get { return Quaternion.identity; }
}
private Vector3 m_Position = Vector3.zero;
public Vector3 position
{
get { return m_Position; }
}
public bool bypassPositionMultiplier
{
get { return true; }
}
public bool bypassRotationMultiplier
{
get { return true; }
}
#if UNITY_EDITOR
void OnValidate()
{
m_DuckHeight = Mathf.Clamp(m_DuckHeight, 0.05f, 0.5f);
}
#endif
void Awake ()
{
m_Handler = GetComponent<IAdditiveTransformHandler>();
if (!string.IsNullOrEmpty(m_JumpChargeKey))
{
var mc = GetComponentInParent<MotionController>();
if (mc != null && mc.motionGraph != null)
{
m_ChargeParameter = mc.motionGraph.GetFloatProperty(m_JumpChargeKey);
if (m_ChargeParameter != null)
m_ChargeParameter.onValueChanged += OnJumpChargeChanged;
}
}
}
private void OnJumpChargeChanged(float charge)
{
m_TargetDuck = Mathf.Clamp01(charge);
}
void OnEnable ()
{
m_Handler.ApplyAdditiveEffect (this);
}
void OnDisable ()
{
m_Handler.RemoveAdditiveEffect (this);
}
public void UpdateTransform ()
{
if (m_CurrentDuck == m_TargetDuck)
return;
m_CurrentDuck = Mathf.Lerp(m_CurrentDuck, m_TargetDuck, Time.deltaTime * 10f);
float delta = 0f;
if (m_CurrentDuck > m_TargetDuck)
delta = m_CurrentDuck - m_TargetDuck;
else
delta = m_TargetDuck - m_CurrentDuck;
if (delta < 0.001f)
m_CurrentDuck = m_TargetDuck;
m_Position.y = m_CurrentDuck * -m_DuckHeight;
}
public float duckAmount
{
get { return m_CurrentDuck; }
set { m_TargetDuck = Mathf.Clamp01 (value); }
}
public void WriteProperties(INeoSerializer writer, NeoSerializedGameObject nsgo, SaveMode saveMode)
{
writer.WriteValue(k_DuckKey, m_CurrentDuck);
}
public void ReadProperties(INeoDeserializer reader, NeoSerializedGameObject nsgo)
{
if (reader.TryReadValue(k_DuckKey, out m_CurrentDuck, m_CurrentDuck))
m_Position = Vector3.down * m_CurrentDuck * m_DuckHeight;
}
}
}