Forum rules - please read before posting.

Change footstep sounds per physic material?

As the title states, I am wondering if there's a way to dynamically have the character's footstep sounds change depending on what physic material the surface they're walking on has. If not I might need to switch it manually with triggers, but that would take a lot of time with a lot of room for error.

Thanks in advance!

Comments

  • It would require a custom script - though it sounds like a good candidate for the AC wiki pages. I'll see if I can cobble something together.

  • @ChrisIceBox That would be awesome, thanks! There's a free FPS controller on the asset store which does this, but I prefer yours because of how customizable it is in general. Not sure if this is a thing in UFPS, don't have that yet.

  • edited July 2021

    It's the perfect setup, but the sounds aren't playing.. I attached the script to the main FirstPersonPlayer which has the Character Controller component. I tried adding audio clips under the Footsteps Sounds component, and those worked, but they don't change. I also tried putting the Auto Set Footstep Sounds script under the FirstPersonCamera and Sound Child.

  • What of the physic materials and colliders? Make sure the raycasting is set to the correct layer.

  • edited July 2021

    Yes, I did exactly what the wiki page states. I can't help but feel I'm doing something wrong, so here's some screenshots. I also played with the raycast distance, with no success.



  • They look correct. What of the Footstep Sounds component?

    Replace the wiki script's LateUpdate function with this, it'll output some debug info in the Console:

    private void LateUpdate ()
    {
        if (character.IsGrounded ())
        {
            Vector3 rayStart = transform.position + (0.5f * rayLength * Vector3.up);
            Debug.DrawRay (rayStart, Vector3.up * -rayLength);
            if (Physics.Raycast (rayStart, Vector3.down, out RaycastHit hitInfo, rayLength, layerMask))
            {
                Debug.Log ("Collider: " + hitInfo.collider + ", Current material: " + standingOnMaterial);
                if (hitInfo.collider.material && standingOnMaterial != hitInfo.collider.material)
                {
                    standingOnMaterial = hitInfo.collider.material;
                    OnStandMaterial (standingOnMaterial);
                }
            }
            else Debug.Log ("No collider found");
        }
    }
    
  • So this is interesting, when I start the game it's on the terrain, and the debug says "Collider: Terrain... Current Material: Grass", but once I walk on that stairs piece I have a screenshot of there, it says "No collider found".

    I'm also getting a null reference exception for "Object reference not set to an instance of an object". I tried changing "char" in the script to "CharacterController" but that made things worse. I then serialized it to see if I could manually add the character controller component, and I was only able to drag the object itself into the field, not the component. And the error didn't clear, and no results.

    Is "Char" a regular Unity component reference, or something specific to Adventure Creator? I've never seen it typed that way before.

  • Oh yeah and even though it knows I'm standing on grass, it still doesn't play the grass sound.

  • Char is the base class for AC characters. You could make use of a CharacterController to perform the grounded check, but you'll have to elaborate on how things were made worse.

    I'm also getting a null reference exception for "Object reference not set to an instance of an object".

    What line in the script was this referring to? That may be key to solving this.

    Again, what of the character's Footstep Sounds component?

  • Oh haha, I misread the post before. Yeah I'm unsure how the footstep sounds component should be set. I tried increasing and decreasing the # of footsteps list lengths, adding footstep sounds into the component, ect. The component is placed on the FirstPersonCamera object, while the Auto Set Footsteps script is placed on the FirstPersonPlayer along with the character controller component. Do all three of those need to be on the same object?

  • If the Footstep Sounds component is on a child object relative to the Player and AutoSetFootsteps components, it should be picked up.

    If you weren't using the Footstep Sounds component before, though, best to remove AutoSetFootsteps for the moment to make sure it's configured properly. You'll want to unset any "Walk sound" etc audio clips you assigned in the Player component. See the Manual's "Footstep sounds" chapter for details on how the component works.

    It is, though, also possible to adapt the wiki script to just affect the original "walk/run" sounds attached to the Player component directly - doing away with the need for the Footstep Sounds component:

    using UnityEngine;
    using AC;
    
    public class AutoSetFootstepSounds : MonoBehaviour
    {
    
        [SerializeField] private LayerMask layerMask = new LayerMask ();
        [SerializeField] private float rayLength = 0.2f;
        [SerializeField] private FootstepMaterial[] footstepMaterials = new FootstepMaterial[0];
    
        private Char character;
        private PhysicMaterial standingOnMaterial;
    
    
        private void Awake ()
        {
            character = GetComponent<Char> ();
        }
    
    
        private void LateUpdate ()
        {
            if (character.IsGrounded ())
            {
                Vector3 rayStart = transform.position + (0.5f * rayLength * Vector3.up);
                Debug.DrawRay (rayStart, Vector3.up * -rayLength);
                RaycastHit hitInfo = new RaycastHit ();
                if (Physics.Raycast (rayStart, Vector3.down, out hitInfo, rayLength, layerMask))
                {
                    if (hitInfo.collider.material && standingOnMaterial != hitInfo.collider.material)
                    {
                        standingOnMaterial = hitInfo.collider.material;
                        OnStandMaterial (standingOnMaterial);
                    }
                }
            }
        }
    
    
        private void OnStandMaterial (PhysicMaterial material)
        {
            foreach (FootstepMaterial footstepMaterial in footstepMaterials)
            {
                if (footstepMaterial.Material == material)
                {
                    footstepMaterial.Apply (character);
                    return;
                }
            }
        }
    
    
        [System.Serializable]
        private class FootstepMaterial
        {
    
            [SerializeField] private PhysicMaterial material = null;
            [SerializeField] private AudioClip walkSound = null;
            [SerializeField] private AudioClip runSound = null;
    
    
            public void Apply (Char character)
            {
                character.walkSound = walkSound;
                character.runSound = runSound;
            }
    
    
            public PhysicMaterial Material { get { return material; } }
    
        }
    
    }
    
  • The Footstep Sounds component by itself works. I noticed something a bit bizarre though about the Auto Set Footsteps script. In debug, it will register what material you are standing on entirely at random. Sometimes you will be standing on a flooring material and it will send a message "grass". It's entirely random how often it changes. And it is checking every late update, because it is sending messages in debug constantly to say what collider you're standing on, but it will get "stuck" at times on one collider even if you're not standing on that one and still send massages as if you are.

    I tried changing it to FixedUpdate and that had no effect. Also with the Footsteps Sounds component enabled, it only plays whatever sounds I already set there. The Auto Set Footsteps component has no effect on what sounds are playing.

    I also figured out what the null reference exception I had before was. I had a collaborate tab in the editor even though it's not a collaborate project, so removing that tab made that error go away. So that was entirely unrelated.

    Also if it helps, I am using the downloadable FPS controller from your site, so maybe you could try the script with that and see if you run into the same issues?

  • I do apologise. Schoolboy mistake on my part - the script was reading the collider's material instance, rather than the original asset.

    Updated the wiki page with a corrected script - try it now.

  • No problem, it works perfectly now! Thanks a bunch! :)

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.