国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Unity UIToolkit】UIBuilder基礎(chǔ)教程-制作簡易的對話系統(tǒng)編輯器 3步教你玩轉(zhuǎn)Unity編輯器擴展工具

這篇具有很好參考價值的文章主要介紹了【Unity UIToolkit】UIBuilder基礎(chǔ)教程-制作簡易的對話系統(tǒng)編輯器 3步教你玩轉(zhuǎn)Unity編輯器擴展工具。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.前言

隨著Unity開發(fā)的深入,基本的Unity編輯器界面并不能滿足大部分玩家高階開發(fā)的要求。為了提高開發(fā)的效率,有針對性的定制化擴展編輯器界面是提高開發(fā)效率的不錯選擇。
今天就給大家?guī)鞺nity官方提高的編輯器擴展工具UIToolkit(集成了UIBuilder和UI Debugger等插件)的使用教程。本次的案例會以游戲中最常用的對話系統(tǒng)作為編輯器管理的內(nèi)容-制作一個對話系統(tǒng)的編輯器界面。

如果覺得圖文教程不夠詳細(xì)的便宜已經(jīng)直接觀看視頻教程,更加直觀詳細(xì)哦!
合集·Unity官方編輯器擴展工具UI ToolKit】UI Builder 制作簡易對話系統(tǒng)編輯器

下圖為使用UIToolkit制作的對話系統(tǒng)編輯器界面(使用節(jié)點樹管理界面)
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

2.UIToolkit安裝

UI Toolkit 的歷史可以追溯到 Unity 2018 年發(fā)布的 UIElement,起初主要用于 Editor 編輯面板中的 UI 開發(fā),自 Unity 2019 起,它開始支持運行時 UI,并更名為 UIToolkit,它以 Package 包(com.unity.ui)的形式存在,并在 Unity 2021.2 版本后被官方內(nèi)置在Unity編輯器中。

因此Unity2021.2之前的版本要使用UIToolkit的話需要在Package Manager中引入UIToolkit包 (舊名UIBuilder)
1.在Unity編輯器頂部欄點擊 Window > Package Manager 來打開 Package Manager 窗口
2.然后左上角點擊+號,在下拉選項中選擇 Add package from git URL…,
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
3.分別通過輸入 com.unity.ui 和 com.unity.ui.builder 來獲取 UI Toolkit 包和 UI Builder 包。unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
而在Unity2021.2之后的版本則可以直接在編輯器頂部欄點擊Window>UI Toolkit>選擇對應(yīng)的工具使用
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

3.編寫運行時對話腳本

在日常游戲?qū)υ捪到y(tǒng)中,并不是每次對話都是一模一樣的 在玩家進(jìn)行不同的選擇時 輸出的對話都是不相同的,因此對話系統(tǒng)一般都是以節(jié)點樹的形式來編寫。
因此我們運行時腳本需要以下的類構(gòu)成

1.對話節(jié)點(每一句對話內(nèi)容存儲的載體)
2.對話節(jié)點樹(每次對話中都包含了許多句對話內(nèi)容 所有對話內(nèi)容都以樹的形式存儲下來)
3.對話節(jié)點樹運行器(對話發(fā)生的觸發(fā)器)

3-1.對話內(nèi)容節(jié)點

基類節(jié)點-此節(jié)點為所有節(jié)點的父類包含了所有節(jié)點的基礎(chǔ)屬性與方法

using UnityEngine;

public abstract class Node : ScriptableObject
{
    // 對話節(jié)點狀態(tài)枚舉值為運行和等待兩種狀態(tài)
    public enum State{ Running , Waiting }
    // 對話節(jié)點當(dāng)前狀態(tài)
    public State state = State.Waiting;
    // 是否已經(jīng)開始當(dāng)前對話節(jié)點判斷指標(biāo)
    public bool started = false;
    // 每個對話節(jié)點的描述
    [TextArea] public string description;
    public Node OnUpdate(){
        // 判斷該節(jié)點首次調(diào)用OnUpdate時調(diào)用一次OnStart方法
        if(!started){
            OnStart();
            started =true;
        }
        Node currentNode = LogicUpdate();
        // 判斷該節(jié)點結(jié)束時調(diào)用一次OnStop方法
        if(state != State.Running){
            OnStop();
            started =false;
        }
        return currentNode;
    } 
    public abstract Node LogicUpdate();
    protected abstract void OnStart();
    protected abstract void OnStop();
}

單向節(jié)點-此類節(jié)點只能單對單的進(jìn)行內(nèi)容關(guān)聯(lián)

public abstract class SingleNode : Node
{
	// 只有一個子類
    public Node child;
}

復(fù)合節(jié)點-此類節(jié)點可以多對多的進(jìn)行內(nèi)容關(guān)聯(lián)

using System.Collections.Generic;
public abstract class CompositeNode : Node
{
	// 有多個子節(jié)點構(gòu)成的列表
    public List<Node> children = new List<Node>();
}

上述都為抽象類節(jié)點 因此還需要編寫繼承了對應(yīng)抽象節(jié)點的實體對話類來才可以使用

普通對話節(jié)點

using UnityEngine;

// 普通對話節(jié)點 后續(xù)只會返回一種情況的對話內(nèi)容
public class NormalDialogue : SingleNode
{
    [TextArea] public string dialogueContent;
    public override Node LogicUpdate()
    {
        // 判斷進(jìn)入下一節(jié)點條件成功時 需將節(jié)點狀態(tài)改為非運行中 且 返回對應(yīng)子節(jié)點
        if(Input.GetKeyDown(KeyCode.Space)){
            state = State.Waiting;
            if(child != null){
                child.state = State.Running;
                return child;
            }
        }
        return this;
    }
    //首次進(jìn)入該節(jié)點時打印對話內(nèi)容
    protected override void OnStart()
    {
        Debug.Log(dialogueContent);
    }
	// 結(jié)束時打印OnStop
    protected override void OnStop()
    {
        Debug.Log("OnStop");
    }
}

分支對話節(jié)點

using System.Collections.Generic;
using UnityEngine;

public class BranchDialogue : CompositeNode
{
    [TextArea] public string dialogueContent;
    public int nextDialogueIndex = 0;
    public override Node LogicUpdate()
    {
    	// 判斷進(jìn)入哪個對話節(jié)點
        if(Input.GetKeyDown(KeyCode.A)){
            nextDialogueIndex = 0;
        }
        if(Input.GetKeyDown(KeyCode.B)){
            nextDialogueIndex = 1;
        }
        // 判斷進(jìn)入下一節(jié)點條件成功時 需將節(jié)點狀態(tài)改為非運行中 且 返回對應(yīng)子節(jié)點
        if(Input.GetKeyDown(KeyCode.Space)){
            state = State.Waiting;
            if(children.Count > nextDialogueIndex){
                children[nextDialogueIndex].state = State.Running;
                return children[nextDialogueIndex];
            }
        }
        return this;
    }
    //首次進(jìn)入該節(jié)點時打印對話內(nèi)容
    protected override void OnStart()
    {
        Debug.Log(dialogueContent);
    }
	// 結(jié)束時打印OnStop
    protected override void OnStop()
    {
        Debug.Log("OnStop");
    }
}

3-2.對話樹

基類節(jié)點樹

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

/* 繼承腳本數(shù)據(jù)化結(jié)構(gòu)對象 ScriptableObject */
public class NodeTree : ScriptableObject
{
    // 當(dāng)前正在播放的對話
    public RootNode rootNode;
    // 當(dāng)前正在播放的對話
    public Node runningNode;
    // 對話樹當(dāng)前狀態(tài) 用于判斷是否要開始這段對話
    public Node.State treeState = Node.State.Waiting;
    // 所有對話內(nèi)容的存儲列表
    public List<Node> nodes = new List<Node>();

    // 判斷當(dāng)前對話樹和對話內(nèi)容都是運行中狀態(tài)則進(jìn)行OnUpdate()方法更新
    public virtual void Update() {
        if(treeState == Node.State.Running && runningNode.state == Node.State.Running){
            runningNode = runningNode.OnUpdate();
        }
    }
    // 對話樹開始的觸發(fā)方法
    public virtual void OnTreeStart(){
        treeState = Node.State.Running;
    }
    // 對話樹結(jié)束的觸發(fā)方法
    public virtual void OnTreeEnd(){
        treeState = Node.State.Waiting;
    }
}

實體類對話節(jié)點樹

using UnityEngine;

[CreateAssetMenu()]
public class DialogueTree : NodeTree{
    public override void OnTreeStart(){
        base.OnTreeStart();
        runningNode.state = Node.State.Running;
    }
}

3-3.對話樹啟動器

using UnityEngine;

public class DialogueRunner : MonoBehaviour
{
    public DialogueTree tree;

    private void Start() {
    
    }
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.P)){
            tree.OnTreeStart();
        }
        if(tree != null){
            tree.Update();
        }
        if(Input.GetKeyDown(KeyCode.D)){
            tree.OnTreeEnd();
        }
    }
}

以上就是所有的運行時腳本了
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
此時在項目內(nèi)點擊右鍵,便可以看到我們剛剛編寫的可創(chuàng)建資產(chǎn)化的對話節(jié)點樹和對話節(jié)點了
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

4.啟動運行時對話腳本

4-1.創(chuàng)建實例話腳本對象

右鍵創(chuàng)建5個實例話腳本對象,分別為:
1個對話節(jié)點樹
3個普通對話節(jié)點
1個分支對話節(jié)點

并且按照父子節(jié)點順序關(guān)系命名
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

4-2.管理對話節(jié)點樹對應(yīng)屬性

1.選擇對對話節(jié)點樹并在屬性面板中創(chuàng)建4個子對話節(jié)點
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
2.選擇對應(yīng)初始運行節(jié)點
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

3.將對應(yīng)實例化對話節(jié)點按照對話順序拖動到對應(yīng)位置
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

4-3.管理各個對話節(jié)點對應(yīng)屬性

普通對話實例
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
分支對話實例
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
后續(xù)的對話實例也以此類推管理其對應(yīng)的屬性
1.填寫對話內(nèi)容
2.將對應(yīng)的子對話內(nèi)容關(guān)聯(lián)到子節(jié)點當(dāng)中(PS : 如果是最后的節(jié)點則無需關(guān)聯(lián))

4-4.創(chuàng)建對話啟動器

1.在場景中創(chuàng)建一個對象
2.將對話啟動器腳本掛載到該對象上
3.將創(chuàng)建好的對話樹掛載到該啟動器腳本的對話樹屬性上
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

此時我們點擊運行啟動腳本便可以,按照啟動器Update()與對話節(jié)點LogicUpdate()中所寫好的操作方法觸發(fā)播放對應(yīng)的對話內(nèi)容了。
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

5.UIToolkit創(chuàng)建對話系統(tǒng)編輯器

5-1.補充完善Runtime腳本

在上一章節(jié)當(dāng)中我們編寫的Runtime腳本僅僅從運行時的角度出發(fā),并沒有考慮到可視化編輯相關(guān)的邏輯,因此我們需要在之前的腳本當(dāng)中補充對應(yīng)代碼邏輯
1.需要在Node抽象類中補充一個guid和position屬性

    [HideInInspector]public string guid;
    [HideInInspector]public Vector2 position;

2.需要在NodeTree類中補充添加節(jié)點和刪除節(jié)點的方法

#if UNITY_EDITOR
        public Node CreateNode(System.Type type){
            Node node = ScriptableObject.CreateInstance(type) as Node;
            node.name =type.Name;
            node.guid = GUID.Generate().ToString();
         
            nodes.Add(node);
            if(!Application.isPlaying){
                AssetDatabase.AddObjectToAsset(node,this);
            }
            AssetDatabase.SaveAssets();
            return node;
        }
        public Node DeleteeNode(Node node){
            nodes.Remove(node);
            AssetDatabase.RemoveObjectFromAsset(node);
            // Undo.DestroyObjectImmediate(node);
            AssetDatabase.SaveAssets();
            return node;
        }
#endif

5-2.創(chuàng)建NodeEditor窗口

1.我們需要在項目中右鍵 Create => UI Toolkit => Editor Window
2.輸入對應(yīng)的編輯器窗口名稱
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
3.點擊Confirm成功創(chuàng)建出NodeEditor界面
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
4.此時我需要把默認(rèn)生成的NodeEditor腳本里的代碼修改一下

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;


public class NodeEditor : EditorWindow
{
    NodeTreeViewer nodeTreeViewer;
    InspectorViewer inspectorViewer;
    [MenuItem("Window/UI Toolkit/NodeEditor")]
    public static void ShowExample()
    {
        NodeEditor wnd = GetWindow<NodeEditor>();
        wnd.titleContent = new GUIContent("NodeEditor");
    }

    public void CreateGUI()
    {
        VisualElement root = rootVisualElement;
        
        var nodeTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/NodeEditor/Editor/UI/NodeEditor.uxml");
        // 此處不使用visualTree.Instantiate() 為了保證行為樹的單例防止重復(fù)實例化,以及需要將此root作為傳參實時更新編輯器狀態(tài)
        nodeTree.CloneTree(root);

        var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/NodeEditor/Editor/UI/NodeEditor.uss");
        root.styleSheets.Add(styleSheet);
        
        // 將節(jié)點樹視圖添加到節(jié)點編輯器中
        nodeTreeViewer = root.Q<NodeTreeViewer>();
        // 將節(jié)屬性面板視圖添加到節(jié)點編輯器中
        inspectorViewer = root.Q<InspectorViewer>();
    }
    private void OnSelectionChange() {
        // 檢測該選中對象中是否存在節(jié)點樹
        NodeTree tree = Selection.activeObject as NodeTree;
        // 判斷如果選中對象不為節(jié)點樹,則獲取該對象下的節(jié)點樹運行器中的節(jié)點樹
        if(!tree){
            if(Selection.activeGameObject){
                NodeTreeRunner runner = Selection.activeGameObject.GetComponent<NodeTreeRunner>();
                if(runner){
                    tree = runner.tree;
                }
            }
        }
        if(Application.isPlaying){
            if(tree){
                if(nodeTreeViewer != null){
                    nodeTreeViewer.PopulateView(tree);
                }
            }
        }else{
            if(tree && AssetDatabase.CanOpenAssetInEditor(tree.GetInstanceID())){
                if(nodeTreeViewer != null){
                    nodeTreeViewer.PopulateView(tree);
                }
            }
        }
    }
}

5.此時我們需要把NodeEditor.uxml里面默認(rèn)生成的一些元素刪除,我們就可以得到一個嶄新干凈的編輯器界面了
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
6.我們通過一些前端的技術(shù)手法將該NodeEditor分為左右兩邊的區(qū)域(左邊為Inspector右邊NodeTreeViewer
(圖文難以說明,詳細(xì)內(nèi)容可以觀看下面視頻教程 )。
合集·Unity官方編輯器擴展工具UI ToolKit】UI Builder 制作簡易對話系統(tǒng)編輯器

unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序

5-3.創(chuàng)建NodeTreeViewer視圖

1.在項目中右鍵創(chuàng)建一個名為NodeTreeViewer腳本
2.該腳本需要繼承GraphView,并添加一些GraphView功能代碼

using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using System;

public class NodeTreeViewer : GraphView
{
    public Action<NodeView> OnNodeSelected;
    public new class UxmlFactory : UxmlFactory<NodeTreeViewer,GraphView.UxmlTraits>{}
    NodeTree tree;
    public NodeTreeViewer(){
        Insert(0, new GridBackground());
        // 添加視圖縮放
        this.AddManipulator(new ContentZoomer());
        // 添加視圖拖拽
        this.AddManipulator(new ContentDragger());
        // 添加選中對象拖拽
        this.AddManipulator(new SelectionDragger());
        // 添加框選
        this.AddManipulator(new RectangleSelector());
        var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/NodeEditor/Editor/UI/NodeTreeViewer.uss");
        styleSheets.Add(styleSheet);
    }
    
    // NodeTreeViewer視圖中添加右鍵節(jié)點創(chuàng)建欄
    public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
    {
        // 添加Node抽象類下的所有子類到右鍵創(chuàng)建欄中
        {
            var types = TypeCache.GetTypesDerivedFrom<Node>();
            foreach(var type in types){
                evt.menu.AppendAction($"{type.Name}", (a) => CreateNode(type));
            }
        }
    }

    void CreateNode(System.Type type){
        // 創(chuàng)建運行時節(jié)點樹上的對應(yīng)類型節(jié)點
        Node node = tree.CreateNode(type);
        CreateNodeView(node);
    }

    void CreateNodeView(Node node){
        // 創(chuàng)建節(jié)點UI
        NodeView nodeView = new NodeView(node);
        // 節(jié)點創(chuàng)建成功后 讓nodeView.OnNodeSelected與當(dāng)前節(jié)點樹上的OnNodeSelected關(guān)聯(lián) 讓該節(jié)點屬性顯示在InspectorViewer上
        nodeView.OnNodeSelected = OnNodeSelected;
        // 將對應(yīng)節(jié)點UI添加到節(jié)點樹視圖上
        AddElement(nodeView);
    }
    
    // 只要節(jié)點樹視圖發(fā)生改變就會觸發(fā)OnGraphViewChanged方法
    private GraphViewChange OnGraphViewChanged(GraphViewChange graphViewChange)
    {
        // 對所有刪除進(jìn)行遍歷記錄 只要視圖內(nèi)有元素刪除進(jìn)行判斷
        if(graphViewChange.elementsToRemove != null){
            graphViewChange.elementsToRemove.ForEach(elem =>{
                // 找到節(jié)點樹視圖中刪除的NodeView
                NodeView nodeView = elem as NodeView;
                if(nodeView != null){
                    // 并將該NodeView所關(guān)聯(lián)的運行時節(jié)點刪除
                    tree.DeleteeNode(nodeView.node);
                }
            });
        }
        return graphViewChange;
    }
internal void PopulateView(NodeTree tree){
        this.tree = tree;
        // 在節(jié)點樹視圖重新繪制之前需要取消視圖變更方法OnGraphViewChanged的訂閱
        // 以防止視圖變更記錄方法中的信息是上一個節(jié)點樹的變更信息
        graphViewChanged -= OnGraphViewChanged;
        // 清除之前渲染的graphElements圖層元素
        DeleteElements(graphElements);
        // 在清除節(jié)點樹視圖所有的元素之后重新訂閱視圖變更方法OnGraphViewChanged
        graphViewChanged += OnGraphViewChanged;
    }
}

3.創(chuàng)建一個與NodeTreeViewer同名的USS文件unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
4.且將下列背景樣式Copy到USS文件當(dāng)

GridBackground{
    --grid-background-color: rgb(40,40,40);
    --line-color: rgba(193,196,192,0.1);
    --thick-line-color: rgba(193,196,192,0.1);
    --spacing: 15;
}

5.回到UI Builder的NodeEditor工程中,由于我們在NodeTreeViewer腳本當(dāng)中添加了
“ public new class UxmlFactory : UxmlFactory<NodeTreeViewer,GraphView.UxmlTraits>{} ” 腳本
使用我們可以在組件庫的Custom Controls當(dāng)中找到我們剛剛寫好的NodeTreeViewer視圖,我們直接將該視圖拖拽到uxml工程當(dāng)中即可unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
6.在調(diào)整好了UXML每個元素的樣式之后這(這里圖文難以講解,具體的看視頻為主)就得到了一個可拖拽 可縮放的NodeTreeViewer網(wǎng)格視圖了。

5-4.創(chuàng)建Node節(jié)點視圖

1.創(chuàng)建一個NodeView腳本,且需要繼承GraphView.Node

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using UnityEditor;

public class NodeView : UnityEditor.Experimental.GraphView.Node
{
    public Action<NodeView> OnNodeSelected;
    public Node node;
    public Port input;
    public Port output;
    public NodeView(Node node){
        this.node = node;
        this.title = node.name;
        // 將guid作為Node類中的viewDataKey關(guān)聯(lián)進(jìn)行后續(xù)的視圖層管理
        this.viewDataKey = node.guid;
        style.left = node.position.x;
        style.top = node.position.y;

        CreateInputPorts();
        CreateOutputPorts();
    }

    private void CreateInputPorts()
    {
        /*將節(jié)點入口設(shè)置為 
            接口鏈接方向 橫向Orientation.Vertical  豎向Orientation.Horizontal
            接口可鏈接數(shù)量 Port.Capacity.Single
            接口類型 typeof(bool)
        */
        // 默認(rèn)所有節(jié)點為多入口類型
        input = InstantiatePort(Orientation.Vertical, Direction.Input, Port.Capacity.Multi, typeof(bool));
        
        if(input != null){
            // 將端口名設(shè)置為空
            input.portName = "";
            inputContainer.Add(input);
        }
    }

    private void CreateOutputPorts()
    {
       	output = InstantiatePort(Orientation.Vertical, Direction.Output, Port.Capacity.Multi, typeof(bool));
        if(output != null){
            output.portName = "";
            outputContainer.Add(output);
        }
    }
    // 設(shè)置節(jié)點在節(jié)點樹視圖中的位置
    public override void SetPosition(Rect newPos)
    {
        // 將視圖中節(jié)點位置設(shè)置為最新位置newPos
        base.SetPosition(newPos);
        // 將最新位置記錄到運行時節(jié)點樹中持久化存儲
        node.position.x = newPos.xMin;
        node.position.y = newPos.yMin;
        EditorUtility.SetDirty(node);
    }

    // 復(fù)寫Node類中的選中方法OnSelected
    public override void OnSelected()
    {
        base.OnSelected();
        // 如果當(dāng)前OnNodeSelected選中部位空則將該節(jié)點視圖傳遞到OnNodeSelected方法中視為選中
        if(OnNodeSelected != null){
            OnNodeSelected.Invoke(this);
        }
    }
}

5-5.創(chuàng)建InspectorViewer面板視圖

1.創(chuàng)建一個InspectorViewer腳本,且需要繼承VisualElement

using UnityEngine.UIElements;
using UnityEditor;
using UnityEngine;

public class InspectorViewer : VisualElement
{
    public new class UxmlFactory : UxmlFactory<InspectorViewer,VisualElement.UxmlTraits>{}
    Editor editor;
    public InspectorViewer(){

    }
    internal void UpdateSelection(NodeView nodeView ){
        Clear();
        UnityEngine.Object.DestroyImmediate(editor);
        editor = Editor.CreateEditor(nodeView.node);
        IMGUIContainer container = new IMGUIContainer(() => { 
            if(editor.target){
            editor.OnInspectorGUI();
            }
        });
        Add(container);
    }   
}

5-6.在NodeEditor視窗中可視化創(chuàng)建節(jié)點

在完成了上述的所有工作之后,來嘗試一下在我們自己制作的NodeEditor視窗中可視化創(chuàng)建節(jié)點把
1.我們在項目中重新創(chuàng)建一個NodeTree(一定要重新創(chuàng)建)
2.在頂部欄點擊Window => UI Toolkit => NodeEditor打開編輯窗口
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
3.此時需要在選中NodeTree腳本對象的情況下(一定要雙擊選中否則會報空指針異常)在NodeEditor編輯界面中右鍵選中我們需要創(chuàng)建的節(jié)點即可
unity uitoolkit 教程,Unity,UIToolkit,UIBuilder,1024程序員節(jié),unity,編輯器,游戲引擎,c#,游戲程序
這樣我們就成功的在NodeEditor視窗中可視化創(chuàng)建了一個節(jié)點

6.引用文獻(xiàn)

【Unity UIBuilder】官方使用手冊

【Unity UIToolkit】官方使用手冊

【Unity3D】UI Toolkit簡介 - 作者 : little_fat_sheep

以上就是本文章全部內(nèi)容了,如果覺得實用可以點個收藏和關(guān)注。博主空間還有更多和Unity相關(guān)的實用技巧歡迎大家來一起相互學(xué)習(xí)。文章來源地址http://www.zghlxwxcb.cn/news/detail-761589.html

到了這里,關(guān)于【Unity UIToolkit】UIBuilder基礎(chǔ)教程-制作簡易的對話系統(tǒng)編輯器 3步教你玩轉(zhuǎn)Unity編輯器擴展工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • unity uitoolkit學(xué)習(xí)

    unity uitoolkit學(xué)習(xí)

    1、打開面板 2、找到元素 在UI Builder窗體,別忘了打開Preview再選擇元素 3、可以選擇不同類型的窗體 4、查看元素的樣式 需要注意的是下面的樣式會覆蓋上面的 5、調(diào)試 1、找到PanelSettingsTheme Style Sheet的資源文件,然后新建uss樣式文件 2、將uss文件拖拽到Style Sheets中, 需要注意

    2024年02月11日
    瀏覽(22)
  • unity如何制作簡易倒計時器

    首先理清思路,計時器的核心要素是計時的總時長和時間間隔需要均勻一秒,要實現(xiàn)的功能是在總時長的基礎(chǔ)上實現(xiàn)等時間間隔減秒,并且減到0后終止。 其中最為關(guān)鍵的問題就是怎么得到均勻的時間間隔1秒,所以我們需要知道: Time.time 表示從游戲開發(fā)到現(xiàn)在的時間,會隨

    2024年02月16日
    瀏覽(19)
  • 【Unity】簡易俄羅斯方塊(Tetris)制作

    【Unity】簡易俄羅斯方塊(Tetris)制作

    原視頻:https://www.youtube.com/watch?v=T5P8ohdxDjo b站轉(zhuǎn)載:【UNITY】13分鐘制作出俄羅斯方塊?。ǜ较螺d)_嗶哩嗶哩_bilibili 一、背景及方塊制作關(guān)鍵點 1、要將背景的左下角移到坐標(biāo)(0,0)點 2、方塊的旋轉(zhuǎn)點設(shè)置 3、方塊坐標(biāo)需要在整數(shù)值 二、腳本 1、TetrisBlock

    2024年02月05日
    瀏覽(23)
  • Unity3d 制作一個簡單的NPC對話系統(tǒng)

    Unity3d 制作一個簡單的NPC對話系統(tǒng)

    ? 最近在自己寫一個比較小的項目,雖然自己是一個策劃,但是程序方面我覺得也是很有必要學(xué)一學(xué)的。 ? 經(jīng)過了接近一年的學(xué)習(xí),也終于是可以獨自寫一些小的系統(tǒng)了。 ? 這次自己寫了一個比較簡單的NPC對話系統(tǒng),供大家參考。 進(jìn)入對話區(qū)域 開始對話 Inspector面板可調(diào)

    2023年04月08日
    瀏覽(30)
  • 【Unity 實用插件篇】 | 使用Fungus插件制作一個對話系統(tǒng),簡單好學(xué)易上手
  • 【Unity 實用工具篇】?| 使用Fungus插件制作一個對話系統(tǒng),簡單好學(xué)易上手
  • 安信可新品雷達(dá)模組Rd-03搭配STM32制作簡易人體感應(yīng)雷達(dá)燈教程

    安信可新品雷達(dá)模組Rd-03搭配STM32制作簡易人體感應(yīng)雷達(dá)燈教程

    - 安信可最新雷達(dá)模組Rd-03已經(jīng)橫空出世,為了方便大家使用該模組,本教程將使用STM32F103C8T6搭配Rd-03制作一個簡易的人體檢測雷達(dá)燈。 Rd-03共有五個管腳,以下是管腳功能定義表: 序號 引腳 說明 1 3.3V 輸入電源 2 GND 接地 3 OT1 UART_TX 4 RX UART_RX 5 OT2 檢測結(jié)果輸出,感應(yīng)時輸出

    2024年03月14日
    瀏覽(26)
  • Excel與Unity工作流(二):基礎(chǔ)對話框架

    Excel與Unity工作流(二):基礎(chǔ)對話框架

    本文將演示在unity中實現(xiàn)類似galgame的對話效果,并且通過Excel進(jìn)行文本、圖片、選項、賦值、音樂的配置 (該圖主要是展示版面和大致目標(biāo)效果,與本文關(guān)系不大) (來源:《無期迷途》) 每點擊一次鼠標(biāo),就出現(xiàn)下一個對話/或者出現(xiàn)選項; 如果出現(xiàn)選項,點擊選項,會有不同

    2024年04月14日
    瀏覽(23)
  • QT基礎(chǔ)教程之五對話框QDialog

    對話框是 GUI 程序中不可或缺的組成部分。很多不能或者不適合放入主窗口的功能組件都必須放在對話框中設(shè)置。對話框通常會是一個頂層窗口,出現(xiàn)在程序最上層,用于實現(xiàn)短期任務(wù)或者簡潔的用戶交互。 Qt 中使用QDialog類實現(xiàn)對話框。就像主窗口一樣,我們通常會設(shè)計一個

    2024年02月10日
    瀏覽(21)
  • Unity教程||Unity添加中文字體||Unity知識記錄--制作UI粒子特效

    Unity教程||Unity添加中文字體||Unity知識記錄--制作UI粒子特效

    ## 1、拷貝字體文件 拷貝C:WindowsFonts文件夾下,華文細(xì)黑常規(guī)文件到項目中 ? ## 2、下載中文字庫 鏈接: https://pan.baidu.com/s/1KW31KB5vEImZHUWvQ9PLEQ 提取碼: bgug? 3、添加字體字庫 選擇Window-TextMeshPro-Font Asset Creator ? 進(jìn)入Font Asset Creator a、Source Font File 選擇字體文件 b、Atlas Resolution 都

    2024年02月09日
    瀏覽(89)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包