Facebook
From Anorexic Shama, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 201
  1. using UnityEngine;
  2. using UnityEngine.Events;
  3.  
  4. public class CharacterController2D : MonoBehaviour
  5. {
  6.         [SerializeField] private float m_JumpForce = 400f;                                                      // Amount of force added when the player jumps.
  7.         [SerializeField] private float m_HorizontalJumpForce = 200f;                            // Amount of lateral force added when the player jumps from a wall
  8.         [Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f;                      // Amount of maxSpeed applied to crouching movement. 1 = 100%
  9.         [Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f;      // How much to smooth out the movement
  10.         [SerializeField] private bool m_AirControl = false;                                                     // Whether or not a player can steer while jumping;
  11.         [SerializeField] private LayerMask m_WhatIsGround;                                                      // A mask determining what is ground to the character
  12.         [SerializeField] private Transform m_GroundCheck;                                                       // A position marking where to check if the player is grounded.
  13.         [SerializeField] private Transform m_CeilingCheck;                                                      // A position marking where to check for ceilings
  14.         [SerializeField] private Collider2D m_CrouchDisableCollider;                            // A collider that will be disabled when crouching
  15.  
  16.         const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
  17.         private bool m_Grounded;            // Whether or not the player is grounded.
  18.         private bool m_wallSliding;                     // Whether or not the player is touching the wall
  19.         const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
  20.         private Rigidbody2D m_Rigidbody2D;
  21.         private bool m_FacingRight = true;  // For determining which way the player is currently facing.
  22.         private Vector3 m_Velocity = Vector3.zero;
  23.         private float m_parsedHorizontalForce;
  24.        
  25.         [Header("Events")]
  26.         [Space]
  27.  
  28.         public UnityEvent OnLandEvent;
  29.  
  30.         [System.Serializable]
  31.         public class BoolEvent : UnityEvent<bool> { }
  32.  
  33.         public BoolEvent OnCrouchEvent;
  34.         private bool m_wasCrouching = false;
  35.  
  36.         private void Awake()
  37.         {
  38.                 m_Rigidbody2D = GetComponent<Rigidbody2D>();
  39.  
  40.                 if (OnLandEvent == null)
  41.                         OnLandEvent = new UnityEvent();
  42.  
  43.                 if (OnCrouchEvent == null)
  44.                         OnCrouchEvent = new BoolEvent();
  45.         }
  46.  
  47.         private void FixedUpdate()
  48.         {
  49.                 bool wasGrounded = m_Grounded;
  50.                 m_Grounded = false;
  51.                 m_parsedHorizontalForce = 0f;
  52.  
  53.                 // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
  54.                 // This can be done using layers instead but Sample Assets will not overwrite your project settings.
  55.                 Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
  56.                 for (int i = 0; i < colliders.Length; i++)
  57.                 {
  58.                         if (colliders[i].gameObject != gameObject)
  59.                         {
  60.                                 m_Grounded = true;
  61.                                 if (!wasGrounded)
  62.                                         OnLandEvent.Invoke();
  63.                         }
  64.                 }
  65.         }
  66.  
  67.  
  68.         public void Move(float move, bool crouch, bool jump)
  69.         {
  70.                 // If crouching, check to see if the character can stand up
  71.                 if (!crouch)
  72.                 {
  73.                         // If the character has a ceiling preventing them from standing up, keep them crouching
  74.                         if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
  75.                         {
  76.                                 crouch = true;
  77.                         }
  78.                 }
  79.  
  80.                 //only control the player if grounded or airControl is turned on
  81.                 if (m_Grounded || m_AirControl)
  82.                 {
  83.  
  84.                         // If crouching
  85.                         if (crouch)
  86.                         {
  87.                                 if (!m_wasCrouching)
  88.                                 {
  89.                                         m_wasCrouching = true;
  90.                                         OnCrouchEvent.Invoke(true);
  91.                                 }
  92.  
  93.                                 // Reduce the speed by the crouchSpeed multiplier
  94.                                 move *= m_CrouchSpeed;
  95.  
  96.                                 // Disable one of the colliders when crouching
  97.                                 if (m_CrouchDisableCollider != null)
  98.                                         m_CrouchDisableCollider.enabled = false;
  99.                         } else
  100.                         {
  101.                                 // Enable the collider when not crouching
  102.                                 if (m_CrouchDisableCollider != null)
  103.                                         m_CrouchDisableCollider.enabled = true;
  104.  
  105.                                 if (m_wasCrouching)
  106.                                 {
  107.                                         m_wasCrouching = false;
  108.                                         OnCrouchEvent.Invoke(false);
  109.                                 }
  110.                         }
  111.  
  112.                         // Move the character by finding the target velocity
  113.                         Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
  114.                         // And then smoothing it out and applying it to the character
  115.                         m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);
  116.  
  117.                         // If the input is moving the player right and the player is facing left...
  118.                         if (move > 0 && !m_FacingRight)
  119.                         {
  120.                                 // ... flip the player.
  121.                                 Flip();
  122.                         }
  123.                         // Otherwise if the input is moving the player left and the player is facing right...
  124.                         else if (move < 0 && m_FacingRight)
  125.                         {
  126.                                 // ... flip the player.
  127.                                 Flip();
  128.                         }
  129.                 }
  130.                 // If the player should jump...
  131.                 if ((m_Grounded || m_wallSliding) && jump)
  132.                 {
  133.                
  134.                        
  135.                         // Add a vertical force to the player.
  136.                         m_Grounded = false;
  137.                         m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce), ForceMode2D.Force);
  138.  
  139.                 }
  140.         }
  141.  
  142.  
  143.         public bool isGrounded()
  144.         {
  145.                 return m_Grounded;
  146.         }
  147.  
  148.         private void Flip()
  149.         {
  150.                 // Switch the way the player is labelled as facing.
  151.                 m_FacingRight = !m_FacingRight;
  152.  
  153.                 // Multiply the player's x local scale by -1.
  154.                 Vector3 theScale = transform.localScale;
  155.                 theScale.x *= -1;
  156.                 transform.localScale = theScale;
  157.         }
  158.        
  159.         private void OnCollisionEnter2D(Collision2D other)
  160.         {
  161.                 if (other.gameObject.CompareTag("Wall"))
  162.                 {
  163.                         m_wallSliding = true;
  164.                 }
  165.         }
  166.        
  167.         private void OnCollisionExit2D(Collision2D other)
  168.         {
  169.                 if (other.gameObject.CompareTag("Wall"))
  170.                 {
  171.                         m_wallSliding = false;
  172.                 }
  173.         }
  174. }