|
|
@ -4,20 +4,25 @@ using UnityEngine.Events; |
|
|
|
public class CharacterController2D : MonoBehaviour |
|
|
|
{ |
|
|
|
[SerializeField] private float m_JumpForce = 400f; // Amount of force added when the player jumps.
|
|
|
|
[SerializeField] private float m_WallJumpMultiplier = 3f; // Amount of force added when the player jumps off a wall.
|
|
|
|
[Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f; // Amount of maxSpeed applied to crouching movement. 1 = 100%
|
|
|
|
[Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f; // How much to smooth out the movement
|
|
|
|
[SerializeField] private bool m_AirControl = false; // Whether or not a player can steer while jumping;
|
|
|
|
[SerializeField] private LayerMask m_WhatIsGround; // A mask determining what is ground to the character
|
|
|
|
[SerializeField] private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
|
|
|
|
[SerializeField] private Transform m_CeilingCheck; // A position marking where to check for ceilings
|
|
|
|
[SerializeField] private Transform m_WallCheck; |
|
|
|
[SerializeField] private Collider2D m_CrouchDisableCollider; // A collider that will be disabled when crouching
|
|
|
|
|
|
|
|
const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
|
|
|
|
private bool m_Grounded; // Whether or not the player is grounded.
|
|
|
|
private bool m_TouchingWall; |
|
|
|
const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
|
|
|
|
private Rigidbody2D m_Rigidbody2D; |
|
|
|
private bool m_FacingRight = true; // For determining which way the player is currently facing.
|
|
|
|
private Vector3 m_Velocity = Vector3.zero; |
|
|
|
private enum Direction { NA=0, L, R }; |
|
|
|
private Direction m_LastWallJumpDirection = Direction.NA; |
|
|
|
|
|
|
|
[Header("Events")] |
|
|
|
[Space] |
|
|
@ -43,23 +48,39 @@ public class CharacterController2D : MonoBehaviour |
|
|
|
|
|
|
|
private void FixedUpdate() |
|
|
|
{ |
|
|
|
bool wasGrounded = m_Grounded; |
|
|
|
m_Grounded = false; |
|
|
|
|
|
|
|
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
|
|
|
|
// This can be done using layers instead but Sample Assets will not overwrite your project settings.
|
|
|
|
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround); |
|
|
|
for (int i = 0; i < colliders.Length; i++) |
|
|
|
{ |
|
|
|
if (colliders[i].gameObject != gameObject) |
|
|
|
{ |
|
|
|
m_Grounded = true; |
|
|
|
if (!wasGrounded) |
|
|
|
OnLandEvent.Invoke(); |
|
|
|
} |
|
|
|
} |
|
|
|
CheckGrounded(); |
|
|
|
CheckTouchingWall(); |
|
|
|
} |
|
|
|
|
|
|
|
private void CheckGrounded() |
|
|
|
{ |
|
|
|
bool wasGrounded = m_Grounded; |
|
|
|
m_Grounded = false; |
|
|
|
|
|
|
|
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround); |
|
|
|
for (int i = 0; i < colliders.Length; i++) |
|
|
|
{ |
|
|
|
if (colliders[i].gameObject != gameObject) |
|
|
|
{ |
|
|
|
m_Grounded = true; |
|
|
|
if (!wasGrounded) |
|
|
|
OnLandEvent.Invoke(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void CheckTouchingWall() |
|
|
|
{ |
|
|
|
m_TouchingWall = false; |
|
|
|
|
|
|
|
if(!m_Grounded) |
|
|
|
{ |
|
|
|
if(Physics2D.OverlapCircle(m_WallCheck.position, 0.2f, m_WhatIsGround)) |
|
|
|
{ |
|
|
|
m_TouchingWall = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void Move(float move, bool crouch, bool jump) |
|
|
|
{ |
|
|
@ -67,7 +88,6 @@ public class CharacterController2D : MonoBehaviour |
|
|
|
if (!crouch) |
|
|
|
{ |
|
|
|
// If the character has a ceiling preventing them from standing up, keep them crouching
|
|
|
|
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround)) |
|
|
|
{ |
|
|
|
crouch = true; |
|
|
|
} |
|
|
@ -129,12 +149,31 @@ public class CharacterController2D : MonoBehaviour |
|
|
|
{ |
|
|
|
// Add a vertical force to the player.
|
|
|
|
m_Grounded = false; |
|
|
|
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce)); |
|
|
|
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce)); |
|
|
|
|
|
|
|
// Reset wall jump switch
|
|
|
|
m_LastWallJumpDirection = move > 0 ? Direction.R : Direction.L; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void Flip() |
|
|
|
else if (m_TouchingWall && jump) |
|
|
|
{ |
|
|
|
if (m_FacingRight && m_LastWallJumpDirection == Direction.L) |
|
|
|
{ |
|
|
|
m_Rigidbody2D.AddForce(new Vector2(m_JumpForce * m_WallJumpMultiplier * (m_FacingRight ? 1f : -1f), m_JumpForce * m_WallJumpMultiplier)); |
|
|
|
|
|
|
|
m_LastWallJumpDirection = Direction.R; |
|
|
|
} |
|
|
|
else if (!m_FacingRight && m_LastWallJumpDirection == Direction.R) |
|
|
|
{ |
|
|
|
m_Rigidbody2D.AddForce(new Vector2(m_JumpForce * m_WallJumpMultiplier * (m_FacingRight ? 1f : -1f), m_JumpForce * m_WallJumpMultiplier)); |
|
|
|
|
|
|
|
m_LastWallJumpDirection = Direction.L; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void Flip() |
|
|
|
{ |
|
|
|
// Switch the way the player is labelled as facing.
|
|
|
|
m_FacingRight = !m_FacingRight; |
|
|
|