par , 24/11/2020 à 22h00 (613 Affichages)
Unity est un très bon outil.
Par exemple, imaginons que vous souhaitez manipuler des textures, ou des images, ce qui revient au même, mais comme disait le grand-frère, "La guerre c'est la paix". Enfin bref. Si vous souhaitez importer, exporter, serialiser, manipuler des images dans Unity, vous avez à disposition pléthore de classes, fonctions, outils, tout ce dont vous avez besoin, parfois même tellement qu'on peut s'y perdre.
En revanche, si vous souhaitez manipuler des fichiers audio, j'aime autant vous prévenir de suite : c'est la chienlit !
Il n'y a même pas une fonction pour charger un fichier audio !
Non mais mais allô ?! Les mecs ils font un éditeur de jeu vidéo et ils prennent pas leur shampooing ?!
Nous, on aimerait bien pouvoir écrire du code genre :
AudioSource source = AudioSource.LoadFromFile("C:/mon/son/qui/tue.wav");
Car c'est l'équivalent de ce que je fais pour mes textures.
Et bien non, on peut pas faire ça.
Tenez-vous bien, pour charger un fichier audio qui est sur votre disque dur, il faut utiliser... tenez-vous bien... un client http qui va faire une requête !
Voici un exemple de code fournit par les gars de la team Unity et qui est censé fonctionner :
1 2 3 4 5
| string url = "file://C:/mon/son/qui/tue.wav";
WWW audioLoader = new WWW(url);
while (!audioLoader.isDone)
System.Threading.Thread.Sleep(100);
audioSource.clip = audioLoader.GetAudioClip(false, false, AudioType.WAV); |
Bon c'est un peu relou, mais soit, allons-y.
Bon évidemment, ça ne fonctionne pas.
Premier problème, la classe WWW est deprecated.
Bon c'est pas grave, ils nous disent qu'on peut la remplacer par la classe UnityWebRequest.
Ok.
Sauf que UnityWebRequest c'est un peu relou parce qu'il faut l'utiliser dans une coroutine. C'est un peu chiant mais allons-y. Du coup le code devient un truc comme ça :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public LoadAudioFile(AudioSource sound)
{
Action<AudioClip> callback = delegate (AudioClip clip)
{
if (clip != null)
sound.clip = clip;
};
LoadClip("file://C:/mon/son/qui/tue.wav", AudioType.WAV, callback);
}
private void LoadClip(string path, AudioType audio_type, Action<AudioClip> callback)
{
StartCoroutine(LoadAudioClipFromUrl(path, audio_type, (audioClip) =>
{
if (audioClip != null)
{
callback.Invoke(audioClip);
}
}));
}
IEnumerator private LoadAudioClipFromUrl(string audio_url, AudioType audio_type, Action<AudioClip> callback)
{
using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestMultimedia.GetAudioClip(audio_url, audio_type))
{
while (!www.isDone)
System.Threading.Thread.Sleep(100);
yield return www.SendWebRequest();
if (www.isNetworkError)
Debug.Log(string.Format("Error downloading audio clip at {0} : {1}", audio_url, www.error));
callback.Invoke(UnityEngine.Networking.DownloadHandlerAudioClip.GetContent(www));
}
} |
Bon ok, c'est vachement de code pour pas grand chose mais soit.
Sauf que ...
Si le fichier qu'on veut charger n'existe pas, ben on est bloqué dans une boucle infinie et c'est pas beau à voir. Même alt+F4 ne nous sauve pas toujours.
Bon ok, alors on ajoute des timeout et nbTry... et on gère tous les cas bizarres où le Network est "buzy"... oui parce que je vous rappelle que ce qu'on fait là, c'est une requête GET de type HTTP ... enfin bref...
Après avoir bien blindé le code, ça semble fonctionner. Dans l'éditeur en tout cas. C'est quand même relou : tout ça pour charger un pauvre fichier audio... enfin bref ...
Maintenant voyons voir ce que ça donne en stand alone.
Hé bien là, figurez-vous, c'est le drame ! Les requêtes http partent dans le vide interstellaire et sont incapables de trouver un foutu fichier local !
Même avec le path codé en dur, rien à faire : vous vous mangez des 404 dans le museau; l'enfer de Dante est une sinécure à côté.
Et votre beau fichier de log, que vous avez maintenu parfaitement propre avec la plus grande fierté depuis le début du projet, à tel point que lorsque le boss commence à péter une durite, seuls ces magnifiques fichiers de logs peuvent le calmer. Et bien vos beaux fichiers de logs, ben là ils sont complètement fuckés, parce que des requêtes http qui n'aboutissent pas, ben ça en fout partout !
Du coup, ben là c'est moi qui commence à pèter une durite. Et encore, ce n'est que le début ...