Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved how to convert string to audioclip?

Discussion in 'Scripting' started by Deleted User, Mar 26, 2023.

  1. Deleted User

    Deleted User

    Guest

    i need to reproduce audio depending on given string
    playing an specific animation with a string is easy. it's just this:
    Code (CSharp):
    1. [SerializeField] Animator animator;
    2.  
    3. animator.Play(clouds);
    but how to play an audiosource or audioclip with string?

    further context i'm with a dialogue system that uses tags (strings). and i want to control audio from it



    THANKS IN ADVANCE!
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,144
    Set up your audio to be addressables. Use the string as the addressable path and load up the audioclip and pass that to your audiosource. At least, that's how I did it in a recent project. But, you really just need a way to associate your string with the proper audioclip.
     
    Deleted User likes this.
  3. Deleted User

    Deleted User

    Guest

    haven't heard of addressables. i'll give them a try
    THANKS! <3
     
  4. Deleted User

    Deleted User

    Guest

    how i associate string with audioclip?

     
    Last edited by a moderator: Mar 27, 2023
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,144
    Ah, you might be better using scriptableobjects.

    But for addressables, you need to be able to load it from the addressable system.

    Code (CSharp):
    1. public static void GetAudioClip(string clipId, Action<AudioClip> callback)
    2. {
    3.    Addressables.LoadAssetAsync<AudioClip>(clipId).Completed += (AsyncOperationHandle<AudioClip> handle) =>
    4.    {
    5.        callback?.Invoke(handle.Result);
    6.    }
    7. }
    Essentially you pass in the addressable path and it will return the audioclip tied to that path. Note that you can change the addressable path to whatever you want, you don't have to use the default it puts in for you.
     
  6. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    AudioSource.clip is of type AudioClip, you are assigning a value of type string to it. AudioClips are not strings, therefor you cant make the assignment to that variable.

    you need something like
    Code (CSharp):
    1. audioSource.clip = GetClipFromString("cloud");
    2.  
    3. AudioClip GetClipFromString(string clipName){
    4. //return the AudioClip associated with clipName
    5. }
    this function is an example of an association from string to AudioClip that Brethnann was referring to. The simplest way for you to acheive your goal may be the following, but i dont think it is very scaleable and wouldn't use it for 10000 clips.


    Code (CSharp):
    1. public class AudioClipGetter{
    2.  
    3. [SerializeField] List<AudioClip> clips; //add your clips to this list in inspector
    4. Dictionary<string, AudioClip> dict;
    5. void Awake(){
    6.     dict = new Dictionary<string, AudioClip>();
    7.     for(int i = 0; i < clips.Count; i++){
    8.             AudioClip clip = clips[i];
    9.             dict[clip.name] = clip;
    10.     }
    11. }
    12.  
    13. //this is your association function
    14. public AudioClip GetClip(string clipName){
    15.     if(dict.ContainsKey(clipName)) return dict[clipName];
    16.     else return null;
    17. }
    18.  
    19. }
    Again this is not very scaleable, but should do the job.
     
    Last edited: Mar 28, 2023
    Deleted User and Bunny83 like this.
  7. Deleted User

    Deleted User

    Guest

    thanks!
    Code (CSharp):
    1.     for(int i = 0; i < clips.Count; i++){
    2.         dict[clip.name] =clip;
    3.     }
    that code is there to populate the dictionary right? but what's happening in second line? i don't get it
     
  8. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    Yes that populates the dictionary. if by second line, you mean the 'GetClip' function, that is how you will be able to get an audioClip from a string, allowing you to perform
    Code (CSharp):
    1. myAudioSource.clip = myClipGetter.GetClip("cloud.mp3");
    notice the return type of the function is of type AudioClip, making it a valid value to assign to audioSource.clip.
    I added some more notes to the class for you or anyone in the future stumbling upon this.

    Code (CSharp):
    1. public class AudioClipGetter{
    2.     //add your clips to this list in inspector
    3.     [SerializeField] List<AudioClip> clips;
    4.  
    5.     //this is the the object that will hold a mapping of strings to AudioClips
    6.     Dictionary<string, AudioClip> dict;
    7.  
    8.  
    9.     void Awake(){
    10.         //initialize an empty dictionary, so we can add clip names and their associated AudioClips to it
    11.         dict = new Dictionary<string, AudioClip>();
    12.  
    13.         //add all clips to the dictionary, such that they string that will be used to be associated
    14.         //with them will be the name of the clip file (i.e. 'cloud.mp3')
    15.         for(int i = 0; i < clips.Count; i++){
    16.             AudioClip clip = clips[i];
    17.             dict[clip.name] = clip;
    18.         }
    19.     }
    20.  
    21.     //this is your association function. you provide it the name of the clip (i.e. 'cloud.mp3')
    22.     //as the parameter to the function. It returns the clip with that name, if you added that clips
    23.     //to the serialized list field 'clips'.
    24.     public AudioClip GetClip(string clipName){
    25.         //check that there is a clip associated with clip
    26.         if(dict.ContainsKey(clipName)) return dict[clipName];
    27.         else return null;
    28.     }
    29. }
     
    Last edited: Mar 28, 2023
    Deleted User likes this.
  9. Deleted User

    Deleted User

    Guest

    thanks!!
    by second line i meant the second one in the code i quoted. sorry for the confusion! TT_TT
    Code (CSharp):
    1. dict[clip.name] =clip;
     
  10. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    ahh, that is what actually creates the mapping in the dictionary between clip.name and the AudioClip. I editted that part of the code in my response because there was a missing line of code. check out "for loop" and "Dictionary" in C# (but they are popular in most languages) if any of it seems foreign to you.
     
    Deleted User likes this.
  11. Deleted User

    Deleted User

    Guest

    thanks!! <3
     
    TzuriTeshuba likes this.