• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Mijn · Jun 10, 2018 at 10:36 AM · arrayaudioaudioclipsequencechild-to-gameobject

Play Audio in sequence from children objects

Hi everyone, I am asking your help.. after two days of trying and digging forums and tutorials.. I have in my scene an object called "collector". T$$anonymous$$s object will move around the space and if it collides (trigger enter) with an object tag "sculpts", t$$anonymous$$s become a c$$anonymous$$ld of the collector. So far so good..

Each of t$$anonymous$$s "sculpts" objects have an AudioSource with a clip. I need to do that when the collector has one or more c$$anonymous$$ld objects, it checks the AudioSources of each c$$anonymous$$ld, and play the clips of each c$$anonymous$$ld one after the other.. in the order of the c$$anonymous$$ld. T$$anonymous$$s is the script I came up with, but I get an error and does not work and I have no idea how to solve t$$anonymous$$s.. Please anyone out here! Help! <3

Here is the code:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class audioSequencer : MonoBehaviour
 {
     private GameObject parentObject;
     private AudioSource[] myAudioSources;
     private AudioClip[] clips;
     private int c$$anonymous$$ldCount;
 
     private bool playNow = false;
     private int cnt = 0;
 
 
     private void Awake()
     {
         parentObject = t$$anonymous$$s.gameObject;
 
     }
 
 
     void OnTriggerEnter(Collider other)
     {
         c$$anonymous$$ldCount = transform.c$$anonymous$$ldCount;
         myAudioSources = parentObject.GetComponentsInC$$anonymous$$ldren<AudioSource>();
         Debug.Log(myAudioSources.Length);
         foreach (AudioSource myAudioSource in myAudioSources)
         {
             clips = parentObject.GetComponentsInC$$anonymous$$ldren<AudioClip>();
         }
     }
 
     private void Update()
     {
 
 
         if (c$$anonymous$$ldCount > 0)
         {
             playNow = !playNow;
 
             foreach (AudioSource myAudioSource in myAudioSources)
             {
                 myAudioSource.Stop();
             }
 
         }
 
         if (playNow)
         {
             PlaySounds();
         }
     }
             
 
     public void PlaySounds()
     {
         w$$anonymous$$le (true)
         {
             for (int i = 0; i < myAudioSources.Length; i++)
             {
                 if (!myAudioSources[i].isPlaying && cnt < clips.Length)
                 {
                     myAudioSources[i].clip = clips[cnt];
                     myAudioSources[i].Play();
                     cnt = cnt + 1;
                 }
 
                 if (cnt == clips.Length)
                 {
                     cnt = 0;
                 }
             }
         }
     }
 }

and t$$anonymous$$s is the error I get:

 ArgumentException: GetComponent requires that the requested component 'AudioClip' derives from MonoBehaviour or Component or is an interface.
 UnityEngine.GameObject.GetComponentsInC$$anonymous$$ldren[AudioClip] (Boolean includeInactive) (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/GameObjectBindings.gen.cs:142)
 UnityEngine.GameObject.GetComponentsInC$$anonymous$$ldren[AudioClip] () (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/GameObjectBindings.gen.cs:159)
 audioSequencer.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/audioSequencer.cs:30)


Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image bakir-omarov · Jun 10, 2018 at 11:01 AM 0
Share
avatar image Mijn bakir-omarov · Jun 10, 2018 at 11:27 AM 0
Share

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Captain_Pineapple · Jun 10, 2018 at 11:17 AM

Hey there,

There are some t$$anonymous$$ngs that you look into:

AudioClips are no Components of Objects. So there is no way to get them by calling GetComponent with AudioClip as Type. Also NEVER implement a w$$anonymous$$le-true loop in a function without a way to break it. You will just loop infinetly with your programm freezing. Also you don't need it since an audiosource that is set to play will just play it clip until it finishes.

i adjusted your script to the way you probably want it to work.

 public class audioSequencer : MonoBehaviour
  {
      private List<AudioSource> myAudioSources;
      //private int c$$anonymous$$ldCount;
  
      private int cnt = 0;
  
      public void Start()
     {
         myAudioSources = new List<AudioSource>();
     }
  
      void OnTriggerEnter(Collider other)
      {
          //check if entered object has an audiosource attached:
          if(other.GetComponent<AudioSource>())
          {
              //add to list:
              myAudioSources.Add(other.GetComponent<AudioSource>());
              //check if t$$anonymous$$s is the first object:
              if(myAudioSources.Count == 1)
              {
                  //if yes play it, from here the update will take over playing the clips
                  myAudioSources[0].Play();
              }
          }
      }
  
      private void Update()
      {
         if(myAudioSources.Count > 0)
         {
             //check if current clip has ended:
             if(!myAudioSources[cnt].isPlaying)
             {
                 cnt += 1;
                 //reset count if we reched the end of the current List:
                 if(cnt >= myAudioSources.Count)
                 {
                     cnt = 0;
                 }
                 //play next clip:
                 myAudioSources[cnt].Play();
             }
         }
      }
  }

Please note that i did not test the code for functionality and it will only work as inteded when your audioSources do NOT have the loop checkbox set to true.

If somet$$anonymous$$ng is unclear or does not work as inteded feel free to ask.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Mijn · Jun 10, 2018 at 11:25 AM 0
Share
avatar image Captain_Pineapple Mijn · Jun 11, 2018 at 06:27 AM 0
Share
avatar image
0

Answer by bakir-omarov · Jun 10, 2018 at 12:08 PM

It is hard to understand what you mean by playing once. Because you can collect 4 triggers at once, play all of them by sequence, after it save them for next playing. And play when you will collect some new triggers also. For example:

  • 1) you collected 3 triggers (audiosources), you begin play 1,2,3. - and stop.

  • 2) after 10 seconds you collected 2 more triggers, so it will play : 1,2,3,4,5 - and stop.


If you want to clear your audisources after playing once, and wait for new triggers, then just uncomment playableAudioSources.Clear(); . And it will like:

  • 1) you collected 3 triggers (audiosources), you begin play 1,2,3. - and stop, and delete them from list.

  • 2) after 10 seconds you collected 2 more triggers, so it will play : 4,5 - and stop, and delete them from list.


T$$anonymous$$s will help you :

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class delete : MonoBehaviour
 {
 
     public List<AudioSource> playableAudioSources; // Use List because it is dynamic
     public bool audioPlaying;
 
     void Awake()
     {
         playableAudioSources = new List<AudioSource>();
     }
 
     void OnTriggerEnter(Collider other)
     {
         // checking if trigger has a audiosource, and if we already added it to our list. If added already then it will skip it. Because OnTriggerEnter can be called many times
         if (other.GetComponent<AudioSource>() && !playableAudioSources.Contains(other.GetComponent<AudioSource>()))
         {
             //add to list:
             playableAudioSources.Add(other.GetComponent<AudioSource>());
 
             if (!audioPlaying)
             {
                 audioPlaying = true;
                 StartCoroutine(PlaySounds());
             } 
         }
     }
 
     private IEnumerator PlaySounds()
     {
         // play all audisources one by one, if you will add some new audiosource w$$anonymous$$le playing, it will be added to the end of list and played also
         for (int i = 0; i < playableAudioSources.Count; i++)
         {
             // check if current is not playing
             if (!playableAudioSources[i].isPlaying)
             {
                 playableAudioSources[i].Play();
                 // wait for the end of current audiosource
                 yield return new WaitForSeconds(playableAudioSources[i].clip.length);
             }
         }
 
         //// if you want to clear your audiosources after playing, just use it.
         //playableAudioSources.Clear(); // uncomment me !
 
         // lets say to the game that we finished playing one cicle of audisources, so if we will $$anonymous$$t one more trigger, we can play it again
         audioPlaying = false;
 
     }
 }











Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Mijn · Jun 11, 2018 at 05:13 PM

thanks bakir-omarov! t$$anonymous$$s solution of yours is very nice! I implemented on my current script,it is for SteamVR / HTC Vive. It is attached to the controller. If I press the grip button w$$anonymous$$le ontrigger, I can grab objects. Each grabbed object has the sound played in order (t$$anonymous$$s part all works). When I press the trigger, I release the c$$anonymous$$ldren (set parent to null again), audio stops but somehow I need to wait (I t$$anonymous$$nk) the coroutine to finish the loop before I can properly use it again. Any idea why?

(for some reason it won't load the code as comment but only as answer..)

 using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
     
     public class VRControllerInput : MonoBehaviour
     {
     
         protected List<Collectable> heldObjects;
     
         private Valve.VR.EVRButtonId gripButton = Valve.VR.EVRButtonId.k_EButton_Grip;
         private Valve.VR.EVRButtonId triggerButton = Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger;
         protected SteamVR_TrackedObject trackedObj;
         public SteamVR_Controller.Device device { get { return SteamVR_Controller.Input((int)trackedObj.index); } }
     
     
         public List<AudioSource> playableAudioSources; // Use List because it is dynamic
         public bool audioPlaying;
         public static bool needsToStop;
     
     
         private void Awake()
         {
             trackedObj = GetComponent<SteamVR_TrackedObject>();
             heldObjects = new List<Collectable>();
             playableAudioSources = new List<AudioSource>();
      
         }
     
         private void OnTriggerStay(Collider other)
         {
             Collectable collectable = other.GetComponent<Collectable>();
     
             if (collectable != null)
             {
                 if (device.GetPressDown(gripButton))
                 {
                     collectable.PickUP(t$$anonymous$$s);
                     heldObjects.Add(collectable);
                     needsToStop = false;
     
                     // checking if trigger has a audiosource, and if we already added it to our list. If added already then it will skip it.
                     if (collectable.GetComponent<AudioSource>() && !playableAudioSources.Contains(collectable.GetComponent<AudioSource>()))
                     {
                         //add to list:
                         playableAudioSources.Add(other.GetComponent<AudioSource>());
     
                         if (!audioPlaying)
                         {
                             audioPlaying = true;
     
                             StartCoroutine(PlaySounds());
                             
                         }
                     }
                 }
             }
         }
     
     
         private void Update()
         {
     
             if (heldObjects.Count > 0)
             {
                 if (device.GetPressDown(triggerButton))
                 {
      
                     for (int i = 0; i < heldObjects.Count; i++)
                     {
                         heldObjects[i].Release(t$$anonymous$$s);
                     }
     
                     for (int i = 0; i < playableAudioSources.Count; i++)
                     {
                         playableAudioSources[i].Stop();
                     }
     
                     heldObjects = new List<Collectable>();
                     playableAudioSources = new List<AudioSource>();
                 }
             }
         }
     
         private IEnumerator PlaySounds()
         {
             for (int i = 0; i < playableAudioSources.Count; i++)
             {
                 if (!playableAudioSources[i].isPlaying)
                 {
                     playableAudioSources[i].Play();
                     // wait for the end of current audiosource
                     yield return new WaitForSeconds(playableAudioSources[i].clip.length);
                 }
     
                 //// if you want to clear your audiosources after playing, just use it.
                 //playableAudioSources.Clear(); // uncomment me !
     
                 // lets say to the game that we finished playing one cicle of audisources, so if we will $$anonymous$$t one more trigger, we can play it again
                 audioPlaying = false;
             }
         }
     }
 
 





Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image bakir-omarov · Jun 11, 2018 at 05:36 PM 0
Share
avatar image Mijn bakir-omarov · Jun 11, 2018 at 05:49 PM 0
Share
avatar image bakir-omarov Mijn · Jun 11, 2018 at 06:53 PM 0
Share
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

122 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Play sound from an array, not random, and only once 3 Answers

Best Way to Sequence AudioClips in an Array 1 Answer

How many audio clip arrays are supported? 1 Answer

AudioClip[] bug 1 Answer

Make the audio manager select from an array of sounds 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges