本文主要是介绍Unity插件开发笔记IMGUI-持续记录中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
插件特点,无需运行可进行编译。
分为3大类插件:菜单项相关操作、自定义Inspector检视面板、自定义操作界面。
一.菜单项相关操作的插件分为4种:包含MenuItem菜单项插件、AddComponentMenu组件菜单插件、ContextMenu上下文菜单插件、RequireComponent必要组件菜单
1.MenuItem菜单项插件
(0)选项出现位置:编辑器上方菜单栏 。
(1)脚本放置的目录:Assets/Editor(该目录不会被打到包里)。
(2)创建如下方代码:需要命名空间UnityEditor;可自定义入口路径和自定义快捷键;MenuItem对应的自定义方法必须是static静态方法(方法在该脚本类的内部。static静态变量和静态方法是类中的静态成员,无论创建多少个类的对象,静态成员都只会存在一个,静态成员是不依赖于类的具体对象,可以通过类名.变量名(方法名)直接访问)。
(3)特点:无需放到场景里也无需运行,点击使用即可对MenuItem对应的函数进行编译。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;//MenuItem类插件需要该命名空间public class MenuItem_Test1 : MonoBehaviour
{//快捷键类型(H是可自定义按键)//_H:单一个自定义按键//#H: Shift+自定义按键//%H:Ctrl+自定义按键//&H: Alt+自定义按键[MenuItem("Menu/Test_ _H")]//注册菜单选项:Menu/Test_是自定义的菜单路径,H是自定义的快捷键,放在该MenuItem_Test1类的里面public static void Test1()//定义MenuItem菜单操作:菜单必须是static静态方法{Debug.Log("Test_");}[MenuItem("Menu/Test# #H")]public static void Test2(){Debug.Log("Test#");}[MenuItem("Menu/Test% %H")]public static void Test3(){Debug.Log("Test%");}[MenuItem("Menu/Test& &H")]public static void Test4(){Debug.Log("Test&");}
}
2.AddComponentMenu组件菜单插件
(0)选项出现位置:节点上AddComponent增加组件时的可选组件列表里 。
(1)脚本放置的目录:一般在Assets/Script里(可自定义,会被打到包里的目录即可)。
(2)创建如下方代码:可自定义在添加组件时的菜单路径(放在该脚本类的前面)。
(3)特点:跟组件一样,需放到场景里也需运行,才可进行编译。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[AddComponentMenu("Menu/Test2")]//Test2是Component_Test1类脚本的组件名称,Menu/Test2是添加组件时的菜单路径,放在该Component_Test1类的前面
public class Component_Test1 : MonoBehaviour//定义Component操作
{void Start(){Debug.Log("Component_Test");}void Update(){}
}
3.ContextMenu上下文菜单插件
(0)选项出现位置:节点上的组件的右键菜单列表里 。
(1)脚本放置的目录:一般在Assets/Script里(可自定义,会被打到包里的目录即可)。
(2)创建如下方代码:可自定义在组件的右键菜单列表的菜单路径(放在该脚本类的内部)。
(3)特点:场景里需有所在的组件,但无需运行,点击使用即可进行编译。
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;[AddComponentMenu("Menu/Test2")]
public class Component_Test1 : MonoBehaviour
{void Start(){Debug.Log("Component_Test");}void Update(){}[ContextMenu("Menu3")]//Menu3是组件右键菜单列表里的路径,放在该Component_Test1类的内部public void Test()//定义ContextMenu菜单操作{Debug.Log("ContextMenu_Test");}
}
4.RequireComponent必要组件菜单
(0)选项出现位置:无菜单,自动添加关联的必要组件。
(1)脚本放置的目录:一般在Assets/Script里(可自定义,会被打到包里的目录即可)。
(2)创建如下方代码:可自定义在添加组件时的菜单路径(放在该脚本类前面AddComponentMenu语句的前面)。
(3)特点:场景里需添加对应组件,无需运行,即可自动进行编译。
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;[RequireComponent(typeof(Rigidbody))]//设置该脚本类Component_Test1的必要组件菜单-Rigidbody(自定义的必要组件):添加该脚本,会自动添加Rigidbody组件。不算严格意义的组件,主要是给该脚本类设置关联。Rigidbody是依附于该脚本类Component_Test1的,需先删除本脚本,才能删除Rigidbody组件
[AddComponentMenu("Menu/Test2")]
public class Component_Test1 : MonoBehaviour
{void Start(){Debug.Log("Component_Test");}void Update(){}
}
二.自定义Inspector检视面板插件
1.常打的4种Attribute属性标识:HideInInspectory隐藏变量;NonSerialized不序列化保存;SerializeField序列化域;Serializable关键字序列化。
(还有许多其他的Attribute属性标识,还有odin插件的Attribute属性标识比IMGUI的Attribute属性标识的功能更全使用更简单。)
(1)HideInInspectory隐藏变量:隐藏公有变量属性显示。
(2)NonSerialized不序列化保存:隐藏公有变量属性显示且不序列化保存。需要using System;命名空间。
(3)SerializeField序列化域:强制显示私有变量且序列化保存。
(4)Serializable可序列化的:需要在Type1类的定义前面设置,会把该类的公有变量在这里也序列化。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Component_Test2 : MonoBehaviour
{public int Int1=3;//正常公有变量(默认情况下:公有变量会序列化,私有变量不会序列化;序列化指显示在界面组件上且会存储到硬盘上)[HideInInspector]//HideInInspector:隐藏公有变量属性显示。public int Int2=3;[NonSerialized]//NonSerialized:隐藏公有变量显示,防止变量序列化保存。需要using System;的命名空间。public int Int3=3;[SerializeField]//SerializeField:序列化域。强制显示私有变量,且序列化保存到硬盘上。private int Int4;//[Serializable]:关键字序列化。需要在Type1类的定义前面设置,会把该类的公有变量在这里也序列化。public Type1 mType=new Type1();void Start(){}void OnGUI(){}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[Serializable]//关键字序列化。需要在对应Type1类的定义前面设置,会把该类的公有变量在其他地方新建该类的时候也序列化。
public class Type1 //不挂在界面里的节点上,所以不用继承MonoBehaviour
{public int InitVal;public float FloatVal;private Color mColor;void Start(){}void Update(){}
}
2.自定义界面属性
(1)被自定义属性界面的类:在挂在界面节点上,继承MonoBehaviour,脚本放置在Assets/Script(可自定义,会被打到包里的目录即可)。
1) 属性类型、自定义class类方法里的属性等都在该脚本里定义
2)自定义class类方法前面需打可被序列化的Attribute属性标识:[System.Serializable]
(2)自定义绘制界面属性类:新建一个C#脚本,继承自Editor(需要using UnityEditor;命名空间),脚本放置在Assets/Editor(该目录不会被打到包里)。
1)继承自Editor的类前面需打关联上被自定义属性界面(序列化对象)的Attribute属性标识:[CustomEditor(typeof(被自定义属性界面的类),true)]。
2)声明序列化对象SerializedObject,和声明序列化属性SerializedProperty
3)在OnEnable()函数里初始化赋值以上的序列化对象和序列化属性:新建序列化对象,FindProperty序列化属性
4)在override void OnInspectorGUI()复写Editor的绘制函数里:先更新序列化对象Update,再自定义绘制序列化属性EditorGUILayout.PropertyField,再让序列化对象应用自定义绘制ApplyModifiedProperties
5)在override void OnInspectorGUI()复写Editor的绘制函数里的默认绘制语句:base.OnInspectorGUI();//表示按照Editor默认的行为将所有的序列化属性绘制出来:属性面板包含默认的绘制+本脚本的绘制。 如果去掉这句话, 属性面板上只会绘制脚本的名字+本脚本的绘制。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test3 : MonoBehaviour//挂界面节点上的脚本,继承MonoBehaviour
{public int IntVal;public float FloatVal;public string StrVal;public Type3 Type3Val=new Type3();//引用类型class,需要实例化出一个对象“带()”// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}[System.Serializable]//在Test3_Window窗口绘制脚本里需要序列化,所以这里需要设置成可序列化的
public class Type3//class是引用类型
{public int mInt;public int mInt2;
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;//继承Editor类,需要改命名空间
using UnityEngine;[CustomEditor(typeof(Test3),true)]//把Test3类的属性关联到本编辑界面,Test3是继承了MonoBehavior脚本的类(当然还有其它类);第2个参数指是否对其子类生效
public class Test3_Inspoector : Editor//不挂在界面里的节点上,所以不用继承MonoBehaviour。本编辑界面需继承Editor类,需要using UnityEditor;命名空间。放在Asset/Editor目录下,不打入包内。
{public SerializedObject mObj;//SerializedObject序列化对象类型public SerializedProperty mInt;//SerializedProperty序列化通用属性类型public SerializedProperty mFloat;public SerializedProperty mStr;public SerializedProperty mType3;//选择当前脚本所在的游戏对象时执行public void OnEnable(){this.mObj=new SerializedObject(target);//这里的target指被检视的Object对象Test3类,这里时用被检视的Object对象新建序列化对象this.mInt=this.mObj.FindProperty("IntVal");//FindProperty查找序列化对象中的已有属性,然后赋值给序列化属性this.mFloat=this.mObj.FindProperty("FloatVal");this.mStr=this.mObj.FindProperty("StrVal");this.mType3=this.mObj.FindProperty("Type3Val");}//显示绘制本编辑界面public override void OnInspectorGUI()//override指是重写父类的方法,OnInspectorGUI方法会在对象获得焦点或者对象属性变化或者其他一些情况下调用{ //base.OnInspectorGUI();//表示按照Editor默认的行为将所有的序列化属性绘制出来:属性面板包含默认的绘制+本脚本的绘制。 如果去掉这句话, 属性面板上只会绘制脚本的名字+本脚本的绘制。//更新一下序列化对象,以免数据未同步this.mObj.Update();//重载:绘制属性到Inspector检视面板里EditorGUILayout.PropertyField(this.mInt);//EditorGUILayout.PropertyField:按照默认行为绘制该字段EditorGUILayout.PropertyField(this.mFloat);//EditorGUILayout.PropertyField(this.mStr);EditorGUILayout.PropertyField(this.mType3,true);//第2个参数true指包括子节点,现在默认就是包括的了所以不设置也可以//序列化对象应用修改的属性this.mObj.ApplyModifiedProperties();//ApplyModifiedProperties的返回值能够表明序列化字段是否有修改,返回true代表有修改}
}
3.自定义序列化属性字段(枚举enum+switch方法实现多类型选一显示)
(1)被自定义属性界面的类:Test4 ,说明同上“2.自定义界面属性”。多定义了一个枚举类型。
(2)自定义绘制界面属性类:Test4_EditorInspector ,说明同上“2.自定义界面属性”。多用了一个Switch方法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public enum Enum4//enum枚举类型:会在编译阶段将名字替换成对应的整数常量(从0开始),是预处理指令宏#define的替代
{None,IntVal,FloatVal,StrVal,ColorVal
}//None/IntValue/FloatVal/StrValColorVal是全局常量,其他地方不可有相同名字的变量或常量
public class Test4 : MonoBehaviour
{public Enum4 mEnum;//在上方定义public int mInt;public float mFloat;public string mStr;public Color mColor;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(Test4))]//把该属性视图面板Test4_EditorInspector定义到Test4里
public class Test4_EditorInspector : Editor
{public SerializedObject mObj;public SerializedProperty mEnum;public SerializedProperty mInt;public SerializedProperty mFloat;public SerializedProperty mStr;public SerializedProperty mColor;public void OnEnable(){//初始化this.mObj=new SerializedObject(target);this.mEnum=this.mObj.FindProperty("mEnum");this.mInt=this.mObj.FindProperty("mInt");this.mFloat=this.mObj.FindProperty("mFloat");this.mStr=this.mObj.FindProperty("mStr");this.mColor=this.mObj.FindProperty("mColor");}public override void OnInspectorGUI(){this.mObj.Update();//序列化对象更新//自定义绘制EditorGUILayout.PropertyField(this.mEnum);switch(this.mEnum.enumValueIndex)//开关语句{case 1:EditorGUILayout.PropertyField(this.mInt);//EditorGUILayout.PropertyField属性绑定绘制break;case 2:EditorGUILayout.PropertyField(this.mFloat);break;case 3:EditorGUILayout.PropertyField(this.mStr);break;case 4:EditorGUILayout.PropertyField(this.mColor);break;}this.mObj.ApplyModifiedProperties();//序列化对象应用自定义的修改}
}
三.自定义操作界面(类似Animation这种弹出的界面)
(0)选项出现位置:编辑器上方菜单栏 。
(1)脚本放置的目录:Assets/Editor(该目录不会被打到包里)。
(2)创建如下方代码:类名=窗口界面名;继承EditorWindow父类,需要命名空间UnityEditor;可用MenuItem自定义入口路径和自定义快捷键;MenuItem对应的自定义方法必须是static静态类方法(放在该脚本类的内部)。
(3)特点:无需放到场景里也无需运行,点击使用即可对MenuItem对应的函数进行编译。
1.界面的启动关闭-常用的EditorWindow的3种方法:
(1)Show:面板显示方法:跟Game窗口同级,可合并到编辑器面板里。可拖动,自带关闭按钮。
(2)ShowUtility:浮动显示方法:跟编辑器界面同级,不可合并到编辑器面板里。可拖动,自带关闭按钮。
(3)ShowPopup:不可拖动,需要手动增加绘制关闭按钮。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;//EditorWindow弹出窗口类需要该命名空间
using UnityEngine;public class Test5_Window : EditorWindow//EditorWindow弹出窗口类,需要using UnityEditor;命名空间
{[MenuItem("Menu/ShowTest5Window")]//注册菜单选项:在unity菜单栏里,增加执行下面ShowWindow函数的菜单项public static void ShowWindow(){//(1)面板显示方法:跟Game窗口同级,可合并到编辑器面板里。可拖动,自带关闭按钮Test5_Window.CreateInstance<Test5_Window>().Show();//创建窗口:实例化出一个窗口对象,点击菜单多次则创建多个相同的窗口。CreateInstance是窗口的官方实例化接口}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test5_Window : EditorWindow
{[MenuItem("Menu/ShowTest5Window")]public static void ShowWindow(){//(2)浮动显示方法:跟编辑器界面同级,不可合并到编辑器面板里。可拖动,自带关闭按钮Test5_Window.CreateInstance<Test5_Window>().ShowUtility();}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test5_Window : EditorWindow
{[MenuItem("Menu/ShowTest5Window")]public static void ShowWindow(){//(3)弹窗显示方法:不可拖动,需要手动增加绘制关闭按钮Test5_Window.CreateInstance<Test5_Window>().ShowPopup();}public void OnGUI()//自动执行的绘制函数{if(GUILayout.Button("关闭"))//GUILayout.Button绘制按钮{this.Close();//关闭界面}}
}
2.界面的相关事件机制(内置函数自动调用):
(1)单例形式创建窗口:EditorWindow.GetWindow。
(2)界面的事件机制:生命周期(也叫消息Message、必然事件)-常用事件监听有以下9种OnGUI(类似Update每帧调用)、Update、OnInspectorUpdate、OnDestroy、OnSelectionChange、OnFocus、OnLostFocus、OnHierarchyChange、OnHierarchyChange。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test6_Window : EditorWindow//继承EditorWindow类
{[MenuItem("Menu/ShowTest6Window")]//注册菜单选项public static void ShowWindow()//单例形式创建窗口{//创建窗口:实例化出一个窗口对象,点击菜单多次则创建多个相同的窗口。CreateInstance是窗口的官方实例化接口//Test6_Window.CreateInstance<Test6_Window>().Show();//单例形式创建窗口:点击菜单多次,也只打开一个Test6_Window窗口EditorWindow.GetWindow<Test6_Window>().Show();//获取Test6_Window本类型已打开窗口界面的第一个,然后把Test6_Window传递进去,然后Show显示出来}//界面的事件机制:生命周期(也叫消息Message、必然事件)-常用事件监听有以下9种OnGUI、Update、OnInspectorUpdate、OnDestroy、OnSelectionChange、OnFocus、OnLostFocus、OnHierarchyChange、OnHierarchyChange。//界面绘制方法:绘制操作面板上的内容,比如按钮public void OnGUI(){if(GUILayout.Button("关闭")){this.Close();}}//界面刷新方法:刷新周期每秒钟执行100次public void Update(){//index_1++;}public int index_1=0;//检视面板刷新方法:刷新周期比Update小public void OnInspectorUpdate(){ //Debug.Log("index_1:"+index_1+"\n"+"index_2:"+(index_2++));}public int index_2=0;//本视图面板被删除时,触发该事件并自动调用该方法public void OnDestroy(){Debug.Log("删除");}//在Hierarchy视图面板选择一个节点或者在Project视图面板里选择一个文件时,触发该事件并自动调用该方法public void OnSelectionChange(){//Debug.Log("在Hierarchy或Project选择一个对象");/*for(int i=0;i<Selection.gameObjects.Length;i++)//Selection.gameObjects:仅获取Hierarchy视图面板里目前选择的对象,即场景里的对象{Debug.Log("选择场景里的对象:"+Selection.gameObjects[i].name);}*/for(int i=0;i<Selection.objects.Length;i++)//Selection.objects:获取Hierarchy和Project视图面板里目前选择的对象{Debug.Log("选择对象:"+Selection.objects[i].name);}}//本视图面板获取焦点时,触发该事件并自动执行该方法public void OnFocus(){Debug.Log("本窗口获取焦点");}//本视图面板失去焦点时,触发该事件并自动执行该方法public void OnLostFocus(){Debug.Log("本窗口失去焦点");}//Hierarchy视图面板有任何更改时,触发该事件并自动执行该方法,但是组件里的属性数值发生变化不会触发public void OnHierarchyChange(){Debug.Log("Hierarchy有更改");}//Project视图面板有任何更改时,触发该事件并自动执行该方法public void OnProjectChange(){Debug.Log("Project有更改");}
}
3.文本和颜色字段-EditorGUILayout的方法
(1)文本输入字段-常用有3种:TextField单行输入框、TextArea多行输入框、PasswordField加密输入框。
(2)颜色选择字段:ColorField。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test7_Window : EditorWindow
{[MenuItem("Menu/ShowTest7Window")]public static void ShowWindow(){EditorWindow.GetWindow<Test7_Window>().Show();//EditorWindow单例形式打开界面}public string mText="默认文本";//用于存储输入的文本内容,保证创建文本输入框时的文本是输入的文本public Color mColor=Color.white;//用于存储修改的颜色值,保证创建颜色输入框时的颜色是输入的颜色public void OnGUI()//自动绘制函数{//EditorGUILayout创建一个输入框:重载输入一个字符串,同时也会返回一个字符串。重载就是一个类中有N个重名函数,但是他们的参数类型或者个数不相同,当然顺序不相同也是可以的,调用的时候,会自动根据你填写的参数类型,个数来调用匹配的重载(注意:和返回值木有任何关系)this.mText=EditorGUILayout.TextField(this.mText);//文本单行输入框字段this.mText=EditorGUILayout.TextArea(this.mText);//文本多行输入框字段this.mText=EditorGUILayout.PasswordField(this.mText);//文本单行密码输入框字段this.mColor=EditorGUILayout.ColorField(this.mColor);//颜色选择字段}
}
4.标签和换行字段(给属性增加前缀名字)-EditorGUILayout的方法
(1)标签前缀字段-常用有3种:LabelField静态标签前缀、SelectableLabel可选择标签前缀、PrefixLabel可聚焦不可选择标签前缀。
(2)空一行字段:Space。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test8_Window : EditorWindow
{[MenuItem("Menu/ShowTest8Window")]public static void ShowWindow(){EditorWindow.GetWindow<Test8_Window>().Show();//EditorWindow单例形式打开界面} public string mText="默认文本";public Color mColor=Color.white;public void OnGUI(){EditorGUILayout.LabelField("文本标签");//EditorGUILayout.LabelField:不可选择的文本标签字段,不能更改。this.mText=EditorGUILayout.TextField(this.mText);EditorGUILayout.SelectableLabel("可选择文本标签");//EditorGUILayout.SelectableLabel:可选择的文本标签字段,不能更改。上下会自动空行this.mText=EditorGUILayout.TextArea(this.mText);EditorGUILayout.PrefixLabel("可焦点但不可选择文本标签");//EditorGUILayout.PrefixLabel:可作为焦点但不可选择文本标签字段,不能更改。this.mText=EditorGUILayout.PasswordField(this.mText);EditorGUILayout.Space();//EditorGUILayout.Space:空一行字段。this.mColor=EditorGUILayout.ColorField(this.mColor);}
}
5.数字输入字段-EditorGUILayout的方法
(1)浮点型数字输入字段:FloatField
(2)整形数字输入字段:IntField
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test9_Window : EditorWindow
{[MenuItem("Menu/Show Test9Window")]public static void ShowWindow(){EditorWindow.GetWindow<Test9_Window>().Show();}public float mFloat;//用于存储输入的浮点数,保证创建浮点形数字输入框时的数值是输入的数值public int mInt;//用于存储输入的整数,保证创建整形数字输入框时的数值是输入的数值public void OnGUI(){EditorGUILayout.LabelField("浮点形数字输入框:");this.mFloat=EditorGUILayout.FloatField(this.mFloat);//浮点形数字输入框字段,单精度类型,保留7位有效数字EditorGUILayout.Space();EditorGUILayout.PrefixLabel("整形数字输入框:");this.mInt=EditorGUILayout.IntField(this.mInt);//整形数字输入框字段}
}
6.滑动条字段--EditorGUILayout的方法
(1)默认浮点型滑动条:Slider
(2)整形滑动条:IntSlider
(3)有长度的滑动条:MinMaxSlider
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Test10_Window : EditorWindow
{[MenuItem("Menu/ShowTest10Window")]public static void ShowWindow(){EditorWindow.GetWindow<Test10_Window>().Show();}public float mFloat;//用于存储滑动条设置的浮点数,保证创建滑动条时的当前数值是设置的数值public int mInt;//用于存储滑动条设置的整数,保证创建整数形滑动条时的当前数值是设置的数值public float mMinVal;//用于存储MinMaxSlider的有长度滑动条的左端的值public float mMaxVal;//用于存储MinMaxSlider的有长度滑动条的右端的值public void OnGUI(){//默认滑动条(浮点型)EditorGUILayout.LabelField("默认浮点型滑动条:");this.mFloat=EditorGUILayout.Slider(this.mFloat,0,10);//3个参数:默认值,最小值,最大值;会返回一个浮点型数值//整数型滑动条EditorGUILayout.LabelField("整形滑动条:");this.mInt=EditorGUILayout.IntSlider(this.mInt,0,10);//3个参数:默认值,最小值,最大值;会返回一个整型数值EditorGUILayout.Space();this.mMinVal=EditorGUILayout.Slider(this.mMinVal,0,10);//用于显示设置下面MinMaxSlider左端的数值this.mMaxVal=EditorGUILayout.Slider(this.mMaxVal,0,10);//用于显示设置下面MinMaxSlider右端的数值//最小最大限制滑动条(滑动条自身有长度)EditorGUILayout.LabelField("有长度的滑动条:");EditorGUILayout.MinMaxSlider(ref this.mMinVal,ref this.mMaxVal,1,10);//4个参数:第一个参数-有长度的滑动条左端点的值,第二个参数-有长度的滑动条右端点的值,最小值,最大值。ref是指引用类型的参数,引用传递是传递变量的地址,使得形参和实参指向同一内存空间,方法中对于形参的修改,实际上就是对实参的修改。调用方法时初始化参数值。}
}
这篇关于Unity插件开发笔记IMGUI-持续记录中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!