TryGetComponent Can't seem to get another script

Hi everyone, I seem to be having an issue with some of the code for my game and im not sure why.

basically, we have a PlayerController script that operates on the main character, this bear fella, and we want to make a system for making different footstep sounds based on the surface he walks on.

We wanted to first, check if the character is moving, then send a raycast downwards to hten try to get a specific script attached to the surfaces of the level, which have a serialized field containing the exact sound we want to play, as seen in part of the code below (it might be formatted wierdly while pasted here):

public class PlayerController : MonoBehaviour
{
   //other player movemet variables like velocity

   //Walking Audio and Raycast Variables
   [SerializeField] private GameObject WalkSource;
   public AudioSource audioSource;
   public RaycastHit walkSurfaceHit;
   [SerializeField] Transform rayStart;
   [SerializeField] float rayRange = 5;
   //private LayerMask layermask = 6;
   int layerMask = 1 << 8;

///other player movement related code here

if(rb.velocity.magnitude > 0)
{

    //WalkSource.SetActive(true);
    if (!audioSource.isPlaying)
    {
        OnWalkSound();
        Debug.DrawRay(transform.position, transform.up * rayRange * -1, Color.cyan);
    }
}
else
{
    //WalkSource.SetActive(false);
    audioSource.Stop();
}
}

this calls this method in the same script:

private void OnWalkSound()
{
    layerMask = ~layerMask;
    //audioSource.PlayOneShot(audioSource.clip);
    if (Physics.Raycast(transform.position, transform.up * -1, out walkSurfaceHit, rayRange, layerMask))
    {
        Debug.Log("asdadasda");
        //if (walkSurfaceHit.collider.TryGetComponent(out WalkingAudio walkingAudio))
        //{
        //    Debug.Log(walkingAudio.myAudioClip.ToString());
        //    audioSource.PlayOneShot(walkingAudio.myAudioClip);
        //}
        //if (walkSurfaceHit.collider.gameObject.GetComponent<WalkingAudio>() != null)
        //{
        //    Debug.Log("adsada");
        //    audioSource.PlayOneShot(walkSurfaceHit.collider.gameObject.GetComponent<WalkingAudio>().myAudioClip);
        //}
        if (walkSurfaceHit.transform.gameObject.GetComponent<WalkingAudio>() != null)
        {
            Debug.Log("sssssssssss");
            audioSource.PlayOneShot(walkSurfaceHit.collider.gameObject.GetComponent<WalkingAudio>().myAudioClip);
        }
    }
}

and it searches for a script “WalkingAudio” in the colliding object
(this is the script, just containing the type of audio we have)

public class WalkingAudio : MonoBehaviour
{
    [SerializeField] public AudioClip myAudioClip;
}

yet still, while we know that the ray is firring (coloured cyan, in the attached image), we’re not sure why sound isnt playing.

The dubug.Log messages “asdadasda” show up, but nothing after that even though they’re supposed to be in the console, the character does have an audio source component, and we’re pretty sure this is a script issue I’m not sure what the exact issue here is, if anyone can help I’d be thankful!

9834264--1414641--raycast.png

Cute bear model.

But even if that “asdadasda” log fires, you might still be hitting some other game object than the one you expect. Rather than some random letters, use it to log the name of the game object you’re hitting (make your Debug.Logs informative, effectively). See if this matches the game object you know has the component you’re looking for. Raycast will return the first object below the player.

You may need to be using RaycastAll and check for any results with the right component. Though if this is happening every frame than perhaps opt to use RaycastNotAlloc instead.

3 Likes

Note that RaycastHit has several object references. The Transform reference does “either” refer to the object the collider that was hit is on, or if the collider is part of a rigidbody, it would return the transform of the rigidbody and not of the collider. If it’s important to access the exact object the collider is on, use hit.collider.

So like spiney said, check which object you actually interact with. Note that Unity also provides GetComponentInChildren as well as GetComponentInParent. Both methods do the same as GetComponent, but if no such component is found on the actual object, it will also search for one in the children / parents of the object. This is in many cases quite useful.

If your objects don’t have unique names so you can distinguish them, you can also pass the object as second argument to Debug.Log as context object. That way this object gets highlighted when you click on the log message in the console.

1 Like