124 lines
3.7 KiB
C#
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();
|
|
}
|
|
} |