如何在 Unity 3D 中使用 goto 属性?
Posted
技术标签:
【中文标题】如何在 Unity 3D 中使用 goto 属性?【英文标题】:How do I use goto attribute in Unity 3D? 【发布时间】:2021-07-02 21:27:25 【问题描述】:这行得通吗?这是在启动方法中,使用光子进行联网。我正在尝试等待房间时间初始化。
Wait:
if (!PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey("StartTime") )
goto Wait;
else
goto Continue;
Continue:
startTime = double.Parse(PhotonNetwork.CurrentRoom.CustomProperties["StartTime"].ToString());
【问题讨论】:
请注意"attribute" has a specific meaning in .NET,因此您不应将其他事物称为“属性”。关于您的问题:根据我对 Unity 的了解,我希望您在Update()
方法中检查这种事情,而不是在某处有一个循环(最好作为 while
循环而不是使用goto
,但可能仍然不是正确的方法)。
这不是属性,而是语句(如for
或switch
)。通常带有goto
语句的代码往往会变得一团糟(称为spaghetti)。搜索“goto 被认为有害”)。一般来说,最好避免使用它们。 goto
很有用的情况很少见
【参考方案1】:
一般来说,我会说避免使用goto
完全!
在几乎所有情况下,我认为任何其他解决方案都比goto
jumps 更清洁、更易于阅读和维护。它更像是过去的“遗物”。在goto
的示例中,它可能是唯一一个可能 有意义的用例...... (在我看来更好)解决方案。
你的代码基本上等于写
while(!PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey("StartTime"))
startTime = double.Parse(PhotonNetwork.CurrentRoom.CustomProperties["StartTime"].ToString());
我希望你看到最新的大问题:你有一个永无止境的while
循环!
while
内,条件永远不会改变
而且它也不能从外部更改,因为你在Start
中运行它,所以整个 Unity 主线程被阻塞,直到循环结束。我不是 100% 确定,但 afaik PhotonNetwork
需要 Unity 主线程来调度接收到的事件 -> 你的情况可能永远不会成为现实。
您应该使用Coroutine
。协程就像一个小的临时 Update
方法。它不是异步的,而是在 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());
....
甚至比在循环中检查这个每一帧根本实际上会更好
在开始时检查一次 只有在房间属性实际发生变化后再次检查一次所以像例如
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);
而是让其他方法等到isInitialized
为真。
【讨论】:
感谢非常详细的解释,这对我很有帮助。编辑:哇!我从这个ans中学到了很多东西。特别是从 IEnumerator 开始以上是关于如何在 Unity 3D 中使用 goto 属性?的主要内容,如果未能解决你的问题,请参考以下文章