简体   繁体   English

如何在 Unity 3D 中使用 goto 属性?

[英]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循环!

  • Inside the while the condition is never changedwhile内,条件永远不会改变
  • And it can not be changed from the outside either since you run this in 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.我不是 100% 确定,但 afaik 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甚至比在一个循环检查每一帧实际上更好

  • check this once in start在开始时检查一次
  • only check it again once after the room properties have actually changed只有在房间属性实际更改后再次检查一次

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.

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