using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; using Bytes.Sound; public class CharacterMovement : MonoBehaviour { [SerializeField] private Rigidbody rb; [SerializeField] private SoundPlayer soundPlayer; [Header("Enable switches")] [SerializeField] private bool canWalk; [SerializeField] private bool canJump; [Header("Movement settings")] [SerializeField] private float movementSpeed; [SerializeField] private float maxMovementSpeed; [SerializeField] private float jumpPower; [SerializeField] private float afterJumpHorizontalSlowdownTime; [Header("Character properties")] [SerializeField] private float groundDrag; [SerializeField] private float airDrag; [SerializeField] private float playerHeight; [SerializeField] private float jumpAirSlowdown; [SerializeField] private float groundHitSoundVelocity; [SerializeField] private GrappleHook grappleHook; public bool isGrounded; private bool isStunned = false; private bool canHitGround = true; private Vector3 rawInputMovement; private float afterJumpHorizontalSlowdownTimeCounter; private bool stopWalk; private void Update() { SpeedControl(); } private void FixedUpdate() { if(isStunned){ return; } if (canWalk || canJump) { //The walk is actually handled here if (!stopWalk) { rb.AddForce(new Vector3(rawInputMovement.x * movementSpeed, rawInputMovement.y, rawInputMovement.z * movementSpeed), ForceMode.Impulse); } else { rb.AddForce(new Vector3(rawInputMovement.x * movementSpeed/ jumpAirSlowdown, rawInputMovement.y, rawInputMovement.z * movementSpeed/ jumpAirSlowdown), ForceMode.Impulse); } } Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.down) * playerHeight, Color.yellow); //Ground Check RaycastHit hit; if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.down), out hit, playerHeight, LayerMask.GetMask("Floor")) || Physics.Raycast(transform.position, transform.TransformDirection(Vector3.up), out hit, playerHeight, LayerMask.GetMask("Floor")) || Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, playerHeight, LayerMask.GetMask("Floor")) || Physics.Raycast(transform.position, transform.TransformDirection(Vector3.back), out hit, playerHeight, LayerMask.GetMask("Floor")) || Physics.Raycast(transform.position, transform.TransformDirection(Vector3.left), out hit, playerHeight, LayerMask.GetMask("Floor")) || Physics.Raycast(transform.position, transform.TransformDirection(Vector3.right), out hit, playerHeight, LayerMask.GetMask("Floor"))) { isGrounded = true; } else { rawInputMovement = new Vector3(rawInputMovement.x, 0, rawInputMovement.z); isGrounded = false; } //Handle Grounded if (isGrounded) rb.drag = groundDrag; else rb.drag= airDrag; } public void Stun(float duration){ isStunned = true; Invoke("Unstun" ,duration); } private void Unstun(){ isStunned = false; } public void Walk(InputAction.CallbackContext value){ if (canWalk) { Vector2 inputMovement = value.ReadValue(); rawInputMovement = new Vector3(inputMovement.x, 0, inputMovement.y); } } public void Jump(InputAction.CallbackContext value) { if(canJump && isGrounded) { float inputMovement = value.ReadValue(); rb.velocity = new Vector3(rb.velocity.x, jumpPower * inputMovement, rb.velocity.z); //rawInputMovement = new Vector3(rawInputMovement.x, jumpPower, rawInputMovement.z); } } private void SpeedControl() { if (grappleHook.isGrappled()) { Vector3 flatVel = rb.velocity; if (flatVel.magnitude > maxMovementSpeed) { Vector3 limitedVel = flatVel.normalized * maxMovementSpeed; rb.velocity = limitedVel; } } else { Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z); if (flatVel.magnitude > maxMovementSpeed) { Vector3 limitedVel = flatVel.normalized * maxMovementSpeed; rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z); } } } private void OnCollisionEnter(Collision collision) { if(rb.velocity.magnitude>= groundHitSoundVelocity && canHitGround) { soundPlayer.PlaySound("PlayerGroudHit"); StartCoroutine(DelayGroundHit(.2f)); } } IEnumerator DelayGroundHit(float delay) { canHitGround = false; yield return new WaitForSeconds(delay); canHitGround = true; } }