using UnityEngine;
using UnityEngine.Events;
public class CharacterController2D : MonoBehaviour
{
public float jumpForce = 400f;
public bool canAirControl = false;
public LayerMask groundMask;
public Transform m_GroundCheck;
const float k_GroundedRadius = .1f;
private bool m_Grounded;
private bool m_FacingRight = true;
private Vector3 m_Velocity = Vector3.zero;
const float m_NextGroundCheckLag = 0.1f;
float m_NextGroundCheckTime;
private Rigidbody2D m_Rigidbody2D;
[Header("Events")]
[Space]
public UnityEvent OnLandEvent;
public UnityEvent OnAirEvent;
[System.Serializable]
public class BoolEvent : UnityEvent<bool> { }
private void Awake()
{
m_Rigidbody2D = GetComponent<Rigidbody2D>();
if (OnLandEvent == null)
OnLandEvent = new UnityEvent();
if (OnAirEvent == null)
OnAirEvent = new UnityEvent();
}
private void FixedUpdate()
{
bool wasGrounded = m_Grounded;
m_Grounded = false;
if (Time.time > m_NextGroundCheckTime)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, groundMask);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
m_Grounded = true;
if (!wasGrounded)
OnLandEvent.Invoke();
}
}
}
if (wasGrounded && !m_Grounded)
{
OnAirEvent.Invoke();
}
}
public void Move(float move, bool jump)
{
if (m_Grounded || canAirControl)
{
m_Rigidbody2D.velocity = new Vector2(move, m_Rigidbody2D.velocity.y);
if (move > 0 && !m_FacingRight)
{
Flip();
}
else if (move < 0 && m_FacingRight)
{
Flip();
}
}
if (m_Grounded && jump)
{
OnAirEvent.Invoke();
m_Grounded = false;
m_Rigidbody2D.AddForce(new Vector2(0f, jumpForce));
m_NextGroundCheckTime = Time.time + m_NextGroundCheckLag;
}
}
private void Flip()
{
m_FacingRight = !m_FacingRight;
transform.localScale = Vector3.Scale(transform.localScale, new Vector3(-1, 1, 1));
}
}