【问题标题】:Does Unity have a constructor when loading a scene?Unity 在加载场景时是否有构造函数?
【发布时间】:2016-02-29 05:22:55
【问题描述】:

我想在加载场景时使用正确的数据而不是占位符填充 UI。

当我调用“LoadSceneAsync”时,第一个被调用的对象是什么,以便我可以用正确的数据填充 UI 标签?我知道有一个场景 GameObject,但我不确定这是否符合我的需要。

我正在寻找某种构造函数,在加载新场景对象时调用;插入我的设置功能。

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    你说

    确实,我确实使用了“onlevelwasloaded”,但是当我调用它时,UI 元素可能不存在,准备就绪,这会导致错误

    这将是 Unity 中一个令人难以置信的严重错误! :)

    会不会是您在某处混淆了AwakeStart

    一种思考方式是,一旦您调用Start,您就会知道所有Awake 都已运行。

    当我调用“LoadSceneAsync”时,第一个被调用的对象是什么,所以我可以用正确的数据填充 UI 标签

    你们仍然在同一个框架内

    一旦您看到LoadSceneAsync,您就可以放心,一切都是Awake 'd。

    或者确实,一旦您使用Start,您就可以绝对确信一切都是Awake 'd。

    1) 是不是在您的某些 UI 元素(或其他)中,您在 Start 中正在做一些您应该在 Awake 中做的事情?

    2) 如果(出于某种原因)您想“等到下一帧”,也许只是在开发过程中 - 然后这样做,等待一帧。您会看到闪烁,但如果这是您想做的事情(出于某种原因),请执行此操作。

    3) 请注意,如果您的意思是要上网 获取某些东西,那么您当然必须等待帧(使用更新/协程),直到信息从网上返回, 明显地。 (怎么可能呢?)


    请注意,在实践中,应该在任何地方使用UnityEngine.Events.UnityEvent

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      依靠 Unity 内部功能并不总是可行的方法。尤其是在处理 RESTApi 时(这就是您在此处处理的内容)。

      除非你控制它,否则你不能假设一个对象会在另一个对象之前准备好。

      添加一个使用 Awake 的控制器脚本。在 Awake 中,调用您需要的所有方法,并在主要准备就绪时使用一些回调来生成辅助代码。

      public class MyController: MonoBehaviour{
      
          private ServerRequestController serverCtrl = null;
          private UIController uiCtrl = null;
          private void Awake(){
              serverCtrl = this.gameObject.AddComponent<ServerRequestController>();
              uiCtrl =this.gameObject.AddComponent<UIController>();
              serverCtrl.GetData(uiCtrl.SetUI);
          }
      }
      public class UIController:MonoBehaviour{
          public void SetUI(Data data)
          {
               SetTopImage(data.topImage);
               SetBottomImage(data.bottomImage);
      
              // And so on
          }
      }
      public class ServerRequestController:MonoBehaviour{
          public void GetData(Action onCompletion){
              // This may be a coroutine if you fetch from server
              Data data = GetDataFromSomewhere();
              // At this point, your data is ready
              onCompletion(data);
          }
      }
      

      多亏了这一点,您现在可以准确地知道一段代码何时准备就绪。

      【讨论】:

      • 太棒了。事实上,我确实使用了“onlevelwasloaded”,但是当我调用它时,UI 元素可能不存在,准备就绪,这会导致错误。这负责同步,这确实是处理问题的好方法。谢谢!
      • 我可以在我的单例游戏管理器中实现这个吗?该对象是在加载主菜单场景时加载的,因此在我加载新场景时它仍然存在。
      • 单例与持久对象无关。这实际上是两个独立的模式。如果你想让它持久化,你会使用 DontDestroyOnLoad。如果您希望使其成为单例,那么您将使其继承自单例类。两者都可以一起使用,因为它们不相关(它们在某些方面相互补充)。只需确保在返回创建经理的场景时没有创建新实例。你的单身人士应该注意这一点,但要注意它。
      • 在 Unity 等基于 ECS 场景的游戏引擎中不存在“单例”这种东西。请注意,每个游戏对象实际上都是一个单例。如果你认为你有一个单例你没有,而且你不了解 OO/ECS。 (这是一篇关于这个话题的愤怒文章!stackoverflow.com/a/35524924/294884)如果你有一个“游戏管理器”,这很好,那是一个“游戏对象”上的“脚本”。这里的所有都是它的。就是这么简单。
      • @fafase old bean - 代码中有错字吗?您必须在 Start 而不是 Awake 中这样做,否则一切都可能不是 Awake 'd,对吧?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 2016-09-20
      相关资源
      最近更新 更多