How Do I Make a Fast-Fall Script?

Okay, my other problem is solved, by myself, I might add. Yay! Now, I’ve been trying to make a fast-fall system, as is implemented in some fighter games (like Super Smash Bros). For some reason, I can crouch while in the air and do not fall faster. I know there’s a lot in this script but it’s the player-character script.

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
    public float maxSpeed = 10f;
    bool facingRight = true;
   
    Animator anim;

    public float jumpForce = 50f;
    public float normalfall = 2f;
    public float fastfall = 9f;
    public bool grounded;
   
    void Start ()
    {
        anim = GetComponent<Animator>();
       
        this.rigidbody2D.gravityScale = normalfall;
    }
   
    void  Update ()
    {   

    }
   
    void FixedUpdate ()
    {
        anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
       
        if (grounded = true)
        {
            if (Input.GetButton ("Down"))
            anim.SetBool ("Crouch", true);

            if (Input.GetButtonUp ("Down"))
            anim.SetBool ("Crouch", false);
        }
        else if (grounded = false) //This does not work
        {
            if (Input.GetButton ("Down"))
            this.rigidbody2D.gravityScale = fastfall;

            if (Input.GetButtonUp ("Down"))
                this.rigidbody2D.gravityScale = normalfall;
        }
       
        float move = Input.GetAxis ("Horizontal");
       
        anim.SetFloat ("Speed", Mathf.Abs (move));
       
        if (move > 0 && !facingRight)
            Flip ();
        else if (move < 0 && facingRight)
            Flip ();

        rigidbody2D.velocity = new Vector2 (move * maxSpeed, rigidbody2D.velocity.y);

        if (Input.GetButton ("Jump"))
        {
            grounded = false;
            anim.SetBool ("grounded", false);
        }
    }
   
    void OnCollisionStay2D ()
    {
        grounded = true;
        anim.SetBool ("grounded", true);

        if (grounded && Input.GetButtonDown ("Jump"))
        {
            rigidbody2D.AddForce(new Vector2(0, jumpForce));
        }
    }
   
    void Flip()
    {
        facingRight = !facingRight;
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

Surely the:

 else if (grounded = false) //This does not work

should read:

 else if (grounded == false) //This does not work

Usually OnCollisionStay2D is a bit flakey, so you probably want to use a raycast to check whether you are grounded or not. You do it more or less like this:

bool grounded = Physics2D.Raycast(raycast.position,
 -Vector2.up, .1f, 1 << LayerMask.NameToLayer("Floor"));

Oh, I forgot, GetButtonUp and GetButtonDown don’t work as intended in FixedUpdate(). They should only be used in Update().

Well, that is definitely news to me! I’ll switch 'em over.

HOWEVER: I now can’t seem to make the fast-fall gravity relent upon releasing the “Down” key. Any ideas?

void Update ()
{
    if (grounded)
    {
        if (Input.GetButton ("Down"))
        anim.SetBool ("Crouch", true);
       
        if (Input.GetButtonUp ("Down"))
        anim.SetBool ("Crouch", false);
    }
   
    else
    {
        if (Input.GetButton ("Down"))
        this.rigidbody2D.gravityScale = fastfall;
       
        if (Input.GetButtonUp ("Down"))
        this.rigidbody2D.gravityScale = normalfall;
    }
}

Can’t really see anything wrong with your code. You might want to change it to this, but it really shouldn’t matter:

        if (Input.GetButton ("Down"))
            this.rigidbody2D.gravityScale = fastfall;
       else
            this.rigidbody2D.gravityScale = normalfall;

I think my keyboard is just relentlessly horrible. Thanks, though!

first,you may have noticed that, the state clip starts a little offset from zero.Why was that?

secondly,the animation clip’s length can’t match with the length of the clip in animation state.You can see the picture I attach.In fact the animation clip last for 6 frames,but 9 frames in mecanim state.Why was that?

There will be some mistakes,when Im using codes to control the time precisely.For example,there is 16frames for me to input a key to change into fly state,when the jump state start.Then I set the end of the transition to about 16frames in the preview.If I input the fly key at the very end of the transition,say 15frame, there will be a fly trigger,but no fly animation,which means the animation time is not the same as the game time?