Maybe Im just doing something wrong with these brackets, or theres something I dont follow with animation layers. This is a third person walk around, including:
Idle Walk jump and strafe.
Theres no Mistyped capitals issues, so its really about layout of code I guess. Currently this allows the idle and strafe anims to play, but no jump or Walk…
The reason it doesn’t work is because the last if/else overrides all the previous animations.
I suppose you want some kind of hierarchy going on, ie if the player’s jumping, do you still play the other clips? You have to figure that out precisely before you can correctly order you ifs.
If you want to use CrossFade, you’d have to put the clips in different layers, ie idle/strafe in layer 0, walk in layer 1, jump in layer 2.
Otherwise, you could use Blend, which is another mechanism that I haven’t figured out completely, but it will actually combine your clips. The thing is, you may experience problem like one clip will “smooth out” the effect of another clip. Like if you blend 2 clips where the first has the character’s arm vertical, and the second horizontal, you’ll end up with a 45° arm.
You may want to check out that post: The Game Needed Me: Fun with blended animation
I did A LOT of experimenting with animations, so I’d be glad to help more (like making sure your code is ok once you’ve figured out your movement hierarchy), or show you some of my tests.
I think Unity is badly lacking a thorough animation tutorial…
I must warn you though, I’m still a noob with Unity, and games in general, and the animating-for-games theory itself. Like, how should you animate you models before even talking of importing them to the engine? (I’m a coder, NOT an animator)
This guy has loads of Maya tutorials, that I guess would apply with any modeler: http://www.poopinmymouth.com
Cheers Ben,
I tried a few variations of the layering system, but whatever was the highest layer always took over. And it does seem that all should be set to loop…
Thank you for clarifying where I was with the if else stuff. Makes sense…Now that youve made it make sense:P
Nice blog, I’ll be reading the other links tonight…
So I might have to settle for stopping all the animations as well as calling the triggered one.
Right back to it…Stay tuned, I’ll get an ugly hack rigged up in no time…
AC[/code]
If you want no blending, then no hack is required, just reorder your ifs.
For example, if you say “jumping has precedence, then walk if walking, then strafe if strafing, otherwise idle”, this should work:
// if you have no input, stay idle
var clipName = "idle";
if (<jumping condition>)
{
clipName = "jump";
// set clip speed
}
else if (<walking condition>)
{
clipName = "walk";
}
else if (<strafing condition>)
{
clipName = "strafe";
}
animation.CrossFade(clipName);
I like using clipName because it makes clearer to me that you can only play on clip at a time.
If you want to combine clips, use Blending, or CrossFade with layers.
Forgot to say in that case you also need to a) have clips that only affect certain limbs, or b) use AddMixingTransform.
In our game we use it for cases like “shoot while idle”/“shoot while walking”, with 3 clips idle/walk/shoot.
But in your case it doesn’t necessarily apply, depends if you want “strafe while walking” or “jump while walking”…
PS: the blog’s not mine, but it sure is full of goodies.
That’s not right!
With your first if, you throw all the rest away: if you’re NOT playing idle, then you play it, so you never evaluate the other "else if"s (because that’s what “else” does). I’ll attribute this to the lack of sleep eh ?
[EDIT: other pb: you’re right, GetButtonDown won’t work for jump. You have to set its wrapMode to Once, and ignore other inputs as long as it’s playing.]
I didn’t recode everything, that’s why there’s no Mathf.Sign, I just put “set speed here” in comment.
I’ll rewrite it for you:
animation.wrapMode = WrapMode.Loop;
animation["strafe"].wrapMode = WrapMode.Once;
animation.Stop();
function Update ()
{
// let the jump finish
if (animation.IsPlaying("Jump"))
return;
var jumping = Input.GetButtonDown("Jump");
var strafing = Mathf.Abs(Input.GetAxis("Horizontal")) > 0.1;
var walking = Mathf.Abs(Input.GetAxis("Vertical")) > 0.1;
if (jumping)
{
animation.CrossFade("jump");
}
else if (strafing)
{
animation.CrossFade("strafe",2.0);
animation["strafe"].speed = Mathf.Sign(Input.GetAxis("Horizontal")*2);
}
else if (walking)
{
animation.CrossFade("Walk");
animation["Walk"].speed = Mathf.Sign(Input.GetAxis("Vertical"));
}
else // no input: stay idle
{
animation.CrossFade("Idle");
}
}
I check all conditions at the beginning of Update() to make it clearer what you’re checking in the ifs.
Plus if you ever want to do some debugging, all you have to do is to make jumping/walking/strafing into class variables.
Some remarks from what I’ve come to understand of animation:
setting every clip’s wrapMode is useless since you globally set it on the animation
setting every clip’s layer is useless as long as they are all the same, it only matters if different clips have different weights. (Plus using -1 is weird, by default it’s 0, leave it that way.)
animation.Stop() is useless if you uncheck “play auto”.
setting jump speed to 1 is useless, it’s 1 by default. (Speed only affects one state/clip, not the whole animation.)
My 2 cents of anal-retentive-coder advice:
properly indenting your code makes it much more readable: you see the structure/hierarchy instantly.
(Could be the forum messing up your code though. I recommend using only tabs instead of multiple spaces to avoid such surprises, but not all coders feel the same way.)
having different cases on clip names (jump/Idle) is a baaad idea… while coding, you’ll have to remember the proper case in addition to the name! Just pick a case, lower or upper don’t matter, and stay with it.