1. 程式人生 > >【Untiy3d-編輯器相關4】ScriptableObject,EditorWindow,ScriptableWizard

【Untiy3d-編輯器相關4】ScriptableObject,EditorWindow,ScriptableWizard

繼承關係:

(基類)Object -> ScriptableObject -> EditorWindow -> ScriptableWizard


ScriptableObject:

將資料儲存在資原始檔中,執行時修改退出也會儲存。一般編輯器使用較多。類似通過Serializable + Class + Prefab實現儲存資料時候,就可以考慮下能不能用ScriptableObject做成一個真正的資原始檔,做法是將繼承自ScriptableObject指令碼建立為yourselfFileName.asset檔案。

  • 利用yourselfFileName.asset創建出來的資料是被引用,一旦被修改就會被儲存到yourselfFileName.asset
  • 類似其他資源,它可以被任何場景引用,即場景間共享
  • 在專案之間共享
  • 沒有其他多餘的東西,例如多餘的Component
  • 只有三個回撥函式OnEnable,OnDisable,OnDestroy

優點:
可以儲存資料型別多樣(int、string、Vector3、GameObject、Transform、Texture等)如關聯預設,關聯圖片等資源資料,而XML、TXT等只能儲存(int、string、Vector3 等基本資料型別)。

缺點:
如果配置資料中儲存了(GameObject、Texture)等資源資料,當關聯的資源被刪除時,配置資料將丟失,需要重新將新的資源再次關聯到配置資料上。

1.利用繼承自ScriptableObject的類建立xxx.assets檔案

方法1:

  1. //CreateAssetMenu 方法用於在上方Asset或Project面板下右鍵的Create選單裡邊下生成建立 CreateMySelfAsset 按鈕
  2.  
  3. [CreateAssetMenu(fileName = "MyScriptableObject", menuName = "CreateMySelfAsset", order = 1)]
  4. public class MyScriptableObject : ScriptableObject
  5. {
  6.    public int value_int;
  7.    public string value_string;
  8.    public AudioClip m_audioClip;
  9.    public Texture2D m_texture;
  10.    public List<MyDataItem> list = new List<MyDataItem>();
  11. }

//自定義資料型別在繼承自ScriptableObject中使用建立.Asset檔案時候,

//該類需要加 Serializable 關鍵字,不然生成的Asset檔案的Inspector面板看不到資料

  1. [System.Serializable]
  2. public class MyDataItem
  3. {
  4. public int keyInt;
  5. public string valueStr;
  6.  
  7. public MyDataItem(int _key,string _value)
  8. {
  9. this.keyInt = _key;
  10. this.valueStr = _value;
  11. }
  12. }

方法2:

  1. MyScriptableObject tempMyDataItem = ScriptableObject.CreateInstance(typeof(MyScriptableObject)) as MyScriptableObject;
  2. AssetDatabase.CreateAsset(tempMyDataItem, "Assets/MyScriptableObject.asset");
  3. AssetDatabase.SaveAssets();

效果圖:

載入.asset檔案:

  1. MyScriptableObject tempMyscriptable = AssetDatabase.LoadAssetAtPath<MyScriptableObject>("Assets/MyScriptableObject.asset");
  2. tempMyscriptable.list[0].valueStr = "執行修改了。。。";


EditorWindow 可以結合ScriptableObject使用,在視窗中編輯ScriptableObject建立的.asset資料

展示一個簡單的自定義window

  1. public class CustomWindow : EditorWindow {
  2. //點選Show MyWindhow顯示自定義視窗
  3. [MenuItem("Window/Show CustomWindow")]
  4. static void ShowMyWindow()
  5. {
  6.     CustomWindow myWindow = EditorWindow.GetWindow<CustomWindow>("MySelfWindow");
  7.     myWindow.Show();
  8. }

  •         EditorWindow.focusedWindow    當前聚焦視窗
  •         EditorWindow.mouseOverWindow  當前滑鼠移動到哪個視窗
  •         myWindow.autoRepaintOnSceneChange = true  設定此值,任何視窗有任何變化,就會重繪此視窗
  •         myWindow.maximized = true   視窗是否可以最大化
  •         myWindow.wantsMouseMove = true;  是否接收滑鼠移動事件,不會自動觸發重繪此視窗        
  •         滑鼠移動事件判斷  Event.current.type == EventType.mouseMove
  •         myWindow.Close()  關閉此視窗       myWindow.Focus()  聚焦到此視窗      
  •         myWindow.Focus()   聚焦到此視窗

 

//建立巢狀視窗,引數分別為id,大小位置,建立子視窗的元件的函式,標題

  1. public Rect windowRect = new Rect(0, 0, 100, 100);//子視窗的大小和位置
  2. void OnGUI()
  3. {
  4.      BeginWindows();
  5.      windowRect = GUILayout.Window(1, windowRect, DoWindow, "子視窗");
  6.      EndWindows();
  7. }

顯示一個通知如下,移除通知 myWindow.RemoveNotification(); 不手動移除,過幾秒也會自己消失。。。

  1. public string m_notification;
  2. void OnGUI()
  3. {
  4.    m_notification = EditorGUILayout.TextField(m_notification);
  5.    if (GUILayout.Button("顯示訊息"))
  6.    {
  7.       myWindow.ShowNotification(new GUIContent(m_notification));
  8.    }
  9. }

 

向其他視窗傳遞事件(當聚焦到Hierarchy面板時,傳遞給它一個貼上的事件)

  1.  void OnGUI()
  2. {
  3.      if (EditorWindow.focusedWindow.ToString().Trim() == "(UnityEditor.SceneHierarchyWindow)")
  4.     {
  5.         EditorWindow.focusedWindow.SendEvent(EditorGUIUtility.CommandEvent("Paste"));//傳遞貼上的事件
  6.     }
  7. }


ScriptableWizard

顯示:

//第一個引數是對話方塊名稱,第二個引數是Create按鈕的名字,第三個引數是第二個按鈕,點選不會關閉視窗

ScriptableWizard.DisplayWizard<CustomScriptableWizard>("自定義一個對話視窗","按鈕1","按鈕2");

內建函式:

  • OnWizardUpdate()  對話視窗改變自動呼叫
  • OnWizardCreate()  對應上圖按鈕1點選事件(實測,是關閉按鈕?)
  • OnWizardOtherButton  對應上圖的按鈕2點選事件

https://blog.csdn.net/liqiangeastsun/article/details/50510615