繁体   English   中英

在while循环列表中,协程有时无法正常工作-C#Unity3D Rhythm Game

[英]In while loops list compare of coroutine not work sometimes - C# Unity3D Rhythm Game

我要做一个节奏游戏。

音乐播放时间是可变的,它随毫秒的播放而变化

List是一个浮动列表,具有我填充的时间(浮动秒),让我可以访问它,并用于与实例对象的音乐播放时间进行比较。

当列表时间=音乐时间,然后是即时对象。

但有时会丢失(列表中未找到值,但列表中确实存在值)。

这是我的假设。

我认为List.indexOf性能不好,线程有一些延迟。

音乐播放时间每毫秒变化一次,从团结到其他的一点延迟会导致丢失(如果声明则不会进入)

我不知道这是正确的。

谁能帮我。

这是我的代码。

IEnumerator Execute(MethodDelegate Start,MethodDelegate Stop)
    {
        while (true) {
            int res = result.IndexOf ((float)System.Math.Round (GameObject.Find ("Music").GetComponent<AudioSource> ().time, DigitalAdjust)-TimeAdjust);
            if (res!=-1) {
                if (res == result.Count-2) {
                    Stop.Invoke ();
                    print ("CoroutineStop");
                    StopCoroutine (_Execute);
                }
                //execute
                num=Positoin[res];
                print (res);
                Start.Invoke();
            }
            yield return null;
        }
    }

谢谢。

您可能是正确的。 您可能会错过一些if语句,因为您不完全匹配毫秒。 以下是一些有帮助的内容:

如果您的游戏达到60 FPS(平滑渲染的通常速率),则每个帧大约需要16毫秒。 如果您的事件必须在精确的毫秒内触发,则您会错过一些事件,因为Execute函数调用之间的间隔约为16毫秒(每帧调用一次协程)。

一个解决方案是记住上一次调用Execute函数并检查之间的所有内容:

private float _lastTime;

IEnumerator Execute(MethodDelegate Start,MethodDelegate Stop)
{
    while (true) {            
        // here your code must check all the event between _lastTime and Time.time
        var lastTimeMilliseconds = (int)(_lastTime*1000);
        var currentTimeMilliseconds = (int)(Time.time*1000);
        for(int time = lastTimeMilliseconds+1; time <= currentTimeMillisedons; time++)
        {
            // let's say last frame was at time 1000ms
            // This frame occurs at time 1016ms
            // we have to check your list for events that have occured since last frame (at time 1001, 1002, 1003, ...) 
            // so we have a for loop starting at 1001 until 1016 and check the list
            int res = result.IndexOf ((float)System.Math.Round (time, DigitalAdjust)-TimeAdjust);
            if (res!=-1) 
            {
                if (res == result.Count-2) 
                {
                    Stop.Invoke ();
                    print ("CoroutineStop");
                    StopCoroutine (_Execute);
                }
                //execute
                num=Positoin[res];
                print (res);
                Start.Invoke();
            }
        }            

       // At the end, remember the time:
       _lastTime = Time.time;

        yield return null;
    }
}

检查Time类,您还可以访问Time.deltaTime以了解两个帧之间经过的时间,如果有帮助的话。

编辑 :根据您的评论要求,我在您的示例中添加了一些代码以更好地解释这一想法。 请注意,我不知道您的变量会做什么,因此您将不得不适应。 例如,Time.time给出自应用程序启动以来的时间。 自开始播放音频以来,您可能需要调整使用时间

另一个重要的事情:

  • GameObject.Find必须查看所有对象。 这真的很慢,不应该每帧都使用

  • GetComponent查找您所有的脚本,而且速度也很慢。 不应在每一帧使用它。

相反,请执行以下操作:

private AudioSource _audioSource;

private void Start()
{
     _audioSource = GameObject.Find ("Music").GetComponent<AudioSource> ();
}

这将仅检索一次源。 然后在代码中,您只需调用

_audioSource.time;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM