2017-08-27 88 views
4

我使用libpd4unity包與Pure Data進行通信。我收到來自Pure Data的爆炸聲,LibPD.Bang。在爆炸事件中,我通過FMOD播放聲音。Unity3D中的幀率無關事件

問題是,我經常收到劉海,例如,每500毫秒一次,但事件不會在特定長度的幀中觸發。通常長度改變1幀或更少。

有沒有解決這個問題的方法?例如一個獨立於幀率的事件?我想知道Unity3D中的事件(委託)是否獨立於幀速率。

因爲有節奏播放每個聲音和只有1幀的廢墟節奏。

我需要同步聲音才能播放每個單獨的砰砰聲。

+0

有人嗎?任何解決方案有什麼建議? – ATHellboy

+0

你可以分享你接收和詳細說明劉海的代碼嗎? – SteakOverflow

回答

1

關於你的問題,如果代表依賴或獨立於Unity的幀率,那麼沒有直接的答案。這取決於代表如何被調用。他們是從一個線程調用?它們是在一個線程中執行的嗎?協程不是獨立於框架的,它們在Unity的循環中執行。

以下腳本應該闡明處理協同代理和線程代理的區別。

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(); 
    } 
} 

如果你把它連接到一個遊戲物體,讓團結發揮了幾秒鐘,你會看到代表是從協程稱爲次數爲而次委託被稱爲執行幀數從線程會更大。

我有類似於Pure Data的接口軟件的經驗,我想你需要的是一個(相當典型的)線程與你所有的委託,爲Unity創建一個命令隊列並在Unity更新中消化它。 在特定情況下不知道libPD可能不是案例的最佳做法,但它是一種廣泛使用的方法。基本上是生產者 - 消費者模式。

根據示例GUITextScript.cs,libPD僅要求您訂閱正確的代表。圖書館在執行這些操作時無法控制;所以如果你一直有這個問題,值得向開發者提交一個錯誤報告。