Danro/Assets/Scripts/PlayerController.cs

124 lines
3.7 KiB
C#

using UnityEngine;
[DisallowMultipleComponent]
[RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
public class PlayerController : MonoBehaviour
{
[Range(0f, 1f)] public float spriteScale = 0.35f;
public float moveSpeed = 8f;
public float accel = 40f;
public float decel = 20f;
public float maxJumpHeight = 5f;
public float jumpCooldown = 0.1f;
public float jumpBuffer = 0.1f;
[Range(0f, 1f)] public float jumpCut = 0.5f;
private Rigidbody2D rb;
private Collider2D col;
float inputX;
float lastGroundedTime;
float lastJumpPressedTime;
bool IsGrounded => Grounded();
[SerializeField] private Animator animator; // оставить в инспекторе на всякий случай
void Awake()
{
rb = GetComponent<Rigidbody2D>();
col = GetComponent<Collider2D>();
rb.freezeRotation = true;
lastJumpPressedTime = -999f;
// если не задано в инспекторе — находим автоматически
if (animator == null)
animator = GetComponent<Animator>();
if (animator == null)
animator = GetComponentInChildren<Animator>(true);
if (animator == null)
Debug.LogError($"[{name}] Animator не найден!");
}
void Update()
{
inputX = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump"))
lastJumpPressedTime = Time.time;
if (Input.GetButtonUp("Jump")) // && rb.linearVelocity.y > 0f)
rb.linearVelocity = new Vector2(rb.linearVelocity.x, rb.linearVelocity.y * jumpCut);
if (inputX != 0f)
transform.localScale = new Vector3(Mathf.Sign(inputX) * spriteScale, spriteScale, spriteScale);
if (IsGrounded) lastGroundedTime = Time.time;
animator.SetFloat("Speed", Mathf.Abs(rb.linearVelocity.x));
animator.SetFloat("VSpeed", rb.linearVelocity.y);
animator.SetBool("Grounded", IsGrounded);
}
void FixedUpdate()
{
float target = inputX * moveSpeed;
float rate = (Mathf.Abs(target) > 0.01f) ? accel : decel;
float vx = Mathf.MoveTowards(rb.linearVelocity.x, target, rate * Time.fixedDeltaTime);
if (transform.position.y < -5) Die();
bool canJump = (Time.time - lastGroundedTime) <= jumpCooldown;
bool wantJump = (Time.time - lastJumpPressedTime) <= jumpBuffer;
if (wantJump && canJump && IsGrounded)
{
float vy = CalcJumpSpeed(maxJumpHeight);
rb.linearVelocity = new Vector2(vx, vy);
animator.SetBool("Jump", true);
lastJumpPressedTime = -999f;
return;
}
rb.linearVelocity = new Vector2(vx, rb.linearVelocity.y);
}
float CalcJumpSpeed(float height)
{
float g = Physics2D.gravity.y * rb.gravityScale;
return Mathf.Sqrt(-2f * g * height);
}
bool Grounded()
{
RaycastHit2D hit = Physics2D.CircleCast(new Vector2(col.bounds.center.x,col.bounds.min.y), 0.01f, Vector2.down, 0.1f);
bool isGrounded = hit.collider != null;
animator.SetBool("Jump", !isGrounded);
return isGrounded;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Coin"))
{
GameManager.Instance.AddCoin();
Destroy(collision.gameObject);
}
if (collision.CompareTag("Finish"))
{
GameManager.Instance.NextLevel();
}
}
public void Die()
{
GameManager.Instance.ResetLevel();
}
}