Firstborn/Assets/RPG Creation Kit/Scripts/Player/PlayerMovements.cs

660 lines
24 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using RPGCreationKit;
namespace RPGCreationKit.Player
{
public class PlayerMovements : PlayerStatus
{
[SerializeField] public CharacterController charController;
[SerializeField] public MouseLook mouseLook;
public bool isFreezed = false;
protected bool controlsEnabled = true;
protected bool movementsEnabled = true;
public bool isInCutsceneMode = false;
public bool isJumping = false;
public bool isRunning = false;
public bool iscrouching = false;
[Space(5)]
[SerializeField] private GameObject fpHandsContainer;
[SerializeField] private float fpsHandOffsetStep = 2;
[SerializeField] private Vector3 FPSHandsOffsetWhileStanding;
[SerializeField] private Vector3 FPSHandsOffsetWhileCrouching;
[SerializeField] [Range(0f, 1f)] private float m_RunstepLenghten;
[SerializeField] private float m_StepInterval;
[SerializeField] private AudioClip[] m_FootstepSounds; // an array of footstep sounds that will be randomly selected from.
private float m_StepCycle;
private float m_NextStep;
public bool IsCrouching
{
get { return iscrouching; }
set
{
if (charController.isGrounded && !crouchEditInProgress)
{
iscrouching = value;
OnCrouchChanges();
}
}
}
float x, z;
Vector3 direction;
public float curSpeed;
public float walkSpeed = 5.0f;
public float runSpeed = 7.5f;
public float crouchSpeed = 2.5f;
bool isSprintingFat = false;
[SerializeField] private float sprintCost;
public float jumpForce = 1.5f;
public float gravity = -9.81f;
public float m_StickToGroundForce = -7f;
Vector3 velocity;
private bool jump = false;
private bool m_PreviouslyGrounded;
public bool m_isMoving;
private bool canStandUp = false;
[SerializeField] private float cameraStandingY = 0f;
[SerializeField] private float cameraCrouchingY = -.75f;
[SerializeField] private float standingHeight = 2.7f;
[SerializeField] private float crouchHeight = 1.7f;
[SerializeField] private float crouchEditSpeed = 2f;
public bool isInThirdPerson;
public ThirdPersonPlayer thirdPersonModel;
public void INPUT_MoveAxis(InputAction.CallbackContext value)
{
Vector2 dValue = value.ReadValue<Vector2>();
if (!inventory.IsOverencumbred())
{
x = dValue.x;
z = dValue.y;
}
else
{
x = 0;
z = 0;
AlertMessage.instance.InitAlertMessage("You are overencumbred.", 5, false);
}
}
public void INPUT_JumpCmd(InputAction.CallbackContext value)
{
if (controlsEnabled && !isFreezed && PlayerCombat.instance.canAttack)
if (charController.isGrounded && value.started)
{
if (!IsCrouching)
jump = true;
else
INPUT_CrouchCmd(value);
}
}
public void INPUT_RunCmd(InputAction.CallbackContext value)
{
if (controlsEnabled && !isFreezed)
if (value.started && playerAttributes.CurStamina >= 5.0f)
{
if (charController.isGrounded)
{
if (!isRunning)
{
if (IsCrouching && canStandUp)
{
IsCrouching = false;
isRunning = true;
}
else if (!IsCrouching)
isRunning = true;
}
else
isRunning = false;
}
}
}
public void INPUT_CrouchCmd(InputAction.CallbackContext value)
{
if (controlsEnabled && !isFreezed)
if (value.started)
{
if (IsCrouching == true)
{
if (canStandUp)
IsCrouching = false;
}
else
IsCrouching = true;
}
}
public void INPUT_ChangePersonCmd(InputAction.CallbackContext value)
{
if (controlsEnabled && !isFreezed && value.started)
{
if (!isInThirdPerson)
{
SwitchToThirdPerson();
}
else
{
SwitchToFirstPerson();
}
}
}
public override void Start()
{
base.Start();
m_PreviouslyGrounded = charController.isGrounded;
thirdPersonModel = ThirdPersonPlayer.instance;
}
public override void Update()
{
base.Update();
if (!isFreezed)
{
HandleMovements();
if (IsCrouching)
CanStandUpCheck();
BroadcastAnimatorToThirdPerson();
}
}
public virtual void FixedUpdate()
{
}
private void HandleMovements()
{
if (charController.isGrounded && !jump)
velocity.y = m_StickToGroundForce;
if (movementsEnabled)
direction = transform.right * x + transform.forward * z;
else
{
direction = Vector3.zero;
velocity = Vector3.zero;
}
curSpeed = (isRunning) ? runSpeed : (IsCrouching) ? crouchSpeed : walkSpeed;
// Jump
if (jump && charController.isGrounded)
{
velocity.y = Mathf.Sqrt(jumpForce * -2f * gravity);
PlayerCombat.instance.fpcAnim.ResetTrigger("Land");
cameraAnim.m_Animator.SetTrigger("Jump");
PlayerCombat.instance.fpcAnim.SetTrigger("Jump");
ThirdPersonPlayer.instance.m_Animator.SetTrigger("Jump");
jump = false;
}
velocity.y += gravity * Time.deltaTime;
if (!isInCutsceneMode)
{
m_isMoving = (direction == Vector3.zero) ? false : true;
cameraAnim.m_Animator.SetBool("isMoving", m_isMoving);
cameraAnim.m_Animator.SetBool("isWalking", !isRunning);
}
else
{
m_isMoving = false;
cameraAnim.m_Animator.SetBool("isMoving", false);
cameraAnim.m_Animator.SetBool("isWalking", false);
}
if (m_isMoving && isRunning)
SprintFatigue();
if (!movementsEnabled)
{
direction = Vector3.zero;
velocity = Vector3.zero;
}
direction.Normalize();
if(charController.enabled)
charController.Move(((direction * curSpeed) + velocity) * Time.deltaTime);
ClampStates();
if (!m_PreviouslyGrounded && charController.isGrounded)
{
// Landed
isJumping = false;
cameraAnim.m_Animator.SetTrigger("Land");
PlayerCombat.instance.fpcAnim.ResetTrigger("Jump");
PlayerCombat.instance.fpcAnim.SetTrigger("Land");
ThirdPersonPlayer.instance.m_Animator.SetTrigger("Land");
/*
if (playerCombat.weaponDrawn && playerCombat.canAttack)
{
playerCombat.fpcAnim.SetTrigger("Land");
playerCombat.fpcAnim.ResetTrigger("Jump");
}
*/
}
ProgressStepCycle(curSpeed);
m_PreviouslyGrounded = charController.isGrounded;
}
/// <summary>
/// Controls the states - never make Is Crouching and Is Running be both true at the same time etc
/// </summary>
private void ClampStates()
{
if (z <= .86f || IsCrouching)
isRunning = false;
if(playerAttributes.CurStamina <= 1.0f && isRunning)
isRunning = false;
if (isRunning && canStandUp)
IsCrouching = false;
}
/// <summary>
/// Modifies the Player dimensions when he's crouching
/// </summary>
private void OnCrouchChanges()
{
StartCoroutine(SmoothHeightChange());
StartCoroutine(SmoothFPHandsChange());
thirdPersonModel.m_Animator.SetBool("isCrouched", iscrouching);
}
private bool crouchEditInProgress = false;
IEnumerator SmoothHeightChange()
{
crouchEditInProgress = true;
if (IsCrouching)
{
Vector3 camTarget = new Vector3(cameraAnim.transform.localPosition.x, cameraCrouchingY, cameraAnim.transform.localPosition.z);
// Lerp camera
cameraAnim.LerpCamera(camTarget, crouchSpeed);
while (charController.height > crouchHeight)
{
charController.height -= crouchEditSpeed * Time.deltaTime;
charController.center = Vector3.down * (standingHeight - charController.height) / 2.0f;
yield return null;
}
cameraAnim.MoveCamera(camTarget, true);
charController.height = crouchHeight;
}
else
{
Vector3 camTarget = new Vector3(cameraAnim.transform.localPosition.x, cameraStandingY, cameraAnim.transform.localPosition.z);
// Lerp camera
cameraAnim.LerpCamera(camTarget, crouchEditSpeed);
while (charController.height < standingHeight)
{
if(charController.height < standingHeight)
charController.height += crouchEditSpeed * Time.deltaTime;
charController.center = Vector3.down * (standingHeight - charController.height) / 2.0f;
yield return null;
}
cameraAnim.MoveCamera(camTarget, true);
charController.height = standingHeight;
}
crouchEditInProgress = false;
yield return null;
}
IEnumerator SmoothFPHandsChange()
{
if (IsCrouching)
{
while (fpHandsContainer.transform.localPosition != FPSHandsOffsetWhileCrouching)
{
fpHandsContainer.transform.localPosition = Vector3.MoveTowards(fpHandsContainer.transform.localPosition, FPSHandsOffsetWhileCrouching, fpsHandOffsetStep * Time.deltaTime);
yield return null;
}
fpHandsContainer.transform.localPosition = FPSHandsOffsetWhileCrouching;
}
else
{
while (fpHandsContainer.transform.localPosition != FPSHandsOffsetWhileStanding)
{
fpHandsContainer.transform.localPosition = Vector3.MoveTowards(fpHandsContainer.transform.localPosition, FPSHandsOffsetWhileStanding, fpsHandOffsetStep * Time.deltaTime);
yield return null;
}
fpHandsContainer.transform.localPosition = FPSHandsOffsetWhileStanding;
}
}
public void SprintFatigue()
{
if (isSprintingFat)
return;
StopRecoveringStamina();
StopCoroutine("ReduceFatigue");
StartCoroutine("ReduceFatigue");
}
public IEnumerator ReduceFatigue()
{
while (m_isMoving && isRunning)
{
CancelInvoke("ResetRecover");
isSprintingFat = true;
playerAttributes.CurStamina -= sprintCost * Time.deltaTime;
if (playerAttributes.CurStamina <= 0)
playerAttributes.CurStamina = 0;
yield return null;
}
isSprintingFat = false;
Invoke("ResetRecover", recoverAfterActionDelay);
}
public void EnableDisableControls(bool _enable)
{
if (_enable)
{
mouseLook.LockCursor();
// Enable them
controlsEnabled = true;
movementsEnabled = true;
mouseLook.lookEnabled = true;
}
else
{
mouseLook.UnlockCursor();
// Disable them
controlsEnabled = false;
movementsEnabled = false;
mouseLook.lookEnabled = false;
}
}
public void FreezeOnly()
{
charController.enabled = false;
isFreezed = true;
direction = Vector3.zero;
velocity = Vector3.zero;
if (charController.enabled)
charController.Move(Vector3.zero);
}
public void Unfreeze()
{
isFreezed = false;
direction = Vector3.zero;
velocity = Vector3.zero;
if (charController.enabled)
charController.Move(Vector3.zero);
charController.enabled = true;
}
public float crouchRayDistance = 1.5f;
public float crouchSphereRadius = 1f;
public LayerMask crouchLayermask;
private void CanStandUpCheck()
{
var coll = Physics.OverlapSphere(transform.position + (transform.up.normalized * crouchRayDistance), crouchSphereRadius, crouchLayermask);
if (coll.Length <= 0)
canStandUp = true;
else
canStandUp = false;
}
public void FreezeAndDisableControl()
{
charController.enabled = false;
isFreezed = true;
direction = Vector3.zero;
velocity = Vector3.zero;
if(charController.enabled)
charController.Move(Vector3.zero);
EnableDisableControls(false);
}
public void UnfreezeAndEnableControls()
{
isFreezed = false;
direction = Vector3.zero;
velocity = Vector3.zero;
if(charController.enabled)
charController.Move(Vector3.zero);
EnableDisableControls(true);
charController.enabled = true;
}
public bool IsControlledByPlayer()
{
return (!isFreezed && charController.enabled && movementsEnabled && controlsEnabled);
}
public void ForceCrouch()
{
iscrouching = true;
OnCrouchChanges();
}
private void PlayFootStepAudio()
{
if (!charController.isGrounded)
{
return;
}
// pick & play a random footstep sound from the array,
// excluding sound at index 0
int n = Random.Range(1, m_FootstepSounds.Length);
AudioClip swap = m_FootstepSounds[n];
GameAudioManager.instance.PlayOneShot(AudioSources.Player, m_FootstepSounds[n]);
// move picked sound to index 0 so it's not picked next time
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = swap;
}
private void ProgressStepCycle(float speed)
{
if (charController.velocity.sqrMagnitude > 0 && (x != 0 || z != 0))
{
m_StepCycle += (charController.velocity.magnitude + (speed * (!isRunning ? 1f : m_RunstepLenghten))) *
Time.fixedDeltaTime;
}
if (!(m_StepCycle > m_NextStep))
{
return;
}
m_NextStep = m_StepCycle + m_StepInterval;
PlayFootStepAudio();
}
public virtual void SwitchToThirdPerson()
{
thirdPersonModel.character.ShowAll();
cameraAnim.SwitchToTPSCamera();
isInThirdPerson = true;
// Enable TPS weapon
if (thirdPersonModel.currentWeaponOnHip != null)
{
if(thirdPersonModel.currentWeaponOnHip.GetComponent<MeshRenderer>() != null)
thirdPersonModel.currentWeaponOnHip.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
if(thirdPersonModel.currentWeaponOnHip.GetComponentInChildren<SkinnedMeshRenderer>() != null)
thirdPersonModel.currentWeaponOnHip.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
if (thirdPersonModel.currentWeaponObject != null)
{
if(thirdPersonModel.currentWeaponObject.GetComponent<MeshRenderer>() != null)
thirdPersonModel.currentWeaponObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
if(thirdPersonModel.currentWeaponObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
thirdPersonModel.currentWeaponObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
if (thirdPersonModel.currentWeaponOnHand != null)
thirdPersonModel.currentWeaponOnHand.enabled = true;
if (thirdPersonModel.currentAmmoObject != null)
thirdPersonModel.currentAmmoObject.SetActive(true);
if (Equipment.PlayerEquipment.currentShieldObject != null)
{
if(Equipment.PlayerEquipment.currentShieldObject.GetComponent<MeshRenderer>() != null)
Equipment.PlayerEquipment.currentShieldObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
if (Equipment.PlayerEquipment.currentShieldObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
Equipment.PlayerEquipment.currentShieldObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
if(thirdPersonModel.projectile != null)
{
if (thirdPersonModel.projectile.GetComponent<MeshRenderer>() != null)
thirdPersonModel.projectile.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
// Disable FPS weapon
if (PlayerCombat.instance.currentWeaponOnHand != null)
{
PlayerCombat.instance.currentWeaponOnHand.enabled = false;
if (PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponent<MeshRenderer>() != null)
PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
if(PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
}
public virtual void SwitchToFirstPerson()
{
thirdPersonModel.character.HideAll();
cameraAnim.SwitchToFPSCamera();
isInThirdPerson = false;
// Disable TPS weapon
if(thirdPersonModel.currentWeaponOnHip != null)
{
if(thirdPersonModel.currentWeaponOnHip.GetComponent<MeshRenderer>() != null)
thirdPersonModel.currentWeaponOnHip.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
if(thirdPersonModel.currentWeaponOnHip.GetComponentInChildren<SkinnedMeshRenderer>() != null)
thirdPersonModel.currentWeaponOnHip.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
if (thirdPersonModel.currentWeaponObject != null)
{
if(thirdPersonModel.currentWeaponObject.GetComponent<MeshRenderer>() != null)
thirdPersonModel.currentWeaponObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
if(thirdPersonModel.currentWeaponObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
thirdPersonModel.currentWeaponObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
if (thirdPersonModel.currentWeaponOnHand != null)
thirdPersonModel.currentWeaponOnHand.enabled = false;
if (thirdPersonModel.currentAmmoObject != null)
thirdPersonModel.currentAmmoObject.SetActive(false);
if (Equipment.PlayerEquipment.currentShieldObject != null)
{
if (Equipment.PlayerEquipment.currentShieldObject.GetComponent<MeshRenderer>() != null)
Equipment.PlayerEquipment.currentShieldObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
if (Equipment.PlayerEquipment.currentShieldObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
Equipment.PlayerEquipment.currentShieldObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
if (thirdPersonModel.projectile != null)
{
if (thirdPersonModel.projectile.GetComponent<MeshRenderer>() != null)
thirdPersonModel.projectile.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
// Enable FPS weapon
if (PlayerCombat.instance.currentWeaponOnHand != null)
{
PlayerCombat.instance.currentWeaponOnHand.enabled = true;
if(PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponent<MeshRenderer>() != null)
PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
if(PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponentInChildren<SkinnedMeshRenderer>() != null)
PlayerCombat.instance.currentWeaponOnHand.gameObject.GetComponentInChildren<SkinnedMeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
}
/// <summary>
/// Syncs the player's input to the third person
/// </summary>
public virtual void BroadcastAnimatorToThirdPerson()
{
// thirdPersonModel.m_Animator.SetFloat("Speed", (z), 0.25f, Time.deltaTime);
thirdPersonModel.m_Animator.SetFloat("Speed", isRunning ? (z) : Mathf.Clamp(z, -1f, 0.5f), 0.25f, Time.deltaTime);
thirdPersonModel.m_Animator.SetFloat("Sideways", (x), 0.25f, Time.deltaTime);
// is Rotating
thirdPersonModel.m_Animator.SetBool("isRotating", Mathf.Abs(mouseLook.x) > 20.0f ? true : false);
}
}
}