You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
8.4 KiB
C#

using MalbersAnimations.Scriptables;
using UnityEngine;
using UnityEngine.Serialization;
namespace MalbersAnimations.Controller
{
[HelpURL("https://malbersanimations.gitbook.io/animal-controller/main-components/manimal-controller/states/glide")]
public class Glide : State
{
public override string StateName => "Glide";
[Header("Glide Parameters")]
public FloatReference GravityDrag = new FloatReference(3);
[Range(0, 90),Tooltip("Bank amount used when turning")]
public float Bank = 30;
[Range(0, 90), Tooltip("Limit to go Pitch")]
public float PitchLimit = 0;
[Range(0, 90), Tooltip("Bank amount used when turning while straffing")]
public float BankStrafe = 0;
[Range(0, 90), Tooltip("Limit to go Up and Down while straffing")]
public float PitchStrafe = 0;
[Tooltip("When Entering the Fly State... The animal will keep the Velocity from the last State if this value is greater than zero")]
public FloatReference InertiaLerp = new FloatReference(1);
[Tooltip("The animal will move forward while flying, without the need to push the W Key, or Move forward Input")]
public BoolReference AlwaysForward = new BoolReference(false);
private bool LastAlwaysForward;
[Tooltip("The animal will change the Camera Input while the Animal is using this State")]
public BoolReference UseCameraInput = new BoolReference(true);
private bool LastUseCameraInput;
[Tooltip("If the Animal has a force applied to it Remove the Force with this acceleration")]
public FloatReference RemoveForce = new FloatReference(5);
[Header("Landing")]
[Tooltip("Layers to Land on")]
public LayerMask LandOn = (1);
[Tooltip("Ray Length multiplier to check for ground and automatically land (increases or decreases the MainPivot Lenght for the Fall Ray")]
public FloatReference CheckLandDistance = new FloatReference(3f);
[Tooltip("Ray Length multiplier to check for ground and automatically land (increases or decreases the MainPivot Lenght for the Fall Ray")]
public FloatReference LandDistance = new FloatReference(1f);
[Tooltip("Minimum Distance to Clamp the State Float")]
public FloatReference LowerBlendDistance = new FloatReference(0.5f);
public FloatReference LerpDistance = new FloatReference(2);
protected Vector3 verticalInertia;
protected Vector3 DownPush;
public override void Activate()
{
base.Activate();
LastAlwaysForward = animal.AlwaysForward;
animal.AlwaysForward = AlwaysForward;
LastUseCameraInput = animal.UseCameraInput;
animal.useGUILayout = LastUseCameraInput;
InputValue = true; //Make sure the Input is set to True when the flying is not being activated by an input player
if (animal.ExternalForceAcel == 0) animal.Force_Remove(RemoveForce);
}
public override void EnterCoreAnimation()
{
verticalInertia = Vector3.Project(animal.DeltaPos, animal.UpVector); //Find the Up Inertia to keep it while entering the Core Anim
animal.PitchDirection = animal.Forward;
animal.InertiaPositionSpeed = animal.HorizontalVelocity * animal.DeltaTime; //Calculate the current Inertia!!
}
public override void OnStateMove(float deltaTime)
{
if (InCoreAnimation) //While is flying
{
var value = animal.ExternalForce != Vector3.zero ? Vector3.zero : (GravityDrag * animal.ScaleFactor) * deltaTime * Gravity;
DownPush = Vector3.Lerp(DownPush, value, deltaTime*InertiaLerp);
animal.AdditivePosition += DownPush; //Glide Push Down
var limit = PitchLimit;
var bank = Bank;
if (animal.Strafe)
{
limit = PitchStrafe;
bank = BankStrafe;
}
animal.CalculateBank(bank); //Calculate default Bank
animal.PitchAngle = Mathf.Lerp(
animal.PitchAngle,
limit * animal.VerticalSmooth,
deltaTime * animal.CurrentSpeedSet.PitchLerpOn); //Calculate Custom Pitch Angle not the default one for Fly and Underwater Swim
animal.CalculateRotator(); //Calculate the Rotator Rotation.
if (InertiaLerp.Value > 0) animal.AddInertia(ref verticalInertia, InertiaLerp);
}
}
public override void TryExitState(float DeltaTime)
{
var Distance = CheckLandDistance.Value * animal.ScaleFactor;
if (Distance <= 0) Distance = animal.Height;
var NormalizedDistance = 1f;
Debug.DrawRay(animal.Main_Pivot_Point, Gravity * Distance, Color.yellow);
Debug.DrawRay(animal.Main_Pivot_Point, Gravity * LandDistance * animal.ScaleFactor, Color.green);
if (Physics.Raycast(animal.Main_Pivot_Point, Gravity, out RaycastHit hit, Distance, LandOn, IgnoreTrigger))
{
if (LandDistance >= hit.distance)
{
Debugging($"[AllowExit] Can Land on <{hit.collider.name}> ");
FlyAllowExit();
return;
}
else
{
NormalizedDistance = Mathf.Clamp01(1 - LandDistance / (hit.distance - LowerBlendDistance));
}
}
animal.State_SetFloat(NormalizedDistance, LerpDistance);
}
private void FlyAllowExit()
{
animal.FreeMovement = false; //Disable the Free Movement
animal.UseGravity = true;
AllowExit();
}
public override void ResetStateValues()
{
verticalInertia = Vector3.zero;
DownPush = Vector3.zero;
InputValue = false;
}
public override void RestoreAnimalOnExit()
{
animal.FreeMovement = false;
animal.AlwaysForward = LastAlwaysForward;
animal.UseCameraInput = LastUseCameraInput;
animal.Speed_Lock(false);
animal.InputSource?.SetInput(Input, false); //Hack to reset the toggle when it exit on Grounded
animal.LockUpDownMovement = false;
}
public override void AllowStateExit()
{
base.InputValue = false; //release the base Input value
base.ExitInputValue = false; //release the base Input value
}
public override bool InputValue //lets override to Allow exit when the Input Changes
{
get => base.InputValue;
set
{
base.InputValue = value;
if (InCoreAnimation && IsActiveState && !value && CanExit) //When the Fly Input is false then allow exit
{
AllowExit();
}
}
}
#if UNITY_EDITOR
void Reset()
{
ID = MTools.GetInstance<StateID>("Glide");
Input = "Glide";
General = new AnimalModifier()
{
RootMotion = true,
Grounded = false,
Sprint = true,
OrientToGround = false,
CustomRotation = false,
IgnoreLowerStates = true,
Gravity = false,
modify = (modifier)(-1),
AdditivePosition = true,
AdditiveRotation = true,
FreeMovement = true,
};
}
public override void StateGizmos(MAnimal animal)
{
if (!Application.isPlaying)
{
var Gravity = animal.Gravity;
var width = 1.5f;
var LandDistance = Gravity.normalized * (this.LandDistance) * animal.transform.lossyScale.y;
var CheckDistance = Gravity.normalized * (CheckLandDistance) * animal.transform.lossyScale.y;
Gizmos.color = Color.yellow;
MTools.DrawLine(animal.Main_Pivot_Point, animal.Main_Pivot_Point + CheckDistance, width);
Gizmos.color = Color.green;
MTools.DrawLine(animal.Main_Pivot_Point, animal.Main_Pivot_Point + LandDistance, width);
}
}
#endif
}
}