Files
Crash-Course/Assets/Scripts/PlayerMovement.cs

254 lines
7.7 KiB
C#
Raw Normal View History

2025-01-10 16:14:33 -05:00
using System.Collections;
2025-01-17 20:11:04 -05:00
using TMPro;
2025-01-10 16:14:33 -05:00
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(BoxCollider2D))]
[RequireComponent(typeof(PlayerInput))]
[RequireComponent(typeof(AnimationPlayer))]
[RequireComponent(typeof(Punch))]
2025-01-10 16:14:33 -05:00
public class PlayerMovement : MonoBehaviour
{
[Header("Ground Layers")]
public LayerMask ground;
2025-01-17 20:11:04 -05:00
public TextMeshProUGUI playerText;
2025-01-10 16:14:33 -05:00
[Header("Movement")]
public float walkSpeed;
public float walkSpeedFactor = 1f;
public float maxSpeed = 5f;
2025-02-08 18:54:21 -05:00
public float maxSpeedOverride;
public float slowdownMultiplier = 10f;
2025-01-10 16:14:33 -05:00
public float virtualAxisX;
public float virtualButtonJump;
public float virtualButtonJumpLastFrame;
public float turnaroundMultiplier = 2;
public float walkSmooth;
public float secondsToFullSpeed;
public float jumpSpeed;
public float coyoteTime;
public float jumpLenience;
public float timeUnableToBeDeclaredNotJumping = 0.1f;
public float groundCheckDistance;
private Rigidbody2D body;
private BoxCollider2D collide;
private PlayerInput input;
private AnimationPlayer animationPlayer;
private Punch punch;
2025-03-07 10:46:30 -05:00
private Damageable damageable;
2025-01-10 16:14:33 -05:00
private bool jumpInputStillValid = false;
private float lastTimeJumpPressed;
private bool canBeDeclaredNotJumping = true;
private bool jumpPhysics;
private bool jumping;
private float lastTimeOnGround;
private Vector3 positionLastFrame;
void Start()
{
2025-02-08 18:54:21 -05:00
maxSpeedOverride = maxSpeed;
GetComponent<RespawnOnTriggerEnter>().spawnPoint = transform.position;
2025-01-10 16:14:33 -05:00
body = GetComponent<Rigidbody2D>();
collide = GetComponent<BoxCollider2D>();
input = GetComponent<PlayerInput>();
animationPlayer = GetComponent<AnimationPlayer>();
punch = GetComponent<Punch>();
2025-03-07 10:46:30 -05:00
damageable = GetComponent<Damageable>();
2025-01-17 20:11:04 -05:00
playerText.text = input.playerIndex.ToString();
2025-01-10 16:14:33 -05:00
}
private void Update()
{
2025-03-07 10:46:30 -05:00
if (damageable.dying) return;
2025-01-10 16:14:33 -05:00
Jump();
UpdateVirtualAxis();
}
private void FixedUpdate()
{
JumpPhysics();
HorizontalMovement();
Land();
}
private void LateUpdate()
{
Animate();
}
private void Animate()
{
if (!IsPhysicallyGrounded())
animationPlayer.SetState(AnimationPlayer.AnimationState.Jump);
else
{
if (Mathf.Abs(body.linearVelocityX) >= 0.1f)
animationPlayer.SetState(AnimationPlayer.AnimationState.Run);
else
animationPlayer.SetState(AnimationPlayer.AnimationState.Idle);
}
2025-01-17 09:40:48 -05:00
if (body.linearVelocityX < -0.1f)
animationPlayer.backwards = true;
2025-01-17 09:40:48 -05:00
else if (body.linearVelocityX > 0.1f)
animationPlayer.backwards = false;
}
2025-01-10 16:14:33 -05:00
private void Land()
{
if (body.linearVelocity.y >= 0f) return;
if (IsPhysicallyGrounded())
{
if (canBeDeclaredNotJumping)
{
jumping = false;
}
}
}
private void Jump()
{
2025-02-08 18:54:21 -05:00
//if (!punch.cancelable) return;
2025-01-10 16:14:33 -05:00
if (virtualButtonJumpLastFrame == 1f)
{
jumpInputStillValid = true;
lastTimeJumpPressed = Time.time;
}
bool isBasicallyGrounded = IsBasicallyGrounded();
if ((virtualButtonJumpLastFrame == 1f && isBasicallyGrounded && jumping == false) // Coyote Jump: Must have jump pressed this frame and be grounded in last time frame and not be actually jumping.
|| (jumpInputStillValid && Time.time - lastTimeJumpPressed <= jumpLenience && IsPhysicallyGrounded())) // Buffered Jump: Must have pressed jump in the last time frame and be jumping
{
jumpPhysics = true;
jumping = true;
jumpInputStillValid = false;
StartCoroutine(NotJumpingDelay());
}
}
private void JumpPhysics()
{
if (jumpPhysics)
{
2025-02-09 17:18:51 -05:00
if (!GetComponent<Block>().blocking)
2025-02-08 18:54:21 -05:00
{
2025-02-09 17:18:51 -05:00
if (body.linearVelocity.y < 0 || !IsPhysicallyGrounded()) body.linearVelocity = new Vector2(body.linearVelocity.x, 0);
body.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse);
if (Mathf.Abs(body.linearVelocityX) > maxSpeed)
{
body.linearVelocity = new Vector2(Mathf.Sign(body.linearVelocityX) * maxSpeed, body.linearVelocity.y);
}
2025-02-08 18:54:21 -05:00
}
2025-01-10 16:14:33 -05:00
jumpPhysics = false;
}
if (!IsPhysicallyGrounded() && !(virtualButtonJump == 1f))
body.AddForce(Vector2.down * jumpSpeed);
}
private IEnumerator NotJumpingDelay()
{
canBeDeclaredNotJumping = false;
yield return new WaitUntil(() => !IsBasicallyGrounded());
canBeDeclaredNotJumping = true;
}
private void HorizontalMovement()
{
2025-02-08 18:54:21 -05:00
float temporaryMax = IsPhysicallyGrounded() ? maxSpeedOverride : Mathf.Infinity;
float temporarySlowdown = IsPhysicallyGrounded() ? slowdownMultiplier : 1;
2025-02-09 17:18:51 -05:00
if (!GetComponent<Block>().blocking && (Mathf.Abs(body.linearVelocityX) <= maxSpeed || Mathf.Sign(body.linearVelocityX) != Mathf.Sign(virtualAxisX)))
2025-02-08 18:54:21 -05:00
{
body.AddForce(new Vector2(virtualAxisX * walkSpeed * walkSpeedFactor, 0), ForceMode2D.Force);
}
2025-02-08 18:54:21 -05:00
if (Mathf.Abs(body.linearVelocityX) >= temporaryMax)
{
2025-02-08 18:54:21 -05:00
//body.linearVelocity = new Vector2(Mathf.Sign(body.linearVelocityX) * temporaryMax, body.linearVelocity.y);
body.AddForce(new Vector2(-Mathf.Sign(body.linearVelocityX) * (Mathf.Abs(body.linearVelocityX) - temporaryMax) * temporarySlowdown, 0));
}
if (transform.position == positionLastFrame && (input.actions.FindAction("Move").ReadValue<Vector2>().x == 0))
2025-01-10 16:14:33 -05:00
{
virtualAxisX = 0;
}
2025-02-09 17:18:51 -05:00
if (GetComponent<Block>().blocking)
{
body.AddForce(new Vector2(-body.linearVelocityX * 0.8f, 0), ForceMode2D.Force);
}
2025-01-10 16:14:33 -05:00
positionLastFrame = transform.position;
}
private void UpdateVirtualAxis()
{
virtualButtonJump = input.actions.FindAction("Action").ReadValue<float>();
virtualButtonJumpLastFrame = input.actions.FindAction("Action").WasPressedThisFrame() ? 1 : 0;
virtualAxisX = input.actions.FindAction("Move").ReadValue<Vector2>().x;
return;
2025-01-10 16:14:33 -05:00
}
2025-01-10 16:14:33 -05:00
public bool IsBasicallyGrounded()
{
if (IsPhysicallyGrounded())
{
lastTimeOnGround = Time.time;
}
if (Time.time - lastTimeOnGround < coyoteTime)
{
return true;
}
return false;
}
public bool IsPhysicallyGrounded()
{
RaycastHit2D leftCheck = Physics2D.Raycast(GetPointInBoxCollider(collide, -1, -1), Vector2.down, groundCheckDistance, ground);
RaycastHit2D rightCheck = Physics2D.Raycast(GetPointInBoxCollider(collide, 1, -1), Vector2.down, groundCheckDistance, ground);
RaycastHit2D midCheck = Physics2D.Raycast(GetPointInBoxCollider(collide, 0, -1), Vector2.down, groundCheckDistance, ground);
if (leftCheck || rightCheck || midCheck)
{
return true;
}
return false;
}
public Vector2 GetPointInBoxCollider(BoxCollider2D boxCollider2D, float horizontal, float vertical)
{
return new Vector2
(
boxCollider2D.bounds.center.x + (horizontal * boxCollider2D.bounds.extents.x),
boxCollider2D.bounds.center.y + (vertical * boxCollider2D.bounds.extents.y)
);
}
public void StopVelocity()
{
if (IsPhysicallyGrounded()) body.linearVelocity = Vector2.zero;
}
2025-01-10 16:14:33 -05:00
}