在開發時經常需要進行大量資源管理, 在編寫新程序及進行 Prefab 建構時這問題令開發者非常苦惱.
e.g. 建立一個多層架構的 Prefab, 把所有在 ScrollView 底下的 MyListElement 都放到 Array/List 的動作..
這些大量 Drag & Drop 的動作多做數次會令人發瘋.
這時候 OnValidate 就可以幫助開發者減少這些無謂的 setup 動作.
以 UGUI 的 Button 舉例.
ButtonLabel.cs
using UnityEngine;
using UnityEngine.UI;
public class ButtonLabel : MonoBehaviour
{
public Text m_Label;
public Button m_Button;
private void OnValidate()
{
if (m_Label == null)
m_Label = GetComponentInChildren<Text>(true);
if (m_Button == null)
m_Button = GetComponentInChildren<Button>(true);
}
}
當這個 ButtonLabel 加入到 Button 上時候, 我們只要把其中一個 field 更動一下 { 放入 Text } 那麼 Button + Label 會一起自動找取底下第一順位的 Text 跟 Button.
但這個對於懶散慣了的程序員是不足夠的.
我們希望這個動作在 ButtonLabel 一開始放到 GameObject 身上時就自動執行一次.
在 Component 放到 GameObject 身上時會自動跑的 method 是 Reset();
所以我們修改如下:
public class ButtonLabel : MonoBehaviour
{
public Text m_Label;
public Button m_Button;
private void Reset()
{
AutoConfig();
}
private void OnValidate()
{
AutoConfig();
}
private void AutoConfig()
{
if (m_Label == null)
m_Label = GetComponentInChildren<Text>(true);
if (m_Button == null)
m_Button = GetComponentInChildren<Button>(true);
}
}
首先 Reset() 在開發者重設 Component 時會被呼叫,
而 OnValidate() 在 “任何” 更改時也會被呼叫一次, 這包括編譯階段. 這間接導致 AutoConfig 在每次編譯時時也被呼叫.
單單一兩個 OnValidate 沒問太大負擔但想像一下你的專案有數千個 OnValidate 的元件每一個在 編譯時也被執行……..
這個測試會令 CPU 浪費很多非必要的檢測資源.
這個時候就需要用到另一個檢測手段.
UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode
用來得知是否正在編譯, 正在編譯就別進行了, 因為我們假設在 Reset 階段已經檢測過了及設定好了.
就別浪費每次對行 Playmode 測試的編譯資源.
using UnityEngine;
using UnityEngine.UI;
public class ButtonLabel : MonoBehaviour
{
public Text m_Label;
public Button m_Button;
private void Reset()
{
AutoConfig();
}
private void OnValidate()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
return;
#endif
if (!Application.isPlaying)
AutoConfig();
}
private void AutoConfig()
{
if (m_Label == null)
m_Label = GetComponentInChildren<Text>(true);
if (m_Button == null)
m_Button = GetComponentInChildren<Button>(true);
}
}
因為 EditorApplication 只能在 UnityEditor 下才能取得. 所以程序又變得擁擠了.
當然有很多手法令這些檢測變得統一及簡化, 但各人有不同方式, 這不在本篇討論範圍.
好东西