clamp an animation just until it's grounded?

How do you clamp an animation forever just until it's grounded?

I have a character that needs to hold their jump animation until they are grounded again.

Here are the snippets of code concerning the jumping actions

function Start () {

    animation.wrapMode = WrapMode.Loop;

    animation["jump"].wrapMode = WrapMode.Clamp;

    animation["walk"].layer = -1;
    animation["idle"].layer = -1;
    animation["run"].layer = -1;
    animation["turn"].layer = -1;
    animation["turn2"].layer = -1;
    animation["jump"].layer =0;

    }

}if (Input.GetButtonDown ("Jump")){ 

        moveDirection.y=jumpSpeed;
        rider.position = saddle.position;
        animation.CrossFade("jump");
        inair = true;

}if (controller.isGrounded){

        inair=false;

right now it will only play the jump animation completely once, then start walking or running way before they hit the ground. I also tried to say if inair was true and if you pressed jump to do the animation, but I think the code checking if it's grounded cancels the animation prematurely. I'm at a loss for setting this up now.

thanks for any help

there are a lot of ways to do this. first of all you need to set the wrapMode of your "jumping" or "falling" animation to Loop. This will make the animation loop over and over. You can do this in script or in the Project section of the Inspector on the animation file.

Next you have to decide exactly when you want this animation to start and when you want it to finish. It may not be as simple as "when the character presses a button he jumps but they must hold a button down". For instance maybe you want this animation to play when the character jumps and loop until he lands regardless of if the button to jump is held down. Maybe it plays this animation when the character falls off a ledge even if there is no jump. You then need a way to detect the ceasing of this animation. Depending on what you decide for your conditions to stop playing the animation...it could be a trigger on a platform, it could be a boolean that gets set to isFalling and checks in Update() or a coroutine when the y velocity is >= 0. When you reach this condition you then have to decide what you want to happen next. maybe it instantly plays an idle animation. maybe the character is frozen in place for 0.72 seconds. maybe the character animation plays a rolling animation. If you want to play another animation, calling Play will cease the falling animation that was looping. calling Stop will simply stop the animation.

var theGround : String = "Ground";

function OnCollisionStart(collision : Collision)
{
    if (collision.gameObject.name == theGround)
    {
        //Stop the animation.
    }
    else
    {
        //Play the animation.
    }

}

The correct setting is `ClampForever`. `Clamp` (which you're using) isn't one of the options. You can use the Inspector to get a dropdown and double-check (WrapMode is the only setting you don't need to do in code.)

You can probably do away with `inAir`, since it will always have the same value as grounded.

One problem with a separate layer for Jump is that stopping it will snap into walk (CrossFade fades anything in, but can only fade out PlayOnce.) I ended up putting Jump on the same layer as Idle/Walk/Run. Just make sure you set those three inside `if(grounded)`.

Another possibly useful chunk of code is something like:

bool oldGrounded = grounded;
// pre-existing code to set new grounded value here
if(!oldGrounded && grounded) {
  // do "we just hit" stuff, like spawning a cloud
}
if(oldGrounded && !grounded) { /* do "we just left the ground" stuff */ }

You could keep Jump on a higher layer and try either a Coroutine "StopFade(float secs)" that uses a loop and yield to lower the weight to 0 then stops it. Or you could have jump be a PlayOnce and freeze it 70% of the way through, unfreezing when you land: `if(animation["Jump"].normalizedTime>0.7) animation["Jump"].speed=0;`