【问题标题】:Inner Workings of Unity3d's GUI.ButtonUnity3d 的 GUI.Button 的内部工作原理
【发布时间】:2014-08-17 14:13:21
【问题描述】:

我对在 Unity3D 中编写脚本还是很陌生,我正在学习使用 GUI.Button() 在屏幕上绘制按钮的教程。

我对这个函数的工作原理很感兴趣。翻看documentation,GUI.Button的正确用法是在if语句中调用函数,并将按下按钮时要调用的代码放在if语句的块中。

我想知道的是,Unity3D 如何“神奇地”将 if 语句中的代码延迟到单击按钮之后?如果它是作为回调函数或其他东西传入的,那么我可以理解发生了什么。也许 Unity 在后台使用延续来延迟代码的执行,但是我觉得这会导致 if 语句之后的代码被执行多次。我只是想了解我的代码是如何工作的,而这个特定的功能对我来说仍然是“神奇的”。

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    我不知道它是否正确,但我通常将这种系统称为即时模式GUI

    Unity3D 如何“神奇地”延迟 if 语句中的代码,直到 点击按钮后?

    GUI.Button 如果在最后一帧的按钮范围内发生单击事件,则返回 true。基本上调用该函数你是轮询:每个按钮的每一帧都询问引擎是否发生了与该按钮(屏幕区域)有关的事件。

    如果它是作为回调函数或其他东西传入的,那么我 可以理解发生了什么

    您可能已经习惯了类似MVC 的模式,您传递一个控制器委托,当从view 引发UI 事件时调用该委托。这是真正不同的东西。

    也许 Unity 在后台使用延续来延迟 执行代码,但后来我觉得它会导致代码之后 if 语句要执行多次。

    没有。该函数只是立即返回,并且仅在事件发生时才返回 true。 if返回false,if后面的代码根本不会被执行。

    旁注:

    • 这种系统很难维护,尤其是对于复杂的结构化 GUI。
    • 它对性能有非常严重的影响(内存分配、UI 元素的 1 个 drawcall)

    除非您正在编写编辑器扩展或自定义检查器代码,否则我会远离它。如果你想建立一个菜单实现你自己的系统或使用外部插件(有几个很好的 NGUI,EZGUI,..)。 Unity 已经宣布了一个新的integrated UI System,它应该很快就会发布。

    【讨论】:

    • @heisenburg,每个 gui 元素 1 个 drawcall 不再正确,这些天的性能相当不错。此外,GUI 分几个阶段执行,因此它可以确定文本字段的输入、哪个按钮在顶部等。
    • 我现在明白了,我对 OnGUI 函数本身的整体作用有误。如果每帧都调用它,那么 GUI.Button 代码执行轮询功能将是微不足道的。出于某种原因,我有一次调用 OnGUI 进行初始化的概念 - 可能是因为 GUI.Button 函数似乎在表面上工作的方式。
    【解决方案2】:

    好问题。 unity3d gui 经历了几个事件阶段,或者在documentation

    事件对应于用户输入(按键、鼠标操作),或者是 UnityGUI 布局或渲染事件。

    对于每个事件 OnGUI 在脚本中被调用;因此每帧可能会多次调用 OnGUI。 Event.current 对应于 OnGUI 调用中的“当前”事件。”

    在 OnGUI 中,您可以通过 >Event.current

    找出当前正在发生的事件

    处理以下事件link

    UnityGUI 输入和处理事件的类型。

    -MouseDown
    -MouseUp,mouse button was released
    -MouseMove,Mouse was moved (editor views only)
    -MouseDrag,Mouse was dragged
    -KeyDown, A keyboard key was pressed
    -KeyUp  A keyboard key was released.
    -ScrollWheel    The scroll wheel was moved.
    -Repaint    A repaint event. One is sent every frame.
    -Layout A layout event.
    -DragUpdated    Editor only: drag & drop operation updated.
    -DragPerform    Editor only: drag & drop operation performed.
    -DragExited Editor only: drag & drop operation exited.
    -Ignore  Event should be ignored.
    -Used   Already processed event.
    -ValidateCommand    Validates a special command (e.g. copy & paste).
    -ExecuteCommand Execute a special command (eg. copy & paste).
    -ContextClick   User has right-clicked (or control-clicked on the mac).
    

    Unity GUI 最近有了很大改进,如果您想以编程方式处理事情,它非常有用。如果您想直观地处理事情,我建议您查看 heisenbug 所指的插件。

    如果你决定使用统一 gui,我建议只使用一个对象与 ongui,并让这个对象处理你所有的 gui。

    【讨论】:

      猜你喜欢
      • 2011-08-29
      • 2015-08-21
      • 2014-01-22
      • 1970-01-01
      • 2018-07-28
      • 2019-06-29
      • 2022-05-21
      • 2012-05-25
      • 1970-01-01
      相关资源
      最近更新 更多