I’m interested in creating a script to automatically import a set of audio clips from an assets folder, and create a new scriptable object for each clip. The type of ScriptableObject I am creating is an AudioCue ripped straight out of the Unity Open Project (Chop Chop)
I’ve gotten 95% of the script complete, but I’m encountering a difficulty:
Each AudioCueSO I’m creating contains at least one referenceto an AudioClip.
I can load these clips directly by making a UnityWebRequestMultiMedia.GetAudioClip().
Unfortunately, when the script runs, each new AudioCueSO has Type mismatch
printed where the loaded AudioClip should be. I’m wondering what the proper way to instantiate scriptable objects with specific audioclip or prefab references is via script?
/// <summary>
/// The purpose of this scriptable object is to make a widget for automatically creating AudioCues from
/// AudioClips by simply providing a directory. This enables batch creation of AudioCueSO.
/// </summary>
[CreateAssetMenu(menuName = "DoGames/Audio/AudioCueImporter", fileName = "AudioCueImporter")]
public class AudioCueImporter : ScriptableObject
{
[SerializeField] protected string audioFilesDir = ".";
[SerializeField] protected AudioType audioType = AudioType.MPEG;
[Tooltip("If true, just print messages to the console. Don't create assets")]
[SerializeField] protected bool dryRun = false;
private Dictionary<AudioType, HashSet<string>> _audioExtensions = new Dictionary<AudioType, HashSet<string>>(){
{AudioType.MPEG, new HashSet<string>(){".mp3", ".mpeg"}},
{AudioType.ACC, new HashSet<string>(){".acc"}},
{AudioType.AIFF, new HashSet<string>(){".aiff"}},
{AudioType.IT, new HashSet<string>(){".it"}},
{AudioType.OGGVORBIS, new HashSet<string>(){".ogg"}},
{AudioType.WAV, new HashSet<string>(){".wav"}}
};
public void ImportAudioCues()
{
// May want to make this async
ImportAudioCuesRequests();
}
public void ImportAudioCuesRequests()
{
List<AudioClip> clips = new List<AudioClip>();
DirectoryInfo info = new DirectoryInfo(audioFilesDir);
FileInfo[] fileInfos = info.GetFiles();
foreach (FileInfo f in fileInfos)
{
if (_audioExtensions[audioType].Contains(f.Extension))
{
Debug.Log($"Creating AudioCueSO for {f.Name} {f.Attributes}");
// May want to wrap this in a `using`
UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(f.FullName, audioType);
UnityWebRequestAsyncOperation op = www.SendWebRequest();
op.completed += (AsyncOperation aop) =>
{
//while(!op.isDone){
// await Task.Delay(1000);
//}
if (www.result == UnityWebRequest.Result.ConnectionError)
{
Debug.LogError(www.error);
}
else
{
AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
// The path here needs to start with Assets/, not C://, etc
string audioCueFilename = Path.Combine(audioFilesDir, Path.GetFileNameWithoutExtension(f.FullName) + ".asset");
CreateAudioCueSOFromAudioClip(clip, audioCueFilename);
}
};
}
}
}
public void CreateAudioCueSOFromAudioClip(AudioClip clip, string audioCueFilename)
{
Debug.Log(clip);
AudioClipsGroup[] group = new AudioClipsGroup[] {
new AudioClipsGroup(
new AudioClip [] {clip}, //<------This clip becomes `Type mismatch`
SequenceMode.Random
)
};
AudioCueSO newCue = AudioCueSO.CreateAudioCueSO(
group
);
//ScriptableObject newCue = ScriptableObject.CreateInstance<ScriptableObject>();
Debug.Log($"Creating AudioCueSO {audioCueFilename}");
if (!dryRun)
{
try
{
AssetDatabase.CreateAsset(newCue, audioCueFilename);
}
catch
{
Debug.LogError($"Failed to create {audioCueFilename}!");
}
}
}
}