I have a script that plays four different walking animations when the w,a,s,d keys are pressed. When I hold two keys at once, the animations stop playing. How can I resume the animation of the first key pressed when a second key is pressed using this script?
function Start () {
}
var FootStepSound : AudioClip;
var JumpSound : AudioClip;
var MoveAmount = 0.15;
var JumpAmount = 250;
function Update () {
if (Input.GetKey(KeyCode.W)) {
transform.Translate (Vector3.forward * MoveAmount);
audio.clip = FootStepSound;
audio.Play();
animation.Play("F1WalkForward", PlayMode.StopAll);
}
if (Input.GetKey(KeyCode.A)) {
transform.Translate (Vector3.left * MoveAmount);
audio.clip = FootStepSound;
audio.Play();
animation.Play("F1WalkLeft", PlayMode.StopAll);
}
if (Input.GetKey(KeyCode.S)) {
transform.Translate (Vector3.back * MoveAmount);
audio.clip = FootStepSound;
audio.Play();
animation.Play("F1WalkBack", PlayMode.StopAll);
}
if (Input.GetKey(KeyCode.D)) {
transform.Translate (Vector3.right * MoveAmount);
audio.clip = FootStepSound;
audio.Play();
animation.Play("F1WalkRight", PlayMode.StopAll);
}
}
You should be starting your animations on Input.GetKeyDown, and stopping them on Input.GetKeyUp.
Also if you want two animations to play simultaneously, you should put them on different layers. For instance it might make sense to have walk forwards/backwards animations on one layer (because they should never play simultaneously), and your strafe left/right on another layer. When you change animation you should only use the default PlayMode.StopLayer.
To set the layer of an animation, you must change the AnimationState of that AnimationClip.
The AnimationState is a set of data of an AnimtionClip specific to the GameObject that is playing it. The AnimationClip is shared between all Animation components that have it in their animations, but each one will have its own AnimationState object to represent its speed, layer, time and weight.
Additionally you might like to use animation weights to blend your strafe and forward/backwards animations.
You can access and adjust weight and layers like this:
var clip1 : String;
var clip2 : String;
var fadePeriod : float = 2.0;
function Awake() {
// The [] operator gives us access to a clip's AnimationState
// Make clip2 take precedence over clip1.
animation[clip1].layer = 0;
animation[clip2].layer = 1;
// Start with clip2 having zero weight, this will allow
// clips playing on lower layers to be seen.
animation[clip2].weight = 0;
// Start both clips.
animation.Play(clip1);
animation.Play(clip2);
}
function Update() {
// Ping pong clip2's weight between weight 0 (min) and 1 (max). This will crossfade
// the animation back and forth between clip1 and clip2.
animation[clip2].weight = Mathf.PingPong(Time.time / fadePeriod, 1.0);
}
Note that for the above example to work, both animations must be specified by name in the inspector and must be set to loop.
Look at this guide for more information on animation blending.
I need help with something else. While working, I noticed a problem. When two keys that translate the player in opposite directions are pressed at the same time, the player does not move. If one is already being held and the other is pressed, the player stops.
How can I get the player to continue in the same direction the player was originally moving before the second key is pressed?