Audio source does not work in OnTriggerEnter() method

using UnityEngine;
using UnityEngine.Audio;

public class Collectible : MonoBehaviour
{
    public float rotationSpeed;

    public GameObject onCollectEffect;

    AudioSource audioSource;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(0, rotationSpeed, 0);      
    }

    public void OnTriggerEnter(Collider other)
    {
        // Destroy a collectible if collides a player

        if (other.CompareTag("Player"))
        {
            audioSource.Play();

            Instantiate(onCollectEffect, transform.position, transform.rotation);

            Destroy(gameObject);
        }
    }
}

And also it somehow creates an object of special effects which does not disappear.

You’re likely destroying the game object the audio source is on, which will stop the audio.

You may want to use this method instead that will instance a new audio-source at play it at the given position: Unity - Scripting API: AudioSource.PlayClipAtPoint

1 Like

Hmm… Interesting! I have got the same explanation after some time. I tried to make delay, and think to place AudioSource object into visual effect object or it is a bad practice, and better to use this instant AudioSource in the space?

The poor, I cannot find something like ‘a list of good practices on Unity’ in my attempts to self-study this American computer program to achieve some money.

I mean components can’t do they’re thing when they’re destroyed. This is true of all components.

Putting them on the same game object is fine. You will probably just need a component on it to destroy said prefab after the audio or effect is finished.

1 Like

A component to destroy a visual effect game object when audio source is finished playing music? And what kid of a component is that?
Actually I have some question about the game-objects, as far as I remember from my basic small course of programming, in C# .NET infrastructure there is no way to directly destroy the instance of a class whenever you want.

What situation with memory manegement in MonoBehaviour Unity? — Most of indy Unity games I played was horrible in terms of memory consumption (I have a pretty low-end computer, two cores american CPU and OM 8 Gb).

Your problem is very straight-forward. In Start you’re saying “get the audio source attached to this GameObject”. In OnTriggerEnter you’re saying “play the audio source, then Destroy this GameObject and all the components attached to it”

Complicated!

Unity is a c++ engine under the hood, so components live partially in C# and partially in c++. Due to the long history of the engine, more basic stuff (like audio sources, colliders, etc.) have more of their data in c++. Your MonoBehaviours has almost all of their data in C#, but they still have an identifier and such in c++ such that the engine can handle them.

When you Destroy any object, the underlying c++ data gets actually “destroyed” - or more precisely the memory gets freed. The c# part gets left behind until you don’t have any references to it and it’s collected by the GC. So you end up with an invalid C# object - usually just referred to as destroyed objects.

Because the devs early in Unity’s history had high intelligence scores and low wisdom scores, they thought that the best way to implement “check if this c# object has been destroyed” would be to override the behaviour of ==, such that if you do something like if (gameObject == null), that’d return true if the gameObject was a destroyed object.

For performance problems in indie titles, this is probably not the issue. The issue is that it’s cheap and easy to make a game in Unity, so you don’t have to have the budget or know-how required to make a game run well in order to make and ship a game.

1 Like

An interesting words. Of course I understand the plan under Unity computer program, to make it easy for a single-developer, and all in one system. But the problem I cannot find any ‘good practice’ how to make your video-game, and for my very small experience as student of basic online courses of programming, to not re-code another 3 thousands of lines of code, it is better to use some average practice of developing your code from the start…

  1. The Destroy() method actually and instantly clears memory, and in addition I see no any ‘null-reference exception’… I understand! I hope…

  2. I will try to stick AudioSource thing to actually visual effect class, but how to say the machine something like “Destroy this object only after AudioSource stops to play!”

Usually video-effects create a lot of non-usable anymore objects, which is I do not think a good thing in performance…

One you write yourself.

I do not get it… I have a class, which pinned to the visual effect game object.

using UnityEngine;

public class VisualEffectSplatter : MonoBehaviour
{
    AudioSource audioSource;    

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        //audioSource = GetComponent<AudioSource>();

        //audioSource.Play();

        Destroy(this.gameObject, 2.0f);   
    }
}

That should destroy the visual effect game object, but… The visual effect game object is always active in the Hirerarchy.

I don’t see your component on it.

1 Like

OMG! I need to sleep more, thank you Mr. Spiney! It works! Audio bells and the stuff splashes. And the visual effect disappears from the Hirerarchy! (And I hope very, it clears the operative memory too…)
So I have the final question: what is the better way to use special effect along with AudioSource class? To create thing like I did:

  1. Attach audio class to visual effect.

  2. Use an overload of method Destroy with a delay.

Or… Use AudioSource.PlayClipAtPoint things as you proposed?

P. S. In the real, humans which already know that somebody has ‘lawful good’ character, annoy him with opposite to his character tasks… It creates eve more problem. Too poor it is not so easy decline such things if you are not a very rich person (too humble) and depends on the others. I mean, I am too sleepy right now and just whim about IRL-thing… :slight_smile:

If you only wanted to play a sound, then you might use this.

But as you want to play some visual effects alongside the sound, a prefab will be a more straightforward way to go.

1 Like