1. 程式人生 > >Unity 拓展Scene檢視自定義操作

Unity 拓展Scene檢視自定義操作

描述

在我們開發專案的時候,可能會遇到一些特殊的情況,比如場景裡面有幾個十幾個甚至幾十個看起來相同的物體,但是其實有幾個物體可能在部分元件數值是特殊的,需要經常修改測試,想直觀的在Scene標識這個特殊物體。又或者一個正方體(不管如何旋轉90度,scene檢視看起來都一樣),我們想直觀的在Scene檢視瞭解這個正方體的朝向,等等。這些需求我們都可以通過自定義Scene檢視來實現(其實是實現MonoBehaviour下OnDrawGizmosOnDrawGizmosSelected方法,實現自定義繪製,並只能在Scene檢視下檢視)


再比如,我們做一個類似《我的世界》這樣的遊戲,所有物體的大小位置都是按一個定好的基數。比如定好所有的物體都是1*1*1的,那麼他們移動的時候也需要1單位1單位的移動,如圖拼積木一般。加入我們有十個這樣的物體需要把它拼成一個門的形狀,那麼一種方法自然是一個個物體去修改他的Inspector下的座標。這樣我們不僅要計算每個點的座標,還要一個個修改,要是物體更多場景更大就很麻煩。當然我們也可以在Scene檢視下拖動物體,但是我們很難精確到每次拖動都是1單位。這時候,我們就可以自定義Scene檢視來處理。(實現Editor下的OnSceneGUI

方法)


實現過程

首先,我們講一講MonoBehaviour下OnDrawGizmos或OnDrawGizmosSelected方法。既然是MonoBehaviour類,我們就需要建立一個指令碼,繼承於MonoBehaviour,然後實現這個兩個方法,最後將指令碼掛在我們需要的物體上即可。

OnDrawGizmos:每幀呼叫,裡面實現的繪製在Scene檢視可見

OnDrawGizmosSelected:物體被選中的時候每幀呼叫

namespace Tool {
    public class CustomCube : MonoBehaviour {

        void OnDrawGizmos() {
            //每幀呼叫

            //繪製一個cube邊框
            Gizmos.color = Color.black;
            Gizmos.DrawWireCube(GetComponent<Renderer>().bounds.center, GetComponent<Renderer>().bounds.size);

            //繪製一條直線,指向物體正上方
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(transform.position, transform.position + transform.up * 2);
        }

        void OnDrawGizmosSelected() {
            //被選中的時候每幀呼叫
            Gizmos.color = Color.red;
            Gizmos.DrawWireCube(GetComponent<Renderer>().bounds.center, GetComponent<Renderer>().bounds.size);
        }
    }
}

如果我們想要在Scene檢視上顯示一些GUI控制元件,即上述例子的第二種情況,我們就需要用到OnSceneGUI方法。需要注意的是這個方法是在Editor基類下的,所以我們生成的指令碼要繼承Editor並放在Editor目錄下。

OnSceneGUI:只有當物體選中的時候每幀會呼叫。

下面這個方法實現的是,帶有CustomCube元件的物體,被選中的時候,Scene場景下會顯示該物體的名稱和座標,同時會顯示四個按鈕提供按單位長度位移。並且當你在Scene檢視使用箭頭拖動該物體時,也是按單位長度位移。

namespace EditorTool {

    //宣告要處理的元件型別
    [CustomEditor(typeof(CustomCube))]
    public class CustomCubeEditor : Editor {

        CustomCube m_cube;
        Transform m_trans;

        void OnEnable() {
            //包含該元件的物體被選中的時候呼叫
            m_cube = (CustomCube)target;
            m_trans = m_cube.transform;
        }

        void OnSceneGUI() {
            //座標位置取整
            Vector3 posTemp = m_trans.localPosition;
            float x = Mathf.RoundToInt(posTemp.x);
            float y = Mathf.RoundToInt(posTemp.y);
            float z = Mathf.RoundToInt(posTemp.z);
            m_trans.localPosition = new Vector3(x, y, z);

            //顯示座標
            Handles.Label(m_trans.position + Vector3.up * 3, m_cube.name + " : " + m_trans.position.ToString());

            Handles.BeginGUI();

            //規定GUI顯示區域
            GUILayout.BeginArea(new Rect(100, 100, 100, 100));

            //GUI繪製按鈕
            if(GUILayout.Button("上移")) {
                m_trans.position += Vector3.up;
            }
            if(GUILayout.Button("下移")) {
                m_trans.position += Vector3.down;
            }
            if(GUILayout.Button("左移")) {
                m_trans.position += Vector3.left;
            }
            if(GUILayout.Button("右移")) {
                m_trans.position += Vector3.right;
            }
            GUILayout.EndArea();

            Handles.EndGUI();
        }
    }
}

上述的方法需要在物品選中的情況下,如果我們要處理未選中物品,在Scene檢視額外顯示一些屬性的話(比如顯示物品名稱)。可以使用DrawGizmo標籤來實現,如下,指令碼要放在Editor資料夾下。

namespace EditorTool {

	public class SceneEditor : MonoBehaviour {

        [DrawGizmo(GizmoType.NonSelected)]
        static void DrawGameObjectName(Transform transform, GizmoType gizmoType) {
            Handles.Label(transform.position, transform.gameObject.name);
        }
    }
}

[DrawGizmo(GizmoType.NonSelected)],即沒有選中物體的時候會呼叫下面的方法。方法名可以自定義,第一個引數可以是自定義的一個class(Transform,GameObject或者你自己寫的元件,如果物品不包含該型別,則不會呼叫該方法),第二個引數必須為GizmoType。

效果如下:


GizmoType支援的型別如下:(NotSelected 和 SelectedOrChild已棄用)

Pickablegizmo在編輯器中可被選中
NotInSelectionHierarchy物品沒有被選中並且其父節點也沒被選中
Selected物體選中的時候
Active物體可見的時候
InSelectionHierarchy物品被選中或選中其中一個子物體
NonSelected物體沒有被選中的時候

備註:上述三種方法都可以在Scene檢視上做一些擴充套件,其實很多情況也是互通的,比如你可以在OnDrawGizmos方法去新增Handles.Label顯示物體名稱,或者做拖動的單位長度限制等等。

相關推薦

Unity 拓展Scene檢視定義操作

描述在我們開發專案的時候,可能會遇到一些特殊的情況,比如場景裡面有幾個十幾個甚至幾十個看起來相同的物體,但是其實有幾個物體可能在部分元件數值是特殊的,需要經常修改測試,想直觀的在Scene標識這個特殊物體。又或者一個正方體(不管如何旋轉90度,scene檢視看起來都一樣),我

Unity Scene場景定義座標軸

多看看別人的程式碼是沒有壞處的,即使學不了人家的大框架,偶爾拾起一些小東西也是可以的。 最近扒了一下DoTween(宣告一下原始碼是自己反編譯的,只為學習),看見了如何在Scene場景中新增標註和座標

拓展編輯器(十三)_拓展Scene檢視(輔助元素)

拓展Scene檢視:   Scene檢視承擔著遊戲“第三人稱”觀察的工作。Unity提供了強大的Gizmos工具API,我們可以在Scene檢視中繪製立方體,網格,貼圖,射線和UI等,開發者可以自由地拓展顯示元件。 輔助元素:   場景在編輯過程中,通常需要一些輔助元素,這樣使用者可以更高效的完成編輯工

10.3 Customizing Operations(定義操作)

10.3.2 Lambda Expression(匿名函式) #include <iostream> #include <algorithm> #include <vector> #include <string> #include <nu

jquery-easyui定義操作列實現方式

  jquery-easyui提供的datagrid元件中,沒有明確給出自定義操作列的實現方式,而我們實際的場景中,操作列是不可少的,因此有必要自定義這一列。   jquery-easyui提供了data-options設定列屬性,可以通過formatter屬性,設定列的展示內容,因此可

C# winform 安裝程式打包(定義操作

(一),安裝程式 以前用vs製作過安裝程式,現在把步驟寫出來,有幫助的大家一定要頂哦 第一步:建立工程 1.開啟vs,新建專案->其他專案型別->安裝和部署(這個子項下面有安裝專案和Web安裝專案等,安裝專案就是普通的桌面程式安裝,Web安裝就是安裝網

Unity】多平臺定義巨集和Scripting Define Symbols的使用

平臺定義 UNITY_EDITOR 編輯器呼叫。 UNITY_STANDALONE_OSX 專門為Mac OS(包括Universal,PPC和Intelarchitectures)平臺的定義。 UNITY_DASHBOARD_WIDGET Mac OS Dashboard

easyui-datagrid定義操作

在實際的專案中,有時會有操作列這個需求,主要是修改和刪除的功能。 類似於: 實現該效果的方法並不複雜。需要使用到datagrid資料表格中的formatter方法。自定義列。 下面寫個小例子。 html <table id="dg" class="easyui-d

springboot2.0 深入解析原理-Bean 初始化回撥前後進行定義操作之BeanPostProcessor

1 demo 版本說明 springboot版本:2.0.5.RELEASE jdk版本:1.8.0_144 在閱讀該部落格前建議大家一定要把demo寫下來 在自己的環境下,根據操作靜下心來一步步看。閱讀原始碼本身是一個比較費神的操作,建議大家一定要多看 看明白後自

Android拿來系列之萬能載入檢視 定義彈窗

上一次關於彈窗的拿來篇是那種偏心選擇的,可以滑動有時差那種.這次不同//各種Dialog compile 'com.flyco.dialog:FlycoDialog_Lib:[email protected]'然後是自定義DiaLog 其實就那麼幾句 找到位

Unity 進行曲線軌跡定義,以及根據定義曲線軌跡運動

1. 當你需要相機鏡頭根據特定軌跡運動。或者一些AI的特定軌跡運動的時候。就可以用到下面的指令碼了 一下方法來自官方案例 直接程式碼嘍。你需要做的就是,複製到你的專案中。拖在指令碼上,你就知道他怎麼用了。 一共兩個指令碼,一個是自定義軌跡的,另一個是使物

新增定義操作後,安裝時未能找到.installstate檔案的問題

在新增自定義操作時,一定要在Install中也新增上輸出。可能是因為在Install階段進行.installstate檔案的建立。所以如果不在Install中新增輸出的話,就會提示找不到相應的.installstate檔

SharePoint 2013 Designer 定義操作選單

  眾所周知,我們在SharePoint的二次開發中,經常會新增ECB選單或者Ribbon選單,通常我們會採取Feature的方式去新增一個Xml,或者採取JavaScript的方式,當然,除此之外,還可以利用Designer新增這些自定義操作,而且更加方便;但是,這種操作

C# PropertyGrid控制元件的四個定義操作

1>PropertyGid 控制元件輸入時顯示隱藏密碼為(*) 單獨寫一個PasswordStringConverter 類; using System.ComponentModel; using System.Globalization;

學習筆記TF049:TensorFlow 模型儲存載入、佇列執行緒、載入資料、定義操作

生成檢查點檔案(chekpoint file),副檔名.ckpt,tf.train.Saver物件呼叫Saver.save()生成。包含權重和其他程式定義變數,不包含圖結構。另一程式使用,需要重新建立圖形結構,告訴TensorFlow如何處理權重。 生成圖協議

[Swift4.2實際操作]九、完整例項-(7)登入頁面:建立定義檢視及相關元件

本文將開始建立登入頁面,首先建立該頁面所需的一些自定義元件:做為登入按鈕的自定義檢視物件。在【RegLogin】組的名稱上點選滑鼠右鍵,開啟右鍵選單。【New File】->【Cocoa Touch Class】建立新檔案【RegButton.swift】Name:RegButtonSubclass:S

[Xcode10 實際操作]三、檢視控制器-(7)UINavigationController定義導航按鈕

本文將演示設定導航按鈕的樣式,以及設定導航標題區域的樣式。 1 import UIKit 2 3 class FirstSubViewController: UIViewController { 4 5 override func viewDidLoad() { 6

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

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

DOM內容操作定義、樣式改變

abcdefg result 定義 tel class abcde inner 參數 fun 自定義 function 方法名或函數名(參數1,參數2,、、、) { 方法體; return返回值;(可不寫) } function a

HTML5的定義屬性data-*詳細介紹和JS操作實例

select 文章 red data scrip style box 實例 width 這篇文章主要介紹JS操作HTML自定義屬性的方法, 以實例形式分析了html中自定義屬性的設置與對應的javascript操作技巧 具體如下: HTML代碼如下(其中的d