[英]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.