这很复杂。虽然,我不会说是
团结一致。它可以精确地完成,但不能用
InvokeRepeating
.
你还有两种方法可以做到这一点。
1.
.
Coroutine
如果
调用重复
太慢了,可能是因为它使用反射来调用函数,或者可能是实现不完美。
WaitForSecondsRealtime
而不是
WaitForSeconds
.
并且不依赖于等待的帧速率。
等待几秒钟
做
public float samplingRate = 60f; // sample rate in Hz
void OnEnable()
{
StartCoroutine(startSampling());
}
IEnumerator startSampling()
{
WaitForSecondsRealtime waitTime = new WaitForSecondsRealtime(1f / samplingRate);
while (true)
{
SampleNow();
yield return waitTime;
}
}
public void SampleNow()
{
Debug.Log("Called");
dataList.Add(new Data(Time.time, transform.position.x, transform.position.y, transform.position.z));
}
.
Thread
(推荐)
我建议您使用它,因为您将完全避免Unity的主线程降低帧速率。在另一个系统中执行计时器操作
线
.
问题是你
不会
transform.position.x
或
Transform
在另一个线程中初始化。团结阻止你这样做。你必须执行
dataList.Add(new Data(Time.time, transform.position.x...
大体上
线
另一种选择是存储
transform.position
在全球
Vector3
变量,然后从另一个变量访问它
线
.
你
不能
也使用
Time.time
线
并将不得不把它放在主要位置
线
,然后将其存储在将在
线
作用
您还必须使用
lock
关键字来制作它
线程安全
请注意,使用
锁
关键字会减慢你的游戏速度
小的
一点它将从您的游戏中删除至少2或3个帧,但这是必需的,值得它提供的好处和保护。
下面的代码将完成我刚才所说的一切。出于测试目的,采样率设置为每秒2次。您可以在中将其更改为60Hz
samplingRate
变量,当您认为它是工作属性时。
private List<Data> dataList = new List<Data>();
Thread samplingThread;
const float samplingRate = 2f; // sample rate in Hz
Vector3 posInThread;
float TimetimeInThread;
private System.Object threadLocker = new System.Object();
void OnEnable()
{
startSampling();
}
void startSampling()
{
samplingThread = new Thread(OnSamplingData);
samplingThread.Start();
}
void Update()
{
lock (threadLocker)
{
//Update this values to be used in another Thread
posInThread = transform.position;
TimetimeInThread = Time.time;
}
}
void OnSamplingData()
{
long oldTime = DateTime.Now.Ticks;
long currentTime = oldTime;
const float waitTime = 1f / samplingRate;
float counter;
while (true)
{
currentTime = DateTime.Now.Ticks;
counter = (float)TimeSpan.FromTicks(currentTime - oldTime).TotalSeconds;
if (counter >= waitTime)
{
//Debug.Log("counter: " + counter + " waitTime: " + waitTime);
oldTime = currentTime; //Store current Time
SampleNow();
}
Thread.Sleep(0); //Make sure Unity does not freeze
}
}
public void SampleNow()
{
Debug.Log("Called");
lock (threadLocker)
{
dataList.Add(new Data(TimetimeInThread, posInThread.x, posInThread.y, posInThread.z));
}
}
void OnDisable()
{
if (samplingThread != null && samplingThread.IsAlive)
{
samplingThread.Abort();
}
samplingThread.Join(); //Wait for Thread to finish then exit
}