[英]How do I use goto attribute in Unity 3D?
Does this work?这行得通吗? This is in the start method, using photon for networking.
这是在启动方法中,使用光子进行联网。 I am trying to wait till room time is initialised.
我正试图等到房间时间初始化。
Wait:
if (!PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey("StartTime") )
{
goto Wait;
}
else
{
goto Continue;
}
Continue:
startTime = double.Parse(PhotonNetwork.CurrentRoom.CustomProperties["StartTime"].ToString());
In general I would say avoid using goto
at all !一般来说,我会说完全避免使用
goto
!
In almost all cases I can think of any other solution in my eyes is cleaner and better to read and maintain than goto
jumps.在几乎所有情况下,我认为任何其他解决方案都比
goto
跳转更清洁、更易于阅读和维护。 It is more a "relic" of former times.它更像是过去的“遗物”。 In the examples of
goto
might be the only use-case where it might make sense.. within a switch-case
or to break out of a nested loop.. but even there you can find other (in my eyes better) solutions.在
goto
的示例中,它可能是唯一有意义的用例.. 在switch-case
中或打破嵌套循环.. 但即使在那里你也可以找到其他(在我看来更好)的解决方案。
Your code basically equals writing你的代码基本上等于写
while(!PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey("StartTime")) { }
startTime = double.Parse(PhotonNetwork.CurrentRoom.CustomProperties["StartTime"].ToString());
And latest now I hope you see the huge issue : You have a neverending while
loop!最近,我希望你能看到一个巨大的问题:你有一个永无止境的
while
循环!
while
the condition is never changedwhile
内,条件永远不会改变Start
so the entire Unity main thread is blocked until that loop ends.Start
中运行它,因此整个 Unity 主线程被阻塞,直到该循环结束。 I'm not 100% sure but afaik PhotonNetwork
needs the Unity main thread to dispatch the received events -> your condition probably will never ever become true.PhotonNetwork
需要 Unity 主线程来分派接收到的事件 -> 你的情况可能永远不会成为真的。 You should rather use a Coroutine
.您应该使用
Coroutine
。 A Coroutine is like a small temporary Update
method.协程就像一个小的临时
Update
方法。 It is not async but rather runs right after Update
until the next yield
statement and thereby still allows your Unity main thread to continue rendering and doesn't freeze your entire application.它不是异步的,而是在
Update
之后运行直到下一个yield
语句,因此仍然允许 Unity 主线程继续渲染并且不会冻结整个应用程序。
// Yes, if you make Start return IEnumerator
// then Unity automatically runs it as a Coroutine!
private IEnumerator Start ()
{
// https://docs.unity3d.com/ScriptReference/WaitUntil.html
// This basically does what it says: Wait until a condition is true
// In a Coroutine the yield basically tells Unity
// "pause" this routine, render this frame and continue from here in the next frame
yield return new WaitUntil(() => PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey("StartTime"));
startTime = double.Parse(PhotonNetwork.CurrentRoom.CustomProperties["StartTime"].ToString());
....
}
Even better than checking this every frame in a loop at all would actually be甚至比在一个循环中检查每一帧实际上更好
So something like eg所以像例如
bool isInitialzed;
private void Start ()
{
TryGetStartTime (PhotonNetwork.CurrentRoom.CustomProperties);
}
private void TryGetStartTime(Hashtable properties)
{
if(!properties.Contains("StartTime")) return;
startTime = double.Parse(properties["StartTime"].ToString());
isInitialzed = true;
}
public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
TryGetStartTime (propertiesThatChanged);
}
And rather make other methods wait until isInitialized
is true.而是让其他方法等到
isInitialized
为真。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.