Start two sounds one after the other...

Hi all :slight_smile:

After so much research, even here, I could not find the answer to my question.
Basically I’ve a door to open. I inserted one sound for the opening and one sound for closing. Everything is ok.
Now I want to insert a sound to unlock the door before opening it, but any method I use does not work. I found many tips on the web, using “WaitForSeconds” method, but for me dont work…

Do you have any advice?

Below a example of my script… The WaitForSeconds is unchecked.I am a beginner with C#, so forgive me if it’s not correct or clear

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Doors : MonoBehaviour 
    {
    	public bool open = false;
    	private bool hasOpenedCompletly;
    
    	public float DoorOpenAngle = 90.0f;
    	public float DoorCloseAngle = 0.0f;
    	public float Smooth = 2.0f;
    
    	public bool front = false;
    	public bool back = false;
    
    	[SerializeField] private AudioClip[] LockedDoorSound;
    	[SerializeField] private  AudioClip[] OpenDoorSound;
    	[SerializeField] private AudioClip[] UnlockedDoorSound;
    	private AudioSource Audio; 
    
    	public bool isLocking = false;
    
    	void Start()
    	{
    		Audio = GetComponent ();
    	}
    
    	public void ChangeDoorState()
    	{
    
    		if (isLocking != true) 
    		{
    			open = !open;
    
    			if (Audio != null) 
    			{ 
    				PlayOpeningDoorSound();
    			} 
    		} 
    		else 
    		{
    			PlayLockedDoorClosed();
    		}	
    	}
    
    	private void PlayLockedDoorClosed()
    	{
    		int n = Random.Range(1, LockedDoorSound.Length);
    		Audio.clip = LockedDoorSound[n];
    		Audio.PlayOneShot(Audio.clip);
    		LockedDoorSound[n] = LockedDoorSound[0];
    		LockedDoorSound[0] = Audio.clip;
    	}
    
    	private void PlayOpeningDoorSound()
    	{
    		int r = Random.Range (1, OpenDoorSound.Length);
    		Audio.clip = OpenDoorSound[r];
    		Audio.PlayOneShot(Audio.clip);
    		OpenDoorSound [r] = OpenDoorSound [0];
    		OpenDoorSound [0] = Audio.clip;
    	}
    
    	private void PlayUnlockedDoorSound()
    	{
    		int u = Random.Range (1, UnlockedDoorSound.Length);
    		Audio.clip = UnlockedDoorSound;
 		Audio.PlayOneShot(Audio.clip);
 		UnlockedDoorSound  = UnlockedDoorSound [0];
 		UnlockedDoorSound [0] = Audio.clip;
 	}
  
 	/*public IEnumerable WaitForOpenDoors()
 	{
 		yield return new WaitForSeconds(2.2f);
 		PlayUnlockedDoorSound ();
 	}*/
  
 	// Update is called once per frame
 	void Update () 
 	{
 		if (open) 
 		{
 			Quaternion targetRotationOpen = Quaternion.Euler (-90, -DoorOpenAngle, 0);
 				transform.localRotation = Quaternion.Slerp (transform.localRotation, targetRotationOpen, Smooth * Time.deltaTime);
  
 				if (transform.localRotation == targetRotationOpen) 
 				{
 					hasOpenedCompletly = true;
 				}
 		} 
  
 		else
  
 		{
 			Quaternion targetRotationClose = Quaternion.Euler (-90, DoorCloseAngle, 0);
 			transform.localRotation = Quaternion.Slerp (transform.localRotation, targetRotationClose, Smooth * Time.deltaTime);
 			hasOpenedCompletly = false;
 		}
 			
 	}
 }
 

You can do something similar to this:

void Update()
{
	if (open)
	{
		StartCoroutine(OpenDoor());		
	}
}

private void IEnumerator OpenDoor()
{
	PlayUnlockSound();

	// wait for 2 seconds
	yield return new WaitForSeconds(2.0f);

	Open();
	PlayOpenSound();

	yield return new WaitForSeconds(2.0f);

	Close();
	PlayCloseSound();
}

For your coroutine issue Try starting your coroutine without " ", adding back in the ();

StartCoroutine(SomeRoutine());

~

This has been answered, if I am not mistaken. If something works for you there give credit to the answerer in that thread.

~

In a nutshell you basically use the ‘length’ field of the audioclip to time your clip-replacement.

Thanks @bliu886 for the answer :slight_smile:

Dont work sorry. I explain everything better.

I’ve two script; “Interact” attach to gameobject “Player” and the script above attach to gameobject “Door”.
When I approach to the door with the player, I use a key to open it (another script called key).
With the current situation, the door is opened immediately, but I would like wait a couple of seconds before opening the door using the desired sound. Now I’ve used “WaitForOpenDoors()” metod but without success. With your example, the door always opens immediately and the sound is looped.

My example below that does not work well because the door opens immediately with its sound, and when the door is completely open, start the sound that I want…

StartCoroutine ("WaitForOpenDoors"); // in the script Interact

[......]

private IEnumerator WaitForOpenDoors() // in the script Door
     {
         yield return new WaitForSeconds(2.2f);
         PlayUnlockedDoorSound ();
     }

Which other solution can I adopt? Thanks again

Ok, re-open this discussion because with a workhome I found a solution :slight_smile:

There were many problems with the solutions mentioned above, so I decided to apply a script linked a collider box attached to the door for trigger solution.
The script contains all the functions suitable to recreate the release of the bolt. It’s work together with the script “Doors”. This solution is more flexible:)

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

public class DoorTriggerFront : MonoBehaviour 
{

	[SerializeField] private AudioClip UnlockDoorSound;
	private AudioSource UnlockAudio;

	public Collider coll;
	[SerializeField] private GameObject Gobj;

	void Start()
	{
		UnlockAudio = GetComponent<AudioSource> ();
		coll = GetComponent <Collider>();
		coll.enabled = false;
	}
		
	public void OnTriggerEnter (Collider other) 
	{
		if (other.CompareTag ("Player")) 
			{
				UnlockAudio.PlayOneShot(UnlockDoorSound);
				StartCoroutine (Wfs());
			} 
	}

	 IEnumerator Wfs()
	{
		Gobj.GetComponent<FirstPersonController> ().enabled = false;
		yield return new WaitForSeconds (UnlockDoorSound.length);
		Destroy (coll);
		Gobj.GetComponent<FirstPersonController> ().enabled = true;
	}


}