OnTrigger - playing sound once with delay

Hello!
I have small problem with script that should play sound once, and after specific delay enable gravity on object.
Here is script:

using UnityEngine;
using System.Collections;

public class gravity_trigger : MonoBehaviour {

public AudioClip sound;
AudioSource audio;
public Rigidbody ActiveObject; 
public int TimeDelay = 1;
public float SoundVolume = 1f;
public bool AlreadyPlayed = false;


void Start() 
	{
    StartCoroutine("OnTriggerEnter");
	audio = GetComponent<AudioSource>();
    }

IEnumerator OnTriggerEnter(Collider otherObj) 
	{
		if (otherObj.tag == "Player")
		{
		audio.PlayOneShot(sound, SoundVolume);
		AlreadyPlayed = true;
		yield return new WaitForSeconds(TimeDelay);
        ActiveObject.useGravity = true;
		ActiveObject.isKinematic = false;
		}
	}
}

Technically it work: Player enter platform that have trigger zone, Sound is playing, and then after one second platform fall down thanks to enabled gravity.

Problem is that sound play again and again, everytime when Player enter that trigger zone, and also I have this error in console:

Failed to call function OnTriggerEnter of class gravity_trigger
Calling function OnTriggerEnter with no parameters but the function requires 1.

So question is how to properly set that script to play that sound only once, and what parameter that function need?

For what you are looking to do then at a minimum your coroutine needs to look like this

IEnumerator OnTriggerEnter(Collider otherObj) 
{
    // if ActiveObject.useGravity is false, the sound has not been played
    if ((otherObj.tag == "Player") && (ActiveObject.useGravity == false))
    {
        if (!AlreadyPlayed) // this is redundant unless you remove '(ActiveObject.useGravity == false)' above
        {
            audio.PlayOneShot(sound, SoundVolume);
            AlreadyPlayed = true;
        }
        yield return new WaitForSeconds(TimeDelay);
        ActiveObject.useGravity = true;
        ActiveObject.isKinematic = false;
    }
    yield return null; // coroutines must always return a value
}

But instead of using the OnTriggerEnter() as a coroutine you can do this instead

void OnTriggerEnter(Collider otherObj) 
{
    // if ActiveObject.useGravity is false, the sound has not been played
    // no use in calling the coroutine
    if ((otherObj.tag == "Player") && (ActiveObject.useGravity == false))
    {
        StartCoroutine(PlaySoundSetGravityAndWait());
    }
}

IEnumerator PlaySoundSetGravityAndWait() // too descriptive I know
{
    if (!AlreadyPlayed) // this is redundant unless you remove '(ActiveObject.useGravity == false)' above
    {
        audio.PlayOneShot(sound, SoundVolume);
        AlreadyPlayed = true;
    }
    yield return new WaitForSeconds(TimeDelay);
    ActiveObject.useGravity = true;
    ActiveObject.isKinematic = false;
}

Also, if the platform ever goes back up to its original position and you want to play the sound again, you do not need the separate bool value AlreadyPlayed to determine if the sound has been played. Just go by the ActiveObject.useGravity value.

Thank you @Mavina !
Both work perfectly.

I still had that error, but then I realize that I left “StartCoroutine” in “void Start()”, so now its clean and work perfectly.

Thanks again for your help!