2017-08-27 86 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仅要求您订阅正确的代表。图书馆在执行这些操作时无法控制;所以如果你一直有这个问题,值得向开发者提交一个错误报告。