如何在 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,但可能仍然不是正确的方法)。 这不是属性,而是语句(如forswitch)。通常带有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 属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Unity3D 项目中启用 c# 7 功能

有没有办法一次在 Unity 3d 动画窗口中添加多个属性?

Unity3d如何同时打开多个项目

Unity3D中如何将导入的资源包删除

unity3d 如何代码修改某个shader的颜色

unity HTC Vive 通过手柄控制3D物体移动、旋转