delspeedy Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Hallo @all Wollte mal nachfragen wie ihr Abfragen löst die nur sehr ungenau überprüft werden müssen. In meinen Fall geht es darum, ob ein Sound noch abgespielt wird, oder schon beendet ist. Habe es derzeit über StartCoroutine gelöst. void Start () { ... StartCoroutine (CheckIsMusicPlaying (1.25f)) } IEnumerator CheckIsMusicPlaying (float waitSeconds) { while (!stopMusic) { yield return new WaitForSeconds (waitSeconds); if (!audioScoures[lastAudioClip].isPlaying) { PlayRandomMusic(); } } void PlayRandomMusic () { Debug.Log ("audioScoure: " + audioScoures [lastAudioClip].clip.name + "ended"); int tempAudioClip = lastAudioClip; while (tempAudioClip == lastAudioClip) { tempAudioClip = Random.Range (0, audioScoures.Length); } lastAudioClip = tempAudioClip; audioScoures [lastAudioClip].Play (); Debug.Log ("Play audioScoure: " + audioScoures [lastAudioClip].clip.name); } [size=4] [/size] Thx & bye delspeedy Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
napoleon12 Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 nix Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Mit Coroutine würd ich das nicht machen, das ist wie mit Atombomben auf Spatzen geschossen xD Ich hätte das jetzt mit einem Timer gemacht. float timer = 0.0F; float time = 3.0F; //wie oft soll überprüft werden? 3 = 3 Sekunden void Update() { if(timer < Time.time) { //dein random music code timer = Time.time + time; } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
DynamicHead Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Da fehlt glaube ich die Time.deltaTime.. irgendwie.. Mach' es einfach so: function Update () { if (!audio.isPlaying) { audio.clip = otherClip; audio.Play(); } } Da wird ja nur eine bool-Variable abgefragt. Kleiner oder größer ( für die Zeit ) ist wahrscheinlich zeitaufwendiger für den Computer als einen boolschen Wert zu überprüfen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Da fehlt glaube ich die Time.deltaTime.. irgendwie.. Nein, bei mir nicht. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
DynamicHead Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Und wie verhält sich Dein Skript bzw. Time.time, wenn man die Anwendung im Hintergrund pausiert ? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Wird ebenfalls pausiert. Time.time ist 0 wenn das Spiel gestartet wird und erhöht sich stetig. Gib doch mal in irgend einer Update() Funktion Debug.Log(Time.time); ein und teste es selbst. Verwende diese Art des Timings sehr oft und bin sehr zufrieden damit. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
DynamicHead Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Aha.. gut zu wissen. Ich verwendet das eigentlich nie, sondern Time.deltaTime. ( Die Doku beschreibt das nämlich etwas schwammig: "This is the time in seconds since the start of the game." Und geht nicht darauf ein, was beim pausieren passiert. ) Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mark Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Der Corouztinen Vorschlag ist bisher das was am wenigsten Performance ziehen sollte, da dadurch keine extra Update Methode erforderlich ist. Update ist langsamer als eine solche Couroutinen da Unity intern Update per Reflection Invoke oder vergleichbarem aufruft. Nach der Couroutine wäre der nächst beste Vorschlag einfach isPlaying direkt in Update abzufragen, da ich bezweifle dass dies ein signifikant teuer Aufruf ist und man ihn sicher hunderte male pro Frame ausführen kann ohne dabei einen merkbaren Leistungseinbruch zu bemerken. Auch wäre es machbar zusätzlich zur Coroutine sowas zu machen: Invoke("AudioClipStopped", audioClip.length); ... void AudioClipStopped() { ... } Wobei man hier innerhalb von AudioClipStopped überprüfen sollte ob er wirklich gestippt wurde, nur um sicher zu gehen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
delspeedy Geschrieben 21. Mai 2014 Autor Melden Share Geschrieben 21. Mai 2014 Vielen Dank für Eure zahlreichen Infos hierzu. Habe mal getestet wie lange "if(!audiosource.isPlaying)..." in der Update Methode verbraucht 2GHz mobile CPU/Im Editor/For-Schleife - Time for !isPlaying x 10000: 00:00:00.0014351 stopwatch.Start(); for (int i = 0; i < 10000; i++) { if (!audioScoures[lastAudioClip].isPlaying) { PlayRandomMusic(); } } stopwatch.Stop(); Debug.Log ("Time for !isPlaying x 10000: " +stopwatch.Elapsed); stopwatch.Reset(); Leider messe ich natürlich die Schleife und den Array-Zugriff mit. Auf Dauer sollte die Coroutine merklich CPU Zeit sparen. Vor allem wenn man sehr viele Ereignisse timen möchte. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mark Geschrieben 21. Mai 2014 Melden Share Geschrieben 21. Mai 2014 Du misst da aber nicht nur isPlaying sondern auch PlayRandomMusic, ist das beabsichtigt? Und interessiert dich wirklich wieviel zeit 10000 Durchgänge insgesamt beanspruchen? Nichts gegen Coroutinen, aber ich hab den Eindruck hier wird zu früh optimiert Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
delspeedy Geschrieben 21. Mai 2014 Autor Melden Share Geschrieben 21. Mai 2014 Habe 10000 Schleifendurchläufe um den Durchschnittswert einer Abfrage besser berechnen zu können. PlayRandomMusic wird in dem Beispiel nie aufgerufen, da die Zeitspanne zu kurz ist um ans Ende des Musikstücks zu gelangen. Wollte nicht optimieren sondern wissen ob man Ereignisse die nur "ungenau" abgefragt werden müssen, so implementiert werden können. isPlaying hat sich nur eben gerade angeboten - bezieht sich aber generell auf Ereignisse die überprüft werden müssen. p.s Wann benutzt man "StartCoroutine_Auto" - ist nicht in der Unity-Doku Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
DynamicHead Geschrieben 22. Mai 2014 Melden Share Geschrieben 22. Mai 2014 InvokeRepeating scheint in der Tat schneller als Coroutinen ( Platz 2 ) und Update ( #3 ) zu sein. Trotzdem finde ich den Code leichter verständlich und weniger abstrakt, wenn man Update benutzt, denn man sieht ganz klar und deutlich, dass sich da in Update( ) was tut.. --Eine gestartete Coroutine oder Invoke gerät in richtig großen Projekten ggf. schnell mal in Vergessenheit, wobei gerade in großen Projekten der Performance-Gewinn unter Umständen nötig ist, den man durch Invoke oder Coroutinen hätte. Tja.. die Qual der Wahl.. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
delspeedy Geschrieben 23. Mai 2014 Autor Melden Share Geschrieben 23. Mai 2014 Super Info ...kann man InvokeRepeating auch von außen beenden? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mark Geschrieben 23. Mai 2014 Melden Share Geschrieben 23. Mai 2014 CancelInvoke könnte die Methode sein die das beenden kann. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.