- Home /
8-Way Animation Blending
I've made some run animations for a character and I'm having some difficulty implementing them. There are 8 separate animations that each correspond to a possible run direction using the WASD keys. They are forward, back, left strafe, right strafe, and the four in-between animations. Just using the four main animations(forward, back, left, right) would be easy - just set the weight to vertical and horizontal input, but I can't seem to wrap my head around how to implement the in-between animations. I am using Input.GetAxis for the input, so the input will be smoothed.
Any advice on how to proceed with this?
im personally waiting for unity 4 as there is a new animation system being introduced. not very helpful right now but just thought i would let you know if you didnt know
Answer by Piflik · Jul 10, 2012 at 09:42 PM
In my game, I blend the animations (6, since I am on a hex grid) based on the angle between the look direction and the move direction, not directly via the input.
function Update () {
lastPos = curPos;
curPos = transform.position;
if(curPos != lastPos){
curAngle = Vector3.Angle((curPos - lastPos).normalized, transform.forward);
clockwise = angleDir(transform.forward, (curPos - lastPos).normalized, Vector3.up);
if(curAngle < 30)
animation.CrossFade("walk_F", 0.1);
else if(curAngle > 30 && curAngle < 90 && clockwise < 0)
animation.CrossFade("walk_FL", 0.1);
else if(curAngle > 30 && curAngle < 90 && clockwise > 0)
animation.CrossFade("walk_FR", 0.1);
else if(curAngle > 90 && curAngle < 150 && clockwise < 0)
animation.CrossFade("walk_BL", 0.1);
else if(curAngle > 90 && curAngle < 150 && clockwise > 0)
animation.CrossFade("walk_BR", 0.1);
else if(curAngle > 150)
animation.CrossFade("walk_B", 0.1);
}
if(curPos == lastPos)
animation.CrossFade("idle", 0.1);
function angleDir(fwd: Vector3, targetDir: Vector3, up: Vector3) { //determines CW or CCW
var perp: Vector3 = Vector3.Cross(fwd, targetDir);
var dir: float = Vector3.Dot(perp, up);
if (dir > 0.0) {
return 1.0;
} else if (dir < 0.0) {
return -1.0;
} else {
return 0.0;
}
}
There are no real blends between the animations here, since the player can only move in distinct directions, but it should be quite simple to implement...
Answer by ricardo.ch · Oct 27, 2012 at 08:26 AM
What you want to do is use animation.Blend("animname", weight) and calculate your weight depending on what's important for you.
For us, we had a 4 way blend and we use the heading angle to calculate the correct blend weight:
get blending angle in radians
calculate sine and cosine
save sign of sine and cosine
animation.blend("forward", Mathf.Clam01(cosSign * cosinevalue^2))
animation.blend("up", Mathf.Clam01(sineSign * sinevalue^2))
animation.blend("back", Mathf.Clam01(cosSign cosinevalue^2 -1))
animation.blend("down", Mathf.Clam01(sineSign sinevalue^2 -1))
This will give you values between 0-1 for each animation and will let you blend between.