Principle Analysis of Unity uGUI
Unity uGUI is the official UI solution launched by Unity. Provided in Unity as a Package. Official Reference Manual API Reference
The use of Unity uGUI can refer to the super detailed teaching of Unity UGUI
Preparation
Since UGUI is the core package provided by Unity, in order to be able to see and debug the source code. You need to check Built-in packages in Preferences -> External Tools -> Generate .csproj file for:. After regenerating, you can see the project in Visual Studio UnityEngine.UI
. At this point, you can use 附加到Unity
the function normally to debug the UGUI code.
Using Visual Studio's View Class Diagram feature we can see UnityEngine.UI
the class diagram. To generate a class diagram, you can refer to the VS code structure to automatically generate a class diagram .
The specific class diagram is roughly as follows (Unity version 2019.4.20):
class diagram analysis
It can be seen from the class diagram that the base class of UI components in UGUI is UIBehaviour. The UI components can be roughly divided into:
- event system
- EventSystem
- PointerInputModule
- components
- Mask related (Mask, RectMask2D)
- UI effects, related to grid modification (implement interface IMeshModifier, Shadow, OutLine)
- Selectable(Toggle、Scrollbar、Dropdown、Button、InputField、Slider)
- Graphic image related (RawImage, Image, Text)
- layout
- ILayoutController, ILayoutElement, etc.
Principle of UGUI
In UGUI, the composition of UI is roughly interfaces and events. and
will be automatically generated when creating the UI , these two correspond to the interface and events. Here also usually appears together with .Canvas
EventSystem
EventSystem
Input Module
EventSystem
Inherited from UIBehaviour
, we can see that it is added to m_EventSystems
this static variable when it is OnEnable, and it is removed from it when it is OnDisable m_EventSystems
. The purpose of this step is to determine whether current is itself in Update. That is to say, if there are multiple EventSystem
components, only one will trigger the content in Update.
At the end of Update, after a series of judgments, the Process method of InputModule will be called.
public class EventSystem : UIBehaviour
{
//...
protected override void OnEnable()
{
base.OnEnable();
m_EventSystems.Add(this);
}
protected override void OnDisable()
{
if (m_CurrentInputModule != null)
{
m_CurrentInputModule.DeactivateModule();
m_CurrentInputModule = null;
}
m_EventSystems.Remove(this);
base.OnDisable();
}
protected virtual void Update()
{
if (current != this)
return;
TickModules(); // <<-- 在这里触发 InputModule 的 UpdateModule 方法
//...
if (!changedModule && m_CurrentInputModule != null)
m_CurrentInputModule.Process(); // <<-- 在这里进行输入的处理
}
//...
}
InputModule has PointerInputModule, StandaloneInputModule, TouchInputModule, these classes are inherited from BaseInputModule.
Here is StandaloneInputModule
an example, where the Process function is the method called in Update in EventSystem. It will also be called ProcessMouseEvent
to handle mouse events. Before handling the event, we also need to know which component was clicked. So GetMousePointerEventData will also call EventSystem.RaycastAll
to perform ray detection on BaseRaycaster
components inherited from .
public class StandaloneInputModule : PointerInputModule
{
//...
public override void Process()
{
if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())
return;
// ...
// touch needs to take precedence because of the mouse emulation layer
if (!ProcessTouchEvents() && input.mousePresent)
ProcessMouseEvent(); // 处理鼠标事件
// ...
}
/// <summary>
/// Process all mouse events.
/// </summary>
protected void ProcessMouseEvent(int id)
{
var mouseData = GetMousePointerEventData(id); // << 在这里面会调用 EventSystem.RaycastAll 来执行射线检测
//...
}
}
Summary: EventSystem mainly detects all objects (BaseRaycaster) that need to be detected through the input module (InputModule). Usually what we see is GraphicRaycaster (and Canvas mounted on the unified game object) for ray detection. Then call each Graphic (that is, RawImage, Image, Text) that implements the ICanvasRaycastFilter interface through GraphicRaycaster.