在unity脚本中控制Inspector面板的参数操作
作者:头号理想
在编写脚本的过程中我们会遇到一些小问题
比如一个的变量 为了在其他脚本中可以调用 我们需要写成public类型的
这样的话在Inspector面板中会出现此变量 这篇博客会给大家介绍一些方法去避免这些小问题
1.[Header(" ")]
这个的作用是给它下面的所有变量一个总标题
2.[Tooltip("")]
这个的作用是给下面的第一行(紧邻的语句)注释
这个注释和双斜杠的注释不同
这个注释的效果是在unity中鼠标拖到变量的名字上 他会出现注释(括号的双引号中的注释)
在这里我给大家一个例子 让大家可以明白一点
[Header("GameObject")] [Tooltip("手枪")] private GameObject SmallGunPlayer; [Tooltip ("AK47"), SerializeField] private GameObject BiglGunPlayer;
它的效果是
然后把鼠标拖到变量上边的时候是
大家对照脚本中的语句可以很轻易的理解了
3.[HideInInspector]
这个的用法是和在这篇博客开头的差不多
就是我们在一个不想出现在Inspector面板上出现的public变量
我们就在这个语句上添加[HideInInspector]即可
在unity的Inspector面板上就不会出现了
因为这个比较好理解 就不给例子了
4.[SerializeField]
这个和上面的语句相反 这个是private的变量
添加上这个语句之后的话
在unity的Inspector面板上可以改变其值 相当于public变量
不过private 具有一定的保护级别 这是和直接用public的区别
在这里最后提一下,以上语句可以一起用 效果可以重叠
具体效果在上面给出的代码和图片中可以发现
5.[Range( , )]
这个的用法是写在一个变量的前边(上边)
然后在unity的Inspector面板上就是一个类似于Slider的效果
[Range(2, 25)] public int maxRandomValue = 5;
6.[Serializable]
这个的作用是 我们在脚本中声明一个类的时候
我们可以把它其中的变量改成一个可以展开 折叠的变量
可能上面的描述不太准确 下面给大家一个例子
public Mydate date; [Serializable] public class Mydate { public float q; public float w; public float m; public float r; }
它的效果是
很容易就看懂了吧
在上边提到了类,在这里给一些小白朋友们介绍一下最简单的类在unity中的用法
[Serializable ] public class prefebs { public GameObject Bullet; public GameObject Robot; public Transform Position; } public prefebs Prefebs; private void Update { Prefebs.Robot.transform.Translate(transform.up*Time.deltatime*10); }
在上边很容易可以知道 在创建类之后在没在update start等中调用
通过上边介绍的所有方法可以制作出很多让你意想不到的效果
并且可以让你感觉这个真的好用
补充:Unity编辑器——Inspector 面板扩展
将EditorGUI 扩展在 Inspector 面板上
EditorGUI 和 GUI 的用法几乎完全一致,目前来说前者多用于编辑器开发,后者多用于发布后调试编辑器。总之,它们都是起辅助作用的。 EditorGUI 提供的组件非常丰富,常用的绘制元素包括文本、按钮、图片和滚动框等。做一个好的编辑器,是离不开 EditorGUI 的。如图:我们将 EditorGUI 拓展在 Inspector 面板上了,相关代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public class Script_03_23 : MonoBehaviour { public Vector3 scrollPos; public int myId; public string myName; public GameObject prefab; public MyEnum myEnum = MyEnum.One; public bool toogle1; public bool toogle2; public enum MyEnum { One=1, Two, } #if UNITY_EDITOR [CustomEditor(typeof(Script_03_23))] public class ScriptEditor_03_23 : Editor { private bool m_EnableToogle; public override void OnInspectorGUI() { //获取脚本对象 Script_03_23 script = target as Script_03_23; //绘制滚动条 script.scrollPos = EditorGUILayout.BeginScrollView(script.scrollPos, false, true); script.myName = EditorGUILayout.TextField("text", script.myName); script.myId = EditorGUILayout.IntField("int", script.myId); script.prefab = EditorGUILayout.ObjectField("GameObject", script.prefab, typeof(GameObject), true) as GameObject; //绘制按钮 EditorGUILayout.BeginHorizontal(); GUILayout.Button("1"); GUILayout.Button("2"); script.myEnum = (Script_03_23.MyEnum)EditorGUILayout.EnumPopup("MyEnum:", script.myEnum); EditorGUILayout.EndHorizontal(); //Toogle 组件 m_EnableToogle = EditorGUILayout.BeginToggleGroup("EnableToogle", m_EnableToogle); script.toogle1 = EditorGUILayout.Toggle("toogle1", script.toogle1); script.toogle2 = EditorGUILayout.Toggle("toogle2", script.toogle2); EditorGUILayout.EndToggleGroup(); EditorGUILayout.EndScrollView(); } } } #endif
EditorGUILayout —— 是EditorGUI 自动 布局版本。
EditorGUILayout.BeginScrollView —— 函数原型: public static Vector2 BeginScrollView( Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, params GUILayoutOption[] options);
scrollPosition参数: 显式使用的位置
alwaysShowHorizontal —— 表示可选的参数,始终显示水平滚动条。如果为false或省略,那么则仅当ScrollView中的内容比ScrollView本身更宽时才会显示。
alwayShowVertical —— 表示可选的参数,始终显示垂直滚动条。如果为false或省略,那么只有当ScrollView中的内容比ScrollView本身高时才会显示。
EditorWindows 窗口
Unity 提供编辑器窗口,开发者可以自由拓展自己的窗口。 Unity 编辑器系统自带的视图窗口其实也是用 EditorWindows 实现的。如图所示,我们来制作一个简单的编辑窗口,它绘制元素时同样使用 EditorGUI 代码。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class Script_03_24Window : EditorWindow { [MenuItem("Window/Open My Window")] static void Init() { Script_03_24Window window = (Script_03_24Window)EditorWindow.GetWindow(typeof(Script_03_24Window)); window.Show(); } private Texture m_MyTexture = null; private float m_MyFloat = 0.5f; void Awake() { Debug.LogFormat("窗口初始化时调用"); m_MyTexture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/unity1.png"); } void OnGUI() { GUILayout.Label("Hello World!!", EditorStyles.boldLabel); m_MyFloat = EditorGUILayout.Slider("Slider", m_MyFloat, -5, 5); GUI.DrawTexture(new Rect(0, 30, 100, 100), m_MyTexture); } void OnDestroy() { Debug.LogFormat("窗口销毁时调用"); } void OnFocus() { Debug.LogFormat("窗口拥有焦点时调用"); } void OnHierarchyChange() { Debug.LogFormat("Hierarchy视图发生改变时调用"); } void OnInspectorUpdate() { //Debug.LogFormat ("Inspector每帧更新"); } void OnLostFocus() { Debug.LogFormat("失去焦点"); } void OnProjectChange() { Debug.LogFormat("Project视图发生改变时调用"); } void OnSelectionChange() { Debug.LogFormat("Hierarchy或者Project视图中选择一个对象时调用"); } void Update() { //Debug.LogFormat ("每帧更新"); } }
EditorWindows 下拉菜单
如图 所示,在 EditorWindows 编辑窗口的右上角,有个下拉菜单,我们也可以对该菜单中的选项进行拓展,不过这里需要实现 IHasCustomMenu 接口。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class Script_03_25Window : EditorWindow,IHasCustomMenu { void IHasCustomMenu.AddItemsToMenu(GenericMenu menu) { menu.AddDisabledItem(new GUIContent("Disable")); menu.AddItem(new GUIContent("Test1"), true, () => { Debug.Log("Test1"); }); menu.AddItem(new GUIContent("Test2"), true, () => { Debug.Log("Test2"); }); menu.AddSeparator("Test/"); menu.AddItem(new GUIContent("Test/Tes3"), true, () => { Debug.Log("Tes3"); }); } [MenuItem("Window/TAOTAO My Window")] static void Init() { Script_03_25Window window = (Script_03_25Window)EditorWindow.GetWindow(typeof(Script_03_25Window)); window.Show(); } }
上述代码中,我们通过 AddItem()方法来添加列表元素,并且监听选择后的事件。
预览窗口
选择游戏对象或者游戏资源后, Inspector 面板下方将会出现它的预览窗口,但是有些资源是没有预览信息的,不过我们可以监听它的窗口方法来重新绘制它,如图 所示,相关代码如下。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; [CustomPreview(typeof(GameObject))] public class Script_03_26 : ObjectPreview { public override bool HasPreviewGUI() { return true; } public override void OnPreviewGUI(Rect r, GUIStyle background) { GUI.DrawTexture(r, AssetDatabase.LoadAssetAtPath<Texture>("Assets/Unity.png")); GUILayout.Label("Hello World!"); } }
获取预览信息
有些资源是有预览信息的,比如模型资源。在预览窗口中,我们可以看到它的样式。如果需要在自定义窗口中显示它,就需要获取它的预览信息。如图所示,选择一个游戏对象后,会在自定义窗口中显示它,相关代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class Script_03_27window : EditorWindow { private GameObject m_MyGo; private Editor m_MyEditor; [MenuItem("Window/TAOSHUI Open My Window")] static void Init() { Script_03_27window window = (Script_03_27window)EditorWindow.GetWindow(typeof(Script_03_27window)); window.Show(); } void OnGUI() { //设置一个游戏对象 m_MyGo = (GameObject)EditorGUILayout.ObjectField(m_MyGo, typeof(GameObject), true); if(m_MyGo !=null) { if(m_MyEditor==null) { //创建Editor 实例 m_MyEditor = Editor.CreateEditor(m_MyGo); } //预览它 m_MyEditor.OnPreviewGUI(GUILayoutUtility.GetRect(500, 500), EditorStyles.whiteLabel ); } } }
在上述代码中,预览对象首先需要通过 Editor.CreateEditor()拿到它的 Editor 实例对象,接着调用 OnPreviewGUI()方法传入窗口的显示区域。