- Home /
Footsteps Script for Running and Walking
Hi everyone. In the game I am currently developing I am trying to add in a footstep sound for when I walk. This will then change to a running sound when I start running. I need some help with the scripting if that is possible. Thanks.
Answer by AlucardJay · Jan 06, 2013 at 10:49 AM
There are alot of answers to this is if you search Unity Footstep.
Check my answer here : http://answers.unity3d.com/questions/343383/switch-between-two-different-sounds-for-walking-an.html
Edit : a more comprehensive script, that looks after running, but the footstep sounds play speed can be changed eg walking is slower footsteps, running is faster footsteps :
#pragma strict
@script RequireComponent( AudioSource )
var walk : AudioClip;
var run : AudioClip;
var walkAudioSpeed : float = 0.4;
var runAudioSpeed : float = 0.2;
private var walkAudioTimer : float = 0.0;
private var runAudioTimer : float = 0.0;
var isWalking : boolean = false;
var isRunning : boolean = false;
var walkSpeed: float = 7; // regular speed
var runSpeed: float = 20; // run speed
private var chCtrl: CharacterController;
private var chMotor: CharacterMotor;
function Start()
{
chCtrl = GetComponent(CharacterController);
chMotor = GetComponent(CharacterMotor);
}
function Update()
{
SetSpeed();
if ( chCtrl.isGrounded )
{
PlayFootsteps();
}
else
{
walkAudioTimer = 0.0;
runAudioTimer = 0.0;
}
}
function SetSpeed()
{
var speed = walkSpeed;
if ( chCtrl.isGrounded && Input.GetKey("left shift") || Input.GetKey("right shift") )
{
speed = runSpeed;
}
chMotor.movement.maxForwardSpeed = speed;
}
function PlayFootsteps()
{
if ( Input.GetAxis( "Horizontal" ) || Input.GetAxis( "Vertical" ) )
{
if ( Input.GetKey( "left shift" ) || Input.GetKey( "right shift" ) )
{
// Running
isWalking = false;
isRunning = true;
}
else
{
// Walking
isWalking = true;
isRunning = false;
}
}
else
{
// Stopped
isWalking = false;
isRunning = false;
}
// Play Audio
if ( isWalking )
{
if ( audio.clip != walk )
{
audio.Stop();
audio.clip = walk;
}
//if ( !audio.isPlaying )
if ( walkAudioTimer > walkAudioSpeed )
{
audio.Stop();
audio.Play();
walkAudioTimer = 0.0;
}
}
else if ( isRunning )
{
if ( audio.clip != run )
{
audio.Stop();
audio.clip = run;
}
//if ( !audio.isPlaying )
if ( runAudioTimer > runAudioSpeed )
{
audio.Stop();
audio.Play();
runAudioTimer = 0.0;
}
}
else
{
audio.Stop();
}
// increment timers
walkAudioTimer += Time.deltaTime;
runAudioTimer += Time.deltaTime;
}
I have written another footstep script, one where you can change the ti$$anonymous$$g between footsteps (so walking plays slower and running plays faster. the only thing is it is merged with my running script, but maybe you can use that too ! I have edited my answer to include this for you. Hope you like it =]
actually, you can just comment out SetSpeed(); in the update, then all this script does is sound =]
Just wanted to jump in and say thankyou for this. Great script. I made the walk/run booleans private because as far as i can tell, you'd never need access to them in the editor.
I'm also gonna try to add sounds for jumping and landing. I'll post here if I make it work.
Thank you for your nice feedback :)
I did a modification of this script to include a sprint timer here : http://answers.unity3d.com/questions/596645/limited-sprint.html
There's still a lot of things I would do differently now, but the script in that link is arranged a little better, hope it helps. You can also add extra variables for walking sideways or backwards. While writing this, am thinking I should really update this answer! Anyway, am glad you found it useful. Happy Coding =]
Use an enum ins$$anonymous$$d of the bools..? (that way you don't have to maintain the implicit invariant that isWalking implies not isRunning and vice versa, either you're walking, running or stopped).
Absolutely. For myself I have used a FS$$anonymous$$ with enum when there is only one possible state to be in at a single moment.
Answer by Pix10 · Jan 06, 2013 at 11:15 AM
You should be able to do even better if using Pro with Mecanim, by simply creating a curve in your animation and naming it i.e. FootstepsRunning with a range on 0 to 1. Over the life of the curve/animation, set keyframes/curve values of 1 to represent footfalls and 0 for none (linear handles).
In the Animator Controller, create a float variable of the same name, and you can detect when to play your footfall audio with:
if (animator.GetFloat("FootstepsRunning") == 1)
PlayMyAudio();
Basically, the float comes from the value of the curve over time, so when it's at 1.0 it's a footstep...you can fine-tune this in the curve editor till it's spot on.
(I can't test this atm, but it should work in theory as long as it doesn't miss the peaks in the curve).
We've been promised Animator Events in future Mecanim updates, so doing this sort of thing should be even easier soon.
Answer by dc5774 · Feb 16, 2014 at 05:14 PM
Hi,
I've updated with a jump sound effect and a landing one.
Unfortunately, the landing sound effect only plays if you are holding a movement key down - this is because OnControllerColliderHit() only gets called if there is a collision during a Move call.
The alternative - using OnCollisionEnter() doesn't seem to work for a character controller (like the 1st person controller prefab that I am using). Any thoughts on why that is would be appreciated.
#pragma strict
@script RequireComponent( AudioSource )
// Note: Only objects tagged with "Ground" (and have colliders) will trigger the landing sound effect.
var walk : AudioClip;
var run : AudioClip;
var jump : AudioClip; // [Edit: New sound for jumping]
var land : AudioClip; // [Edit: New sound for landing]
var walkAudioSpeed : float = 0.4;
var runAudioSpeed : float = 0.2;
private var walkAudioTimer : float = 0.0;
private var runAudioTimer : float = 0.0;
private var isWalking : boolean = false; // Made these private
private var isRunning : boolean = false; // ^^
var walkSpeed: float = 7; // regular speed
var runSpeed: float = 20; // run speed
private var chCtrl: CharacterController;
private var chMotor: CharacterMotor;
private var jumping : boolean = false; // [Edit: new private bool to handle jumping]
function Start()
{
chCtrl = GetComponent(CharacterController);
chMotor = GetComponent(CharacterMotor);
}
function Update()
{
SetSpeed();
if ( chCtrl.isGrounded )
{
PlayFootsteps();
PlayJump();
}
else
{
walkAudioTimer = 0.0;
runAudioTimer = 0.0;
}
}
function SetSpeed()
{
var speed = walkSpeed;
if ( chCtrl.isGrounded && Input.GetKey("left shift") || Input.GetKey("right shift") )
{
speed = runSpeed;
}
chMotor.movement.maxForwardSpeed = speed;
}
// [EDIT: New function PlayJump() for jumping and landing sound (being called from Update)]
function PlayJump()
{
if ( chCtrl.isGrounded && Input.GetButtonDown("Jump") )
{
audio.PlayOneShot(jump, 0.8f);
jumping = true; // tell the script that the player has jumped
}
}
// Landing only triggers if a move control is being pressed which is not ideal.
// This is a due to the way OnControllerColliderHit() works (see docs)
// unfortunately, the simple OnCollisionEnter() is not working for me either.
function OnControllerColliderHit (hit: ControllerColliderHit)
{
if (hit.gameObject.tag == "Ground")
{
if (jumping)
{
audio.PlayOneShot( land , 0.8f );
}
}
jumping = false; // reset jumping variable
}
// END of DOM.STB's edits //
function PlayFootsteps()
{
if ( Input.GetAxis( "Horizontal" ) || Input.GetAxis( "Vertical" ) )
{
if ( Input.GetKey( "left shift" ) || Input.GetKey( "right shift" ) )
{
// Running
isWalking = false;
isRunning = true;
}
else
{
// Walking
isWalking = true;
isRunning = false;
}
}
else
{
// Stopped
isWalking = false;
isRunning = false;
}
// Play Audio
if ( isWalking )
{
if ( audio.clip != walk )
{
audio.Stop();
audio.clip = walk;
}
//if ( !audio.isPlaying )
if ( walkAudioTimer > walkAudioSpeed )
{
audio.Stop();
audio.Play();
walkAudioTimer = 0.0;
}
}
else if ( isRunning )
{
if ( audio.clip != run )
{
audio.Stop();
audio.clip = run;
}
//if ( !audio.isPlaying )
if ( runAudioTimer > runAudioSpeed )
{
audio.Stop();
audio.Play();
runAudioTimer = 0.0;
}
}
else
{
audio.Stop();
}
// increment timers
walkAudioTimer += Time.deltaTime;
runAudioTimer += Time.deltaTime;
}
Your answer
Follow this Question
Related Questions
Footstep Audio Not Working? 1 Answer
Run and Walk Script not working 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Footsteps in Character System 1 Answer
Footstep sounds not coming up when walking? (MOBILE) 3 Answers