events - Unity3D中的帧率独立事件

标签 events unity3d delegates puredata libpd

我使用 libpd4unity包与纯数据通信。我收到了来自 Pure Data 的好评 LibPD.Bang .在爆炸事件中,我通过 FMOD 播放声音。

问题是,我经常收到刘海,例如每 500 毫秒一次,但事件不会在特定长度的帧中触发。通常长度变化 1 帧更少或更多。

这个问题有解决方案吗?例如帧率独立事件?我想知道 Unity3D 中的事件(委托(delegate))是否与帧速率无关。

因为播放每个声音都有节奏,只有一帧会破坏节奏。

我需要同步每个单独的 bang 播放的声音。

最佳答案

关于委托(delegate)是依赖于还是独立于 Unity 的帧速率的问题,没有直接的答案。这取决于如何调用您的委托(delegate)。他们是从线程中调用的吗?它们是在一个线程中执行的吗?
协程不是独立于帧率的,它们在 Unity 的循环中执行。

以下脚本应该阐明在协程和线程中处理委托(delegate)之间的区别。

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

如果将它附加到 GameObject 并让 Unity 播放几秒钟,您会看到从协程调用委托(delegate)的次数等于执行的帧数,而从线程调用委托(delegate)的次数会更大.

我在连接类似于 Pure Data 的软件方面有经验,我认为你需要的是一个(相当典型的)线程,那里有你的所有委托(delegate),为 Unity 创建一个命令队列并在 Unity 的更新中消化它。
不知 Prop 体的 libPD,这可能不是该案例的最佳实践,但它是一种广泛使用的方法。基本上是生产者-消费者模式。

基于示例GUITextScript.cs , libPD 只要求您订阅正确的委托(delegate)。您无法控制何时执行这些,库有;所以如果你一直遇到这个问题,我猜应该向开发人员提交一份错误报告。

关于events - Unity3D中的帧率独立事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45902776/

相关文章:

iphone - 当存在委托(delegate)时,respondsToSelector 的行为如何?

node.js - 在 Node.js 中 - 事件(EventEmitter 和 Listener Function 对象)和异步回调之间是否有任何关系

c# - Framework.Triggers 和 Style.Triggers 之间的区别?

c# - 在哪里订阅内部对象的事件?

c# - 从从未 Hook 的事件中解开委托(delegate)是否有任何问题?

c# - unity navmesh ai卡住了

ios - 在调用 ParentViewController 的委托(delegate)方法之前将消息从 ChildViewController 传递到 ParentViewController

unity3d - Unity Mirror - NetworkServer向目标客户端发送消息

c# 检查列表是否包含现有元素(不为空)

c# - 简化后台 worker 的匿名方法