Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJoseph Rimar
17,101 PointsPlayer Footsteps not always playing and when they do the timing is off.
I've have almost the same problem as another user...when I play the game and open the inspector on playerfootsteps i can see the script box become checked every time I hit an arrow key and move however, I only get sound some of the time. I've checked my scripts multiple times and everything seems to be in order. I've also looked over all my inspector elements to make sure I don't have any errors but alas I cannot find anything wrong. Restarting Unity several times has not helped either. Maybe a bug in Unity on Mac OSX???
PlayerMovement Script
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
private Animator playerAnimator;
private float moveHorizontal;
private float moveVertical;
private Vector3 movement;
private float turningSpeed = 20f;
private Rigidbody playerRigidBody;
[SerializeField]
private RandomSoundPlayer playerFootsteps;
// Use this for initialization
void Start () {
// Gather components from the Player GameObject
playerAnimator = GetComponent<Animator> ();
playerRigidBody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
// Gather input from the keyboard
moveHorizontal = Input.GetAxisRaw("Horizontal");
moveVertical = Input.GetAxisRaw ("Vertical");
movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
}
void FixedUpdate () {
// If players movement vector does not equal zero...
if (movement != Vector3.zero) {
// ...then create a target rotation based on the movement vector
Quaternion targetRotation = Quaternion.LookRotation(movement, Vector3.up);
// ...and create another rotation that moves from the current rotation to the target rotation
Quaternion newRotation = Quaternion.Lerp (playerRigidBody.rotation, targetRotation, turningSpeed * Time.deltaTime);
// ...and change the players roation to the new incremental rotation
playerRigidBody.MoveRotation (newRotation);
// ...then play the jump animation
playerAnimator.SetFloat ("Speed", 3f);
//...play footstep sounds
playerFootsteps.enabled = true;
} else {
// ...otherwise don't play the jump animation
playerAnimator.SetFloat ("Speed", 0f);
//...disable footstep sounds
playerFootsteps.enabled = false;
}
}
}
RandomSound Script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class RandomSoundPlayer : MonoBehaviour {
private AudioSource audioSource;
[SerializeField]
private List<AudioClip> soundClips = new List<AudioClip> ();
[SerializeField]
private float soundTimerDelay = 3f;
private float soundTimer;
// Use this for initialization
void Start () {
audioSource = GetComponent<AudioSource> ();
}
// Update is called once per frame
void Update () {
// Increment a timer to count up to restarting
soundTimer = soundTimer + Time.deltaTime;
// If the timer reaches the delay...
if (soundTimer >= soundTimerDelay) {
//...reset the timer
soundTimer = 0f;
//...choose a random sound
AudioClip randomSound = soundClips[Random.Range (0, soundClips.Count)];
//...play the sound
audioSource.PlayOneShot (randomSound);
}
}
}
Any help would be greatly appreciated!!!
Joseph Rimar
17,101 PointsAndrew, Thanks for spotting that. I changed it but unfortunately it has not fixed my problem.
Jefferson Lessa
5,684 PointsThere is no need to add "-1" to the Range function.
When it is called with a whole number, the second parameter is exclusive, so the script won't break by Random.Range returning soundClips.Count. Adding the -1 prevents the last clip on the list to ever be fired.
Is nice to try everything to solve a bug, but remember to undo your unsucessful tries. If you don't, you may end up not knowing how your problem got fixed in the first place =P
3 Answers
Mike Atkinson
6,882 PointsHi Joseph,
There is no problem with you program, more just a limitation. The random sound script is only enabled when the movement
variable is above zero. Remember, the movement
variable comes from the player input per frame.
Also, the random sound player has a delay on it.
In other words, the delay for the random sound is only advanced in frames that input is being found.
While still not perfect, I adjusted the randomSoundPlayer
script to reset the timer. I'll paste it here, then explain my changes.
public class RandomSoundPlayer : MonoBehaviour {
private AudioSource audioSource;
[SerializeField]
private List<AudioClip> soundClips = new List<AudioClip> ();
private float delayTimer;
[SerializeField]
private float timerTargetDelay = 3f;
// Use this for initialization
void Start () {
delayTimer = timerTargetDelay;
audioSource = GetComponent<AudioSource> ();
}
void OnEnable () {
delayTimer = timerTargetDelay;
}
// Update is called once per frame
void Update () {
delayTimer += Time.deltaTime;
if (delayTimer > timerTargetDelay) {
delayTimer = 0.0f;
// play random sound from soundClips through audioSource component attached to GameObect
audioSource.PlayOneShot (soundClips [Random.Range (0, soundClips.Count)]);
}
}
}
First, notice that the condition in the void Update ()
method is set to if (delayTimer > timerTargetDelay)
so the random sound will play as soon as the delayTimer
is anything above the timerTargetDelay
, but not while equal.
Second, I initialised delayTimer
in the void Start ()
method to be equal to the timerTargetDelay
. This way, as soon as the timer is incremented for the first time, the conditional statement will fire.
Lastly, I added the
void OnEnable () {
delayTimer = timerTargetDelay;
}
This will reset the timer every time the instance of the script is reenabled. This means, as soon as you press the keys to move, the random sound will fire immediately.
As a side note
At first I tried to check if the script was enabled with an if statement inside void Update ()
, however if disabled, the class will not call Update ()
and therefore cannot check itself! So void OnEnable ()
was the answer to that.
Jefferson Lessa
5,684 PointsWhat is the value of your "Sound Timer Delay" field, on the inspector, on your Player object? The value should be like the bird's, 0.4 or something, so the footsteps will play often. If you left the values at 3, the default, the sound will look erratic, like you are describing.
That happens because the script is being enabled and disabled. When the script is disabled, the countdown stops, so the footsteps may take longer then 3 seconds to happen between each other.
Check the value, and see if that was the problem.
Buck DeFore
9,968 PointsI'm also noticing this, with 0.4 for sound timer delay. If I move just once and then wait, the sound never plays. Only if I consistently move.
Andrew Shiets
3,185 PointsAndrew Shiets
3,185 PointsI noticed your forgot the -1 at the end of this line in the RandomSoundPlayer script.