147 lines
5.0 KiB
C#
147 lines
5.0 KiB
C#
#if !NEOFPS_FORCE_QUALITY && (UNITY_ANDROID || UNITY_IOS || UNITY_TIZEN || (UNITY_WSA && NETFX_CORE) || NEOFPS_FORCE_LIGHTWEIGHT)
|
|
#define NEOFPS_LIGHTWEIGHT
|
|
#endif
|
|
|
|
using UnityEngine;
|
|
using NeoFPS.CharacterMotion.MotionData;
|
|
using NeoFPS.CharacterMotion.Parameters;
|
|
using NeoSaveGames.Serialization;
|
|
|
|
namespace NeoFPS.CharacterMotion.States
|
|
{
|
|
[MotionGraphElement("Ground Movement/Ski", "Ski")]
|
|
[HelpURL("https://docs.neofps.com/manual/motiongraphref-mgs-skistate.html")]
|
|
public class SkiState : MotionGraphState
|
|
{
|
|
[SerializeField, Tooltip("The maximum turn rate in degrees per second.")]
|
|
private FloatDataReference m_MaxTurnRate = new FloatDataReference(10f);
|
|
[SerializeField, Tooltip("A constant deceleration while skiing. Once the character speed reaches zero, the state completes.")]
|
|
private FloatDataReference m_Deceleration = new FloatDataReference(0.5f);
|
|
[SerializeField, Tooltip("A multiplier for gravity which affects speed on slopes.")]
|
|
private FloatDataReference m_GravityEffect = new FloatDataReference(1f);
|
|
|
|
private const float k_TinyValue = 0.001f;
|
|
|
|
private Vector3 m_OutVelocity = Vector3.zero;
|
|
private bool m_Completed = false;
|
|
private float m_StepHeight = 0f;
|
|
private float m_SnapHeight = 0f;
|
|
|
|
public override bool completed
|
|
{
|
|
get { return m_Completed; }
|
|
}
|
|
|
|
public override Vector3 moveVector
|
|
{
|
|
get { return m_OutVelocity * Time.deltaTime; }
|
|
}
|
|
|
|
public override bool applyGravity
|
|
{
|
|
get { return true; }// false; }
|
|
}
|
|
|
|
public override bool applyGroundingForce
|
|
{
|
|
get { return false; }// true; }// m_Snap; }
|
|
}
|
|
|
|
public override bool ignorePlatformMove
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
public override void OnValidate()
|
|
{
|
|
base.OnValidate();
|
|
}
|
|
|
|
public override void OnEnter()
|
|
{
|
|
base.OnEnter();
|
|
m_Completed = false;
|
|
|
|
m_StepHeight = characterController.stepHeight;
|
|
characterController.stepHeight = 0.025f;
|
|
m_SnapHeight = characterController.groundSnapHeight;
|
|
characterController.groundSnapHeight = 0.1f;
|
|
|
|
characterController.slopeFriction = 0f;
|
|
}
|
|
|
|
public override void OnExit()
|
|
{
|
|
base.OnExit();
|
|
m_Completed = false;
|
|
m_OutVelocity = Vector3.zero;
|
|
|
|
characterController.stepHeight = m_StepHeight;
|
|
characterController.groundSnapHeight = m_SnapHeight;
|
|
|
|
characterController.slopeFriction = 1f;
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
|
|
if (m_Completed)
|
|
return;
|
|
|
|
// Get velocity & speed
|
|
m_OutVelocity = Vector3.ProjectOnPlane(characterController.rawVelocity, characterController.groundSurfaceNormal);
|
|
float speed = m_OutVelocity.magnitude;
|
|
// ABOVE WILL BE WHY IT SPEEDS UP ON GRAVITY LOOP
|
|
// RAW GAINS STEP HEIGHT AND FLOOR IS SLOPED
|
|
|
|
float newSpeed = speed - m_Deceleration.value * Time.deltaTime;
|
|
m_OutVelocity *= newSpeed / speed;
|
|
|
|
// Complete state if near stationary
|
|
if (newSpeed < 0.05f)
|
|
m_Completed = true;
|
|
else
|
|
{
|
|
// Apply turning input
|
|
if (Mathf.Abs(controller.inputMoveDirection.x) > 0.01f)
|
|
{
|
|
// Turning based on speed. Slower movement = faster turn
|
|
float turnMultiplier = 1f / newSpeed;
|
|
if (turnMultiplier > 1f)
|
|
turnMultiplier = 1f;
|
|
m_OutVelocity = Quaternion.AngleAxis(turnMultiplier * controller.inputMoveDirection.x * m_MaxTurnRate.value, characterController.groundSurfaceNormal) * m_OutVelocity;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void CheckReferences(IMotionGraphMap map)
|
|
{
|
|
m_MaxTurnRate.CheckReference(map);
|
|
m_Deceleration.CheckReference(map);
|
|
m_GravityEffect.CheckReference(map);
|
|
base.CheckReferences(map);
|
|
}
|
|
|
|
#region SAVE / LOAD
|
|
|
|
private static readonly NeoSerializationKey k_CompletedKey = new NeoSerializationKey("completed");
|
|
private static readonly NeoSerializationKey k_VelocityKey = new NeoSerializationKey("velocity");
|
|
|
|
public override void WriteProperties(INeoSerializer writer)
|
|
{
|
|
base.WriteProperties(writer);
|
|
writer.WriteValue(k_VelocityKey, m_OutVelocity);
|
|
writer.WriteValue(k_CompletedKey, m_Completed);
|
|
}
|
|
|
|
public override void ReadProperties(INeoDeserializer reader)
|
|
{
|
|
base.ReadProperties(reader);
|
|
reader.TryReadValue(k_VelocityKey, out m_OutVelocity, m_OutVelocity);
|
|
reader.TryReadValue(k_CompletedKey, out m_Completed, m_Completed);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |