简体   繁体   中英

Crouching issues in Unity

So I've created crouching in Unity 2D game, everything goes well except when there is something above the character after exiting crouching, what it does is that it returns to idle animation and decreases Y-axis position, I know that is normal but how can I keep the character crouched when there is something above him or when I hold the ctrl button? Check the script down below if necessary. Thanks!

    private Rigidbody2D rb2d;
    private float h = 0.0f;
    public float Speed, Jump;
    private bool canJump;
    private Animator anim;
    private BoxCollider2D bc2d;

    // Start is called before the first frame update
    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        bc2d = GetComponent<BoxCollider2D>();
    }

    // Update is called once per frame
    void Update()
    {

        h = Input.GetAxisRaw("Horizontal");

        anim.SetFloat("Speed", Mathf.Abs(h));
        transform.Translate(Vector3.right * h * Speed * Time.deltaTime);
        if (h != 0.0f)
        {
            transform.localScale = new Vector2(h, transform.localScale.y);
        }
        if (Input.GetKeyDown(KeyCode.Space) && canJump == true)
        {
            rb2d.AddForce(new Vector2(rb2d.velocity.x, Jump));
        }

        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            bc2d.enabled = false;
            Speed = Speed / 2;
            anim.SetBool("Crouch", true);
        }
        else if (Input.GetKeyUp(KeyCode.LeftControl))
        {
            bc2d.enabled = true;
            Speed = Speed * 2;
            anim.SetBool("Crouch", false);
        }









    }




    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.name == "Ground")
        {
            canJump = true;
            anim.SetBool("Jump", false);
        }

    }
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.collider.name == "Ground")
        {
            canJump = false;
            anim.SetBool("Jump", true);
        }

    }

Use RaycastHit2D . Basically before "standing" cast a ray Vector2.up from the character and if it hits, check to make sure there's enough room to stand. Something like:

private Rigidbody2D rb2d;   
private Transform t;
private float h = 0.0f;
public float Speed, Jump;
private bool canJump;
private Animator anim;
private BoxCollider2D bc2d;

// Variable to check if character is attempting to stand
private bool tryingToStand = false;
// Keep crouching state
private bool isCrouching = false;

// Start is called before the first frame update
void Start()
{
    rb2d = GetComponent<Rigidbody2D>();
    anim = GetComponent<Animator>();
    bc2d = GetComponent<BoxCollider2D>();
    t = GetComponent<Transform>();
}

// Update is called once per frame
void Update()
{
    h = Input.GetAxisRaw("Horizontal");

    anim.SetFloat("Speed", Mathf.Abs(h));
    transform.Translate(Vector3.right * h * Speed * Time.deltaTime);
    if (h != 0.0f)
    {
        transform.localScale = new Vector2(h, transform.localScale.y);
    }
    // Make sure we can jump and we're not crouching before jumping
    if (Input.GetKeyDown(KeyCode.Space) && canJump == true && !isCrouching)
    {
        rb2d.AddForce(new Vector2(rb2d.velocity.x, Jump));
    }

    if (Input.GetKeyDown(KeyCode.LeftControl))
    {
        bc2d.enabled = false;
        anim.SetBool("Crouch", true);
        // Make sure we haven't already halved the speed
        if (!tryingToStand)
        {
            Speed = Speed / 2;
        }
        // Set tryingToStand to false in case player holds ctrl before character has stood up
        tryingToStand = false;
        // Set crouching state to true
        isCrouching = true;
    }
    else if (Input.GetKeyUp(KeyCode.LeftControl))
    {
        tryingToStand = true;            
    }

    if (tryingToStand && CanStand())
    {
        tryingToStand = false;
        // Set crouching state to false;
        isCrouching = false;
        bc2d.enabled = true;
        Speed = Speed * 2;
        anim.SetBool("Crouch", false);
    }
}

bool CanStand()
{        
    RaycastHit2D hit = Physics2D.Raycast(t.position, Vector2.up);
    if (hit.collider != null)
    {
        // Check the distance to make sure the character has clearance, you'll have to change the 1.0f to what makes sense in your situation.
        if (hit.distance <= 1.0f)
        {
            return false;
        }
    }
    return true;    
}

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.collider.name == "Ground")
    {
        canJump = true;
        anim.SetBool("Jump", false);
    }    
}

private void OnCollisionExit2D(Collision2D collision)
{
    if (collision.collider.name == "Ground")
    {
        canJump = false;
        anim.SetBool("Jump", true);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM