2017-08-27 3 views
4

Ich verwende das libpd4unity Paket, um mit Pure Data zu kommunizieren. Ich bekomme einen Knall von Pure Data mit LibPD.Bang. Bei einem Knallereignis spiele ich Sound von FMOD.Framerate unabhängiges Ereignis in Unity3D

Problem ist, dass ich Pony häufig, zum Beispiel einmal alle 500 ms, aber Ereignis nicht in bestimmter Länge des Rahmens ausgelöst wird. Normalerweise ändert sich die Länge 1 Frame weniger oder mehr.

Gibt es eine Lösung für dieses Problem? Zum Beispiel ein frameratenunabhängiges Ereignis? Ich möchte wissen, ob Ereignis (Delegat) in Unity3D Framerate unabhängig ist oder nicht.

Da gibt es Tempo für die Wiedergabe jedes Sounds und nur 1 Frame ruiniert den Rhythmus.

Ich muss Sounds für jedes einzelne Bang synchronisieren.

+0

Jeder? Irgendeine Lösungsmöglichkeit ? Irgendein Rat ? – ATHellboy

+0

Kannst du den Code teilen, wo du den Pony erhältst? – SteakOverflow

Antwort

1

In Bezug auf Ihre Frage, ob Delegierte abhängig oder unabhängig von der Framerate von Unity sind, gibt es keine direkte Antwort. Es hängt davon ab, wie die Delegierten aufgerufen werden. Werden sie aus einem Thread aufgerufen? Sind sie in einem Thread ausgeführt? Coroutinen sind nicht framefrequenzunabhängig, sie werden in der Unity-Schleife ausgeführt.

Das folgende Skript sollte den Unterschied zwischen dem Umgang mit Delegaten in Coroutinen und in Threads verdeutlichen.

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 
using System.Threading; 

public class DelegatesAndFramerate : MonoBehaviour { 

    delegate void MyDelegate(); 
    MyDelegate myDelegate1; // done with coroutines 
    MyDelegate myDelegate2; // done with threads 

    Thread thread; 
    bool threadDone = false; 

    private int frameCount = 0; 
    private int delegate1CallCount = 0; 
    private int delegate2CallCount = 0; 
    private int callerLoopsCount_coroutine = 0; 
    private int callerLoopsCount_thread = 0; 

    void Start() { 
     myDelegate1 += Elab1; 
     myDelegate2 += Elab2; 

     StartCoroutine(CallerCoroutine()); 

     thread = new Thread(new ThreadStart(CallerThread)); 
     thread.Start(); 
    } 

    void Update() 
    { 
     frameCount++; 
    } 

    void Elab1() 
    { 
     delegate1CallCount++; 
    } 

    void Elab2() 
    { 
     delegate2CallCount++; 
    } 

    IEnumerator CallerCoroutine() 
    { 
     while(true) 
     { 
      callerLoopsCount_coroutine++; 
      myDelegate1(); 
      yield return null; 
     } 
    } 

    void CallerThread() 
    { 
     while(!threadDone) 
     { 
      callerLoopsCount_thread++; 
      myDelegate2(); 
     } 
    } 

    void OnDestroy() 
    { 
     Debug.Log("Frame Count: " + frameCount); 
     Debug.Log("Delegate Call Count (Coroutine): " + delegate1CallCount); 
     Debug.Log("Delegate Call Count (Thread): " + delegate2CallCount); 
     Debug.Log("Caller Loops Count (Coroutine): " + callerLoopsCount_coroutine); 
     Debug.Log("Caller Loops Count (Thread): " + callerLoopsCount_thread); 

     threadDone = true; 
     thread.Join(); 
    } 
} 

Wenn Sie es zu einem Gameobject befestigen und lassen Unity für einige Sekunden spielen Sie werden sehen, dass die Zeiten der Delegat von einem Koroutine gleich der Anzahl der ausgeführten Rahmen aufgerufen wurde während der Zeit der Delegat aufgerufen wurde aus dem Thread wird es viel größer sein.

Ich habe Erfahrung in der Schnittstelle Software ähnlich wie Pure Data und ich denke, was Sie brauchen, ist ein (eher typisch) Thread mit allen Ihren Delegierten dort, erstellen Sie eine Warteschlange von Befehlen für Unity und verdauen Sie es in Unity's Update. Nicht wissen, libPD in der spezifischen dies ist möglicherweise nicht die beste Praxis für den Fall, aber es ist ein weit verbreiteter Ansatz. Grundsätzlich das Produzenten-Konsumenten-Muster.

Basierend auf dem Beispiel GUITextScript.cs erfordert libPD nur, dass Sie die richtigen Delegierten abonnieren. Sie haben keine Kontrolle darüber, wann diese ausgeführt werden, die Bibliothek hat; Wenn Sie dieses Problem haben, sollten Sie den Entwicklern einen Fehlerbericht schicken.