在本文筆者教大家使用代碼動態(tài)調(diào)用 Inspector component 右上角三個點菜單中的某一項族铆。
前言
突遇群友問下圖中三個點的菜單怎么調(diào)用纲仍,我覺得值得記錄一下腐芍。
“這三個點 怎么用代碼調(diào)用忧吟?”
實現(xiàn)
- 眾所周知养筒,這三個點菜單學名是 ContextMenu 曾撤,那么,必然逃離不了 Unity 中執(zhí)行菜單的這個 API:
EditorApplication.ExecuteMenuItem(string menuItemPath);
-
于是問題就變成了如何構(gòu)建一個正確的 menuItemPath晕粪,而 ContextMenu 的路徑是以 "CONTEXT/指定的組件/" 開頭 挤悉,比如 RectTransform 組件右側(cè)的下拉菜單中
Properties...
的完整菜單路徑應該是:,由于 Properties 面板在每一個組件上都出現(xiàn)巫湘,所以此處菜單路徑實際上是:CONTEXT/RectTransform/Properties...
CONTEXT/Component/Properties...
- 最后我們執(zhí)行一下這個路徑不就行了嘛!
EditorApplication.ExecuteMenuItem("CONTEXT/Component/Properties...");
但是聰明如你装悲,會發(fā)現(xiàn)是不是缺少一個聲明昏鹃,聲明你想要展示哪一個 RectTransform 實例的 Properties 呢?
-
所以诀诊,咱們在使用
ExecuteMenuItem
函數(shù)執(zhí)行這個菜單項的同時洞渤,按理說應該指定一個 RectTransform 的實例過去,那怎么實現(xiàn)為 ExecultMenu 傳參數(shù)呢属瓣?
答: 筆者發(fā)現(xiàn)ExecuteMenuItem
函數(shù)并不支持傳參數(shù)载迄,但是函數(shù)ExecuteMenuItemWithTemporaryContext
支持呀 ,雖然它不公開抡蛙,但反射一下不就可以啦护昧,實現(xiàn)如下:
//反射拿到 EditorApplication 下的 content menu 執(zhí)行方法
static bool ExecuteMenuItemOnGameObjects(string menu,Object[] objects)
{
var flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static;
var method = typeof(EditorApplication).GetMethod("ExecuteMenuItemWithTemporaryContext", flags);
var value = method.Invoke(null, new object[] { menu, objects });
return (bool)value;
}
- 于是我們就能夠通過代碼動態(tài)調(diào)用這個 contextmenu 的菜單項,同時傳數(shù)據(jù)進去啦粗截!
下面我們來試試能不能使用代碼動態(tài)的喚起Context Menu 中的 Properties 面板惋耙。
測試代碼:
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(DynamicCallPropertiesMenu))]
class DynamicCallPropertiesMenuEditor : Editor
{
public override void OnInspectorGUI()
{
if (GUILayout.Button("點擊喚起 Properties 面板"))
{
(target as DynamicCallPropertiesMenu).CallMenuDynamic();
}
}
}
public class DynamicCallPropertiesMenu : MonoBehaviour
{
public void CallMenuDynamic()
{
string menu = "CONTEXT/Component/Properties...";
var rt = transform as RectTransform;
ExecuteMenuItemOnGameObjects(menu,new Object[] { rt});
}
static bool ExecuteMenuItemOnGameObjects(string menu, Object[] objects)
{
var flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static;
var method = typeof(EditorApplication).GetMethod("ExecuteMenuItemWithTemporaryContext", flags);
var value = method.Invoke(null, new object[] { menu, objects });
return (bool)value;
}
}
#endif
效果演示
exemenu
- 先手動點擊 Properties,確認菜單點擊后的效果
- 然后使用代碼動態(tài)調(diào)用熊昌,確認得到了一致的結(jié)果绽榛。
- 至此,功能實現(xiàn)浴捆,效果一致蒜田,驗證完畢!
結(jié)語
- 凡是菜單的動態(tài)執(zhí)行都應該首先考慮
EditorApplication.ExecultMenu
這個API - 如果菜單路徑拼接錯誤选泻,就要考慮是不是基類組件的呢,比如本例中 RectTransform 下的 Properties 菜單項路徑就需要拼接 Component 美莫,否則提示路徑拼接錯誤页眯。
- 動態(tài)執(zhí)行的菜單反饋的結(jié)果各式各樣,如果你是復制數(shù)據(jù)的(如 RectTranform 的 Copy Rotation)厢呵,那么數(shù)據(jù)在哪兒取呢窝撵?
答:盲猜系統(tǒng)剪切板唄。
PS:根據(jù)第二條注意事項襟铭,Copy Rotation 的路徑拼接中指定的組件應該是 Transform
擴展閱讀:
[Unity3D] 子類組件怎么無損替換父組件 - Contex Menu 的妙用
2023年9月16日 更新:
- 可以先使用 Selection 選中指定的組件然后再執(zhí)行對應的 CONTEXT 菜單碌奉。
可以測試下 Selection.activeObject 、 Selection.SetActiveObjectWithContext(Object寒砖,Object); - 如何動態(tài)調(diào)用 Inspector 面板右上角三個點里面的 Properties... 菜單呢赐劣?
答: Inspector 右上角三個點的菜單請使用EditorApplication.ExecuteMenuItem($"Assets/Properties...");
訪問即可!
Selection.SetActiveObjectWithContext(yourObject, yourObject); //也可以使用本文的方法指定需要傳入的對象
EditorApplication.ExecuteMenuItem($"Assets/Properties...");