1. 程式人生 > >Unity 自定義編輯器視窗的使用

Unity 自定義編輯器視窗的使用

Unity 自定義編輯器視窗功能強大,可以實現所有希望實現的功能。我在近期的專案中仿照魔獸爭霸3開發了一套簡單的遊戲單位功能元件,其中包括單位資料、移動方式、動畫播放、武器系統等等。如果用傳統的Inspector來修改各項屬性十分不方便,所以實現一個簡單直觀的自定義編輯器視窗來進行屬性管理成了一個很好的選擇。

建立自定義編輯器視窗並將每一項屬性顯示出來是十分簡單的,我們只需要通過Selection.activeGameObject 來獲取當前選中的物體,並在從該物體上獲取相關的指令碼就可以進行屬性的讀取。但是,如何將修改後的屬性傳遞迴指定物體並儲存起來呢?

我的第一想法是通過直接訪問物體上的指令碼這種方法來賦值,下面將舉一個簡單的例子。

假設我的單位系統的移動元件命名為 MovementController 其中speed屬性為移動速度,我在自定義視窗的類中寫如下程式碼:

MovementController mc = Selection.activeGameObject.GetComponent<MovementController>();
if (mc != null) 
{
    mc.speed = EditorGUILayout.FloatField(new GUIContent("Speed"), mc.speed);
}

這些程式碼完成了獲取元件和賦值的功能,那麼它的問題在哪裡呢?

使用這些程式碼之後,在自定義視窗中進行Speed屬性的修改的確是可以影響到物體上的MovementController 元件的。而且,在修改後立刻進入編輯器的播放模式是可以看出修改效果的。但是這次修改作用的時間也僅僅是當前場景開啟的這段時間,一旦你切換場景或是關閉了Unity Editor,所有所做的修改全部會丟失。

究其原因,我們這次修改的是當前場景開啟後在記憶體中儲存的例項屬性,並不是儲存在硬碟上的場景資料。所以在我們切換場景或是關閉Editor後,隨著記憶體的清理,所有修改過的資料也全部一起丟失了。

那麼,怎樣才能算是成功修改到硬碟上的資料,或是通知Editor需要更新硬碟上的資料了呢?

可能細心的朋友會注意到,如果通過Inspector檢視進行場景內某一物體的屬性修改,修改完成後會發現Editor的標題欄會多出一個”*” 來提示使用者當前場景有未儲存的資料。如果這時使用者儲存了當前場景,那麼這個“*”會消失,說明變動已經儲存到硬碟。以此為背景,我們剛剛使用的方法在修改後可以看到Inspector中的對應屬性變化,但是在Editor的標題欄上並不會出現”*”,這也從側面說明Editor並沒有認為這是一次修改,而修改的也僅僅是記憶體中的例項。

這裡要引入一個名為“序列化”的概念。序列化 (Serialization)是指將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。可能只看定義會有些難以理解,簡單來說就是將記憶體中的資料轉化為能夠儲存到硬碟上的形式。用這句話來解釋也是因為它可以和前面所說的內容對應。前面出現的問題是我修改的僅僅是記憶體中的資料,而我需要把這個資料轉化並存儲到硬碟上,所以序列化就是最好的解決方法。

還用剛才的那個例子,使用序列化方法的程式碼如下:

SerializedObject mc = new SerializedObject(Selection.activeGameObject.GetComponent<MovementController>());

SerializedProperty PropSpeed = mc.FindProperty("speed");

PropSpeed.floatValue = EditorGUILayout.FloatField(new GUIContent("Speed"), PropSpeed.floatValue);

mc.ApplyModifiedProperties();

這段程式碼實現的功能依舊是修改speed屬性,但是與前一個方法不同的地方在於,它並不是直接對記憶體中的例項進行修改,而是向將該例項進行序列化處理,將它處理為一個SerializedObject,這也就是將其轉化為可以儲存到硬碟上的狀態。再從SerializedObject上獲取SerializedProperty並對SerializedProperty進行修改,就可以保證我們所修改的值是可以儲存到硬碟上的那一部分。最後一句ApplyModifiedProperties 這個函式的功能就像它的名字一樣——應用修改後的屬性。它做的除了將修改後的值同步到例項,也通知Editor 這個例項進行過修改,需要儲存才能保證修改後的屬性不會丟失。

使用後面這種方法後,在自定義編輯器視窗對Speed屬性進行修改時,會發現Editor的標題欄出現了”*”符號,說明我們的修改生效了,並且可以通過儲存行為將修改後的資料儲存到硬碟中。

相關推薦

Unity 定義編輯視窗的使用

Unity 自定義編輯器視窗功能強大,可以實現所有希望實現的功能。我在近期的專案中仿照魔獸爭霸3開發了一套簡單的遊戲單位功能元件,其中包括單位資料、移動方式、動畫播放、武器系統等等。如果用傳統的Inspector來修改各項屬性十分不方便,所以實現一個簡單直觀的自

拓展編輯功能--Unity定義編輯視窗

最近學習了Unity自定義編輯器視窗,下面簡單總結,方便用到時回顧。 新建一個指令碼: using UnityEngine; using System.Collections; using Unit

Unity 定義編輯窗口 畫線

狀態 nbsp ongui shmat 定義 技術 load oid clas 最近在學習狀態機, 想自己實現一個可視化編輯器, 需要將多個狀態之間用線條連接起來, 效果如下: 代碼如下: Material m;Vector2 start;Vector2 end

[Unity編輯]定義編輯介面

編輯器GUI類 1.GUI、GUILayout 2.EditorGUI、EditorGUILayout 編輯器類(指令碼要放在Assets/Editor資料夾中,要使用UnityEditor的名稱空間): 1.EditorWindow(重點是OnGUI()的編寫) u

@InitBinder裝配定義編輯

format init imp ini con edit r.java 自定義 class @InitBinder裝配自定義編輯器   第一步:BaseController.java,標註@InitBinder     public class BaseController

Unity3D 定義編輯介面(Inspector)

今天看一個指令碼,本想看看在 Inspector 介面的變數在腳本里的用途,然後查詢變數名的時候怎麼也找不到,自己也是驚訝。通過網上搜索才瞭解到原來 Inspector介面 是可以自己定義的。 當然自己定義,當然也需要寫一個指令碼來改的。可能是為了讓介面整潔的目的。 首先

eclipse rcp 解決定義編輯editor重複開啟的問題

參考部落格:https://blog.csdn.net/linuxchyu/article/details/16984737 在eclipse rcp程式設計中,我們經常會自定義編輯器用於開啟自定義的檔案,會遇到每次雙擊檔案都開啟編輯器的問題,如何解決這個問題呢,我所知道的有兩種方法: 方法

Unity3d 2017.3 定義編輯 列舉 隱藏與顯示

今天第一次自定義編輯器,記錄一下心得。 1.在Editor資料夾下建立一個指令碼,將此指令碼與想自定義編輯器的指令碼繫結 2.在OnEnable()方法中獲取原指令碼中,需要操作的物件。 3.OnInspectorGUI()中,EditorGUILayout.Propert

canvas定義編輯

// 獲取視訊資訊 var oVideo = document.querySelector('#video'); // 獲取播放暫停按鈕 var oStopToP = document.querySelector('.stopToP'); var oPlayToS =

Wordpress之二__定義編輯按鈕

做一個很簡單的功能 框架上大概就是新增一個快捷鍵 編輯文章的時候,可以在文章頭加上鍊接,例如:  =================== 明日花->2015  bababalabala ,bala, =================== 首先想到的當然是- 1.wo

【Unity3D5.6版本使用(1)】定義編輯獲取場景所有物件Tag生成Json

在unity3D5.x版本中,一部分以前的程式碼無法正常執行,比如:載入場景時,使用Application.loadedLevel會提示“已過時”,需要使用EditorSceneManager.OpenScene(FileName[scount]);所以寫一篇記

「Unity3D」(9)定義編輯選單擴充套件總結

新增選單 [MenuItem("Tools/MyOption")] private static void MyOption() { // 自定義選單Tools } [MenuItem("Tools/Sub/MyOption")] priva

vivado設定定義編輯與notepad++設定高亮方法

vivado2015.03下tools->option->general->text editor -> 選擇custom editor, 右邊的 ... 瀏覽按鈕,如下圖

Unity擴充套件 檢視面板(Inspector面板),編輯視窗(自己定義的類似Inspector面板的視窗),scene場景 常用的類說明

EditorApplication 主應用程式類。 能控制編輯器的啟動,暫停,新建場景等,比較高層次的控制。 Editor 派生的自定義編輯器基類。使用這個

unity 編輯----編輯視窗控制元件建立和UI佈局

unity編輯器視窗控制元件通過EditorGUILayout、EditorGUI、GUILayout和GUI來建立控制元件和實現佈局。 EditorGUILayout、EditorGUI這兩個是unity編輯器使用。 而GUILayout和GUI執行時遊戲中和編輯器中都可以使用,但是這兩個

Unity定義Inspector視窗——根據列舉型別顯示指定內容

本文參考了這篇文章 我們直接進入主題,假設我們現在有下面這樣一個類: public class Test { public enum Type { Enemy, Player }

在struts2中配置定義攔截放行多個方法

return med ttr limit ring req tac cat invoke 源碼: 自定義的攔截器類: //自定義攔截器類:LoginInterceptor ; package com.java.action.interceptor; import j

SpringMVC 定義轉換

del 轉化 string sna 問題 print request package type 實踐SpringMVC轉化器是遇到的問題:表單提交沒有經過自定義轉換器(解決:表單用post方式提交) 自定義轉化器代碼 package cn.liangqinghai.

JAVAEE——struts2_04:定義攔截、struts2標簽、登陸功能和校驗登陸攔截的實現

strac htm logs transacti 標識 area 返回 ftw jsp 一、自定義攔截器   1.架構      2.攔截器創建 //攔截器:第一種創建方式 //攔截器生命周期:隨項目的啟動而創建,隨項目關閉而銷毀 public class MyInt

struts2學習(6)定義攔截-登錄驗證攔截

back tps class res urn fff .com space war 需求:對登錄進行驗證,用戶名cy 密碼123456才能登錄進去;   登錄進去後,將用戶存在session中; 其他鏈接要來訪問(除了登錄鏈接),首先驗證