Footsteps

Hello i have footsteps script but it just doesn’t work please help me.

using UnityEngine;
using System.Collections;
using UnityStandardAssets.Characters.FirstPerson;

public class FootstepSounds : MonoBehaviour {

    public TextureType[] textureTypes;

    public AudioSource audioS;

    public RigidbodyFirstPersonController player;

    SoundController sc;

    // Use this for initialization
    void Start () {
        GameObject check = GameObject.FindGameObjectWithTag ("Sound Controller");

        if (check != null) {
            sc = check.GetComponent<SoundController> ();
        }
    }

    void PlayFootstepSound () {
        RaycastHit hit;
        Vector3 start = transform.position + transform.up;
        Vector3 dir = Vector3.down;

        if(player.Grounded && player.Velocity.magnitude > 2f)
        {
            if (Physics.Raycast(start, dir, out hit, 1.3f))
            {
                if (hit.collider.GetComponent<MeshRenderer>())
                {
                    PlayMeshSound(hit.collider.GetComponent<MeshRenderer>());
                }
                else if (hit.collider.GetComponent<Terrain>())
                {
                    PlayTerrainSound(hit.collider.GetComponent<Terrain>(), hit.point);
                }
            }
        }

      
    }

    void PlayMeshSound (MeshRenderer renderer) {

        if (audioS == null) {
            Debug.LogError ("PlayMeshSound -- We have no audio source to play the sound from.");
            return;
        }

        if (sc == null) {
            Debug.LogError ("PlayMeshSound -- No sound manager!!!");
            return;
        }

        if (textureTypes.Length > 0) {
            foreach (TextureType type in textureTypes) {

                if (type.footstepSounds.Length == 0) {
                    return;
                }

                foreach (Texture tex in type.textures) {
                    if (renderer.material.mainTexture == tex) {
                        sc.PlaySound (audioS, type.footstepSounds [Random.Range (0, type.footstepSounds.Length)], true, 1, 1.2f);
                    }
                }
            }
        }
    }

    void PlayTerrainSound (Terrain t, Vector3 hitPoint) {
        if (audioS == null) {
            Debug.LogError ("PlayTerrainSound -- We have no audio source to play the sound from.");
            return;
        }

        if (sc == null) {
            Debug.LogError ("PlayTerrainSound -- No sound manager!!!");
            return;
        }

        if (textureTypes.Length > 0) {

            int textureIndex = TerrainSurface.GetMainTexture (hitPoint);

            foreach (TextureType type in textureTypes) {

                if (type.footstepSounds.Length == 0) {
                    return;
                }

                foreach (Texture tex in type.textures) {
                    if (t.terrainData.splatPrototypes[textureIndex].texture == tex) {
                        sc.PlaySound (audioS, type.footstepSounds [Random.Range (0, type.footstepSounds.Length)], true, 1, 1.2f);
                    }
                }
            }
        }
    }
}

[System.Serializable]
public class TextureType {
    public string name;
    public Texture[] textures;
    public AudioClip[] footstepSounds;
}
using UnityEngine;
using System.Collections;

public class SoundController : MonoBehaviour {

    public void PlaySound (AudioSource audioS, AudioClip clip, bool randomizePitch = false, float randomPitchMin = 1, float randomPitchMax = 1) {

        audioS.clip = clip;

        if (randomizePitch == true) {
            audioS.pitch = Random.Range (randomPitchMin, randomPitchMax);
        }

        audioS.Play ();
    }

    public void InstantiateClip (Vector3 pos, AudioClip clip, float time = 2f, bool randomizePitch = false, float randomPitchMin = 1, float randomPitchMax = 1) {
        GameObject clone = new GameObject ("one shot audio");
        clone.transform.position = pos;
        AudioSource audio = clone.AddComponent<AudioSource> ();
        audio.spatialBlend = 1;
        audio.clip = clip;
        audio.Play ();

        Destroy (clone, time);
    }
}

Hello, i have his person i’d like to help, but they just didnt tell me what’s wrong. :wink:
http://plbm.com/?p=220

Hmm, it seems like it can’t go through this condition.

 if (hit.collider.GetComponent<MeshRenderer>())

Can you help me, with this problem? Result of this condition is always null how can i fix it?

That just means that whatever object you are hitting does not have a MeshRenderer component attached. Or that you do not hit anything at all.

Since you start the raycast above the player and cast downwards you may be hitting your player. Does your player have a collider but not a mesh renderer component? Either way you do not want to hit the player, so you should probably use a layermask such that the raycast does not hit the player.
One other thing i note is that you limit your raycast length to 1.3f, which is quite short. Since you only play a sound when the player is grounded, you can make it arbitrarily long, like 10f.

Yes my player has a collider but no mesh renderer, but this object has mesh renderer

Well yeah, as i said above, if you cast your ray from above the player downwards but do not ignore the collision with the player, then you will always collide with the player, not the ground. I already recommended you what to do above, so i’m not gonna repeat it here :stuck_out_tongue:

Okay, and how can i check if player made only one step?

“Steps” are a vague. You will have to define that yourself. You could for example remember where the player started walking and check if the position he stops at is between one and two step-sizes (maybe use one ‘feet’ length) from the place he started moving. Again, how you define all of this is up to you.
In that case he would have done one single step.

Hm i made something this, but it isn’t working perfectly…

private void Update()
    {
        currentSpeed = GetPlayerSpeed();
        walking = CheckIfWalking();
        if (walking)
        {
            distanceTraveled = (currentSpeed * Time.deltaTime);
            print(distanceTraveled);
            if (distanceTraveled >= 0.035f)
            {
                PlayFootstepSound();
                distanceTraveled = 0;

            }
        }
       
    }

float GetPlayerSpeed()
    {
        float speed = player.Velocity.magnitude;
        return speed;
    }

    bool CheckIfWalking()
    {
        if(currentSpeed > 0 && player.Grounded)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

You check every frame whether some distance was passed, and if so play a sound. So obviously as long as you surpass some speed/frame, you play an audio clip every frame. Instead remember the position you last played your audio at, then play the next when some total distance was passed.

Your distanceTraveled variable is wrong - your are doing currentSpeed * Time.deltaTime (0.016666, one frame).

So that could be 3 * 0.016666 which is 0.05, which is greater than 0.035, so it plays the sound and resets distanceTraveled every frame.

Try using distanceTraveled = Vector3.Distance(previousPosition, transform.position); then reset it by assigning a new previousPosition.

here for footsteps, should help you :slight_smile:

1 Like

Okay and the last question, is it possible to make a layer on this: ?