SanAndreasUnity/Assets/Scripts/Behaviours/Ped/States/JumpState.cs
2021-12-19 22:41:07 +01:00

194 lines
4.1 KiB
C#

using UnityEngine;
using SanAndreasUnity.Utilities;
using SanAndreasUnity.Importing.Animation;
using System.Collections;
namespace SanAndreasUnity.Behaviours.Peds.States
{
public class JumpState : BaseMovementState
{
public override AnimId movementAnim { get { return new AnimId (AnimGroup.WalkCycle, AnimIndex.Idle); } }
public override AnimId movementWeaponAnim { get { return this.movementAnim; } }
private Coroutine m_coroutine;
private int m_currentAnimIndex = 0;
[Range(0, 10)] public float launchVelocityMultiplier = 1f;
[Range(0, 10)] public float glideVelocity = 2f;
[Range(0, 10)] public float landVelocityMultiplier = 1f;
public float reEntranceTime = 0.4f;
public override float TimeUntilStateCanBeEnteredFromOtherMovementState => this.reEntranceTime;
public override void OnBecameActive ()
{
base.OnBecameActive ();
m_currentAnimIndex = 0;
m_coroutine = this.StartCoroutine (this.Coroutine());
}
public override void OnBecameInactive ()
{
if (m_coroutine != null)
this.StopCoroutine (m_coroutine);
m_coroutine = null;
base.OnBecameInactive ();
}
IEnumerator Coroutine()
{
// play 3 anims one after another
m_currentAnimIndex = 0;
var state = m_model.PlayAnim ("ped", "JUMP_launch");
state.wrapMode = WrapMode.Once;
while( state.enabled )
{
yield return null;
}
m_currentAnimIndex++;
state = m_model.PlayAnim ("ped", "JUMP_glide");
state.wrapMode = WrapMode.Once;
while (state.enabled)
yield return null;
m_currentAnimIndex++;
state = m_model.PlayAnim ("ped", "JUMP_land");
state.wrapMode = WrapMode.Once;
while (state.enabled)
yield return null;
// all anims finished
// switch to other state
// let it be done both on server and client
// Debug.LogFormat("All 3 anims finished, switching state");
m_ped.SwitchState<StandState>();
}
public bool CanJump()
{
if (m_ped.CurrentWeapon != null && m_ped.CurrentWeapon.IsHeavy)
return false;
if( !m_ped.IsGrounded )
return false;
return true;
}
public bool Jump()
{
if (!this.CanJump ())
return false;
m_ped.SwitchState<JumpState> ();
return true;
}
public override void UpdateState ()
{
base.UpdateState ();
if (!this.IsActiveState)
return;
if (m_isServer)
{
// if character is grounded, then we are no longer in jump state
if (m_currentAnimIndex == 1 && m_ped.IsGrounded)
{
// Debug.LogFormat ("Character is grounded, exiting jump state");
m_ped.SwitchState<StandState> ();
}
}
}
protected override void SwitchToMovementState ()
{
// ignore
}
protected override void SwitchToAimState ()
{
// ignore
}
protected override void UpdateAnims ()
{
// ignore
}
public override void OnSubmitPressed ()
{
// ignore
}
public override void OnJumpPressed ()
{
// ignore
}
public override void OnCrouchButtonPressed ()
{
// ignore
}
public override void OnFlyButtonPressed ()
{
// ignore
}
public override void OnFlyThroughButtonPressed ()
{
// ignore
}
protected override void UpdateHeading ()
{
// not required, since we don't use heading
// do it both on server and client
m_ped.Heading = m_ped.transform.forward;
}
protected override void UpdateRotation ()
{
// ignore
// rotation can not be changed while jumping
}
protected override void UpdateMovement ()
{
// do it both on server and client
Vector3 modelVelocity = m_model.Velocity;
if( m_currentAnimIndex == 0 )
modelVelocity.z *= this.launchVelocityMultiplier;
else if( m_currentAnimIndex == 1 )
modelVelocity.z = this.glideVelocity;
else if( m_currentAnimIndex == 2 )
{
modelVelocity.y = Mathf.Min(modelVelocity.y, 0f); // don't allow to move upwards
modelVelocity.z *= this.landVelocityMultiplier;
}
Vector3 velocity = m_ped.transform.forward.WithXAndZ().normalized * modelVelocity.z + Vector3.up * modelVelocity.y;
// we won't apply gravity
m_ped.characterController.Move (velocity * Time.deltaTime);
}
}
}