Search Unity

When I uncrouch my character falls or enters into the object

Discussion in 'Scripting' started by vladcardosi, Jun 23, 2019.

  1. vladcardosi

    vladcardosi

    Joined:
    Jun 20, 2019
    Posts:
    5
    I've made a script for my player movement. Everything works fine except the crouch. The problem is that when I crouch under something, an object, it works but if I uncrouch while still under that object the character falls or enter into the object and start walking normally. I know this is an overasked question but I couldn't find a response that fit my script. I'll let my script down, I've added some animation too isn't only moving script.
    Thanks for your time!
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6.  
    7. {
    8.     public CharacterController2D controller;
    9.     public Animator animator;
    10.  
    11.     public float runSpeed = 15f;
    12.  
    13.     float horizontalMove = 0f;
    14.     bool jump = false;
    15.     bool crouch = false;
    16.  
    17.     void Start()
    18.     {
    19.  
    20.     }
    21.  
    22.     void Update()
    23.     {
    24.         horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
    25.  
    26.         animator.SetFloat("Speed",Mathf.Abs(horizontalMove));
    27.  
    28.         if (Input.GetButtonDown("Jump"))
    29.         {
    30.             jump = true;
    31.             animator.SetBool("IsJumping", true);
    32.         }
    33.  
    34.         if (Input.GetButtonDown("Crouch"))  // crouch
    35.         {
    36.             crouch = true;
    37.         }
    38.         else if (Input.GetButtonUp("Crouch"))
    39.         {
    40.             crouch = false;
    41.         }
    42.  
    43.         Vector3 characterScale = transform.localScale; // face direction
    44.         if (Input.GetAxis("Horizontal")<0)
    45.         {
    46.             characterScale.x = -1;
    47.         }
    48.         else if(Input.GetAxis("Horizontal")>0)
    49.         {
    50.             characterScale.x = 1;
    51.         }
    52.         transform.localScale = characterScale;
    53.  
    54.     }
    55.  
    56.     public void OnLanding()
    57.     {
    58.         animator.SetBool("IsJumping", false);
    59.     }
    60.  
    61.     public void OnCrouching(bool isCrouching)
    62.     {
    63.         animator.SetBool("IsCrouching", isCrouching);
    64.     }
    65.  
    66.     void FixedUpdate()
    67.     {
    68.         controller.Move(horizontalMove * Time.fixedDeltaTime, crouch, jump);
    69.         jump = false;
    70.  
    71.     }
    72.  
    73. }
    74.  
     
  2. Deleted User

    Deleted User

    Guest

    I don't see that you modified the collider when your player enters crouching. It needs to be downsized and get beck to its normal size when the player comes back to its normal standing position.
     
  3. vladcardosi

    vladcardosi

    Joined:
    Jun 20, 2019
    Posts:
    5
    I have another script for that, everything works fine, I've checked it.
     
  4. Deleted User

    Deleted User

    Guest

    When you enter play mode, do you switch to the scene view to see what happens when your character gets out of crouch mode? Logically, getting out of crouch mode when stuck under an object should not restore the size of the collider.

    When you do that, you must select the player in the scene view and make sure the collider is visible. Then go back to the game view, get out of crouch and monitor what happens in the scene view.
     
  5. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Before you allow the player to standup/uncrouch do a a spherecast/we check you want to check nothing is blocking him from standing.
     
  6. vladcardosi

    vladcardosi

    Joined:
    Jun 20, 2019
    Posts:
    5
    So my character is made by 2 colliders, one circle for the feet and one box for the rest. My other script is made so when i crouch the square box collider disappears. I did what you said and I observed that when I uncrouch under something the box collider starts to work again and he gets checked and unchecked multiple times and character is starting to up and down very fast(or gets through the map, or falls) until I move him back to the side of the map when he can stand. That's the other script I have, isn't made by me, I took it from a tutorial.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4. public class CharacterController2D : MonoBehaviour
    5. {
    6.     [SerializeField] private float m_JumpForce = 200f;                            // Amount of force added when the player jumps.
    7.     [Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f;            // Amount of maxSpeed applied to crouching movement. 1 = 100%
    8.     [Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f;    // How much to smooth out the movement
    9.     [SerializeField] private bool m_AirControl = false;                            // Whether or not a player can steer while jumping;
    10.     [SerializeField] private LayerMask m_WhatIsGround;                            // A mask determining what is ground to the character
    11.     [SerializeField] private Transform m_GroundCheck;                            // A position marking where to check if the player is grounded.
    12.     [SerializeField] private Transform m_CeilingCheck;                            // A position marking where to check for ceilings
    13.     [SerializeField] private Collider2D m_CrouchDisableCollider;                // A collider that will be disabled when crouching
    14.  
    15.     const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
    16.     private bool m_Grounded;            // Whether or not the player is grounded.
    17.     const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
    18.     private Rigidbody2D m_Rigidbody2D;
    19.     private bool m_FacingRight = true;  // For determining which way the player is currently facing.
    20.     private Vector3 m_Velocity = Vector3.zero;
    21.  
    22.     [Header("Events")]
    23.     [Space]
    24.  
    25.     public UnityEvent OnLandEvent;
    26.  
    27.     [System.Serializable]
    28.     public class BoolEvent : UnityEvent<bool> { }
    29.  
    30.     public BoolEvent OnCrouchEvent;
    31.     private bool m_wasCrouching = false;
    32.  
    33.     private void Awake()
    34.     {
    35.         m_Rigidbody2D = GetComponent<Rigidbody2D>();
    36.  
    37.         if (OnLandEvent == null)
    38.             OnLandEvent = new UnityEvent();
    39.  
    40.         if (OnCrouchEvent == null)
    41.             OnCrouchEvent = new BoolEvent();
    42.     }
    43.  
    44.     private void FixedUpdate()
    45.     {
    46.         bool wasGrounded = m_Grounded;
    47.         m_Grounded = false;
    48.  
    49.         // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
    50.         // This can be done using layers instead but Sample Assets will not overwrite your project settings.
    51.         Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
    52.         for (int i = 0; i < colliders.Length; i++)
    53.         {
    54.             if (colliders[i].gameObject != gameObject)
    55.             {
    56.                 m_Grounded = true;
    57.                 if (!wasGrounded)
    58.                     OnLandEvent.Invoke();
    59.             }
    60.         }
    61.     }
    62.  
    63.  
    64.     public void Move(float move, bool crouch, bool jump)
    65.     {
    66.         // If crouching, check to see if the character can stand up
    67.         if (crouch)
    68.         {
    69.             // If the character has a ceiling preventing them from standing up, keep them crouching
    70.             if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
    71.             {
    72.                 crouch = true;
    73.             }
    74.         }
    75.  
    76.         //only control the player if grounded or airControl is turned on
    77.         if (m_Grounded || m_AirControl)
    78.         {
    79.  
    80.             // If crouching
    81.             if (crouch)
    82.             {
    83.                 if (!m_wasCrouching)
    84.                 {
    85.                     m_wasCrouching = true;
    86.                     OnCrouchEvent.Invoke(true);
    87.                 }
    88.  
    89.                 // Reduce the speed by the crouchSpeed multiplier
    90.                 move *= m_CrouchSpeed;
    91.  
    92.                 // Disable one of the colliders when crouching
    93.                 if (m_CrouchDisableCollider != null)
    94.                     m_CrouchDisableCollider.enabled = false;
    95.             } else
    96.             {
    97.                 // Enable the collider when not crouching
    98.                 if (m_CrouchDisableCollider != null)
    99.                     m_CrouchDisableCollider.enabled = true;
    100.  
    101.                 if (m_wasCrouching)
    102.                 {
    103.                     m_wasCrouching = false;
    104.                     OnCrouchEvent.Invoke(false);
    105.                 }
    106.             }
    107.  
    108.             // Move the character by finding the target velocity
    109.             Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
    110.             // And then smoothing it out and applying it to the character
    111.             m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);
    112.  
    113.             // If the input is moving the player right and the player is facing left...
    114.             if (move > 0 && !m_FacingRight)
    115.             {
    116.                 // ... flip the player.
    117.                 Flip();
    118.             }
    119.             // Otherwise if the input is moving the player left and the player is facing right...
    120.             else if (move < 0 && m_FacingRight)
    121.             {
    122.                 // ... flip the player.
    123.                 Flip();
    124.             }
    125.         }
    126.         // If the player should jump...
    127.         if (m_Grounded && jump)
    128.         {
    129.             // Add a vertical force to the player.
    130.             //m_Grounded = false;
    131.             m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
    132.         }
    133.     }
    134.  
    135.  
    136.     private void Flip()
    137.     {
    138.         // Switch the way the player is labelled as facing.
    139.         m_FacingRight = !m_FacingRight;
    140.  
    141.         // Multiply the player's x local scale by -1.
    142.         Vector3 theScale = transform.localScale;
    143.         theScale.x *= -1;
    144.         transform.localScale = theScale;
    145.     }
    146. }
    147.  
     
  7. vladcardosi

    vladcardosi

    Joined:
    Jun 20, 2019
    Posts:
    5
    I've started recently to use Unity, I still have some problems with the script writing, I would appreciate if you could adapt my script for this.
     
  8. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I won't do your work for you, teach a man to fish basically.

    Start with learning about raycasting, then you'll easily understand all of the variants that has volume.

    What youll want to do is when you recieve the input to stand up do a check(if statement) where the condition is you can do a cast from the player feet to his standing height, if nothing intersects it, stand up, if not - ignore the input, maybe pop a text saying you cant or some sound, but thats another story.
     
  9. Deleted User

    Deleted User

    Guest

    Well, you've found the origin of your problem. I didn't go through the script you posted because I spent my day studying another one and my brains are more cheese than anything else.

    Find the lines that set this collider in the script and make it so that it stays crouched when the player is stuck under the object.
     
  10. vladcardosi

    vladcardosi

    Joined:
    Jun 20, 2019
    Posts:
    5
    I've started learning about raycast and I implemented a script. The problem is that when I press the crouch button it stays crouch and cant uncrouch, I know it's a problem from the condition or something but I can't figure out.
    Code (CSharp):
    1.     if (Input.GetButtonDown("Crouch"))  // crouch
    2.         {
    3.             crouch = true;
    4.         }
    5.         else if (Input.GetButtonUp("Crouch"))
    6.         {
    7.             RaycastHit hit;
    8.             Ray ray = new Ray(transform.position, transform.up);
    9.             if(Physics.Raycast(ray,out hit))
    10.             {
    11.                float distance = Vector3.Distance(transform.position, hit.point);
    12.                 if (distance < height)
    13.                 {
    14.                     crouch = true;
    15.                 }
    16.                 else crouch = false;
    17.             }
    18.         }
     
  11. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    This will hit everything, probably including controller itself.
    Try casting by a specific layermask that excludes your character controller colliders.

    Also, you might want to change from GetButtonUp to GetButton, because GetButtonUp is called only in the frame your inputs released, and never again until they're "up" again.

    GetButton <= 0 might be what you need instead.
     
  12. unity_wwGDGFqGx7u0TA

    unity_wwGDGFqGx7u0TA

    Joined:
    Apr 17, 2021
    Posts:
    1
    Sorry my answer kinda 1 year behind but maybe it's useful for everyone. I have the same problem, and it took me 1 day to figure it out. Maybe your coding is already correct, just checked your Player's Layer near 'Inspector' menu. Then changed the layer from 'default' to player if you follow brackeys tutorial