当前位置: 首页 > wzjs >正文

网站设计师如何让客户信任你北京做网站制作的公司哪家好

网站设计师如何让客户信任你,北京做网站制作的公司哪家好,深圳网站建设销售前景,世界十大搜索引擎排名大家好,我是阿赵。继续介绍Unity编辑器界面扩展。   在开发过程中,经常会遇到想自定义Inspector栏的内容。Inspector栏的内容都是通过Component来自定义的,比如可以自定义Unity已有的类型,比如Transform、RectTransform、Camera…

  大家好,我是阿赵。继续介绍Unity编辑器界面扩展。
  在开发过程中,经常会遇到想自定义Inspector栏的内容。Inspector栏的内容都是通过Component来自定义的,比如可以自定义Unity已有的类型,比如Transform、RectTransform、Camera、Light这种,或者自定义自己写的继承MonoBehaviour的脚本的内容。
  下面通过自定义Transform组件的Inspector作为例子,来说明一下应该怎样做。
在这里插入图片描述

一、指定组件的自定义Inspector界面

  在Editor文件夹里面新建一个C#文件,比如我这里新建了一个CustomTransformEditor 文件
在这里插入图片描述

  然后输入以下内容:

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Transform)), CanEditMultipleObjects]
public class CustomTransformEditor : Editor
{public override void OnInspectorGUI(){//这里写需要显示的组件}
}

  代码很简单,简单说明一下:

1. 指定修改某一种组件的Inspector界面

  比如我这里是修改Transform,所以是

CustomEditor(typeof(Transform))

2. 可以同时编辑多个物体

CanEditMultipleObjects

  加上了这一句之后,就可以在同时选择多个有相同Component的对象时,Inspector菜单可以同时修改这些对象的相同Component的内容。

3. 继承Editor

public class CustomTransformEditor : Editor

  虽然这不是一个EditorWindow,但却是一个Editor。继承了Editor之后,才能使用它的很多方法。

4. 写需要显示的UI内容

  需要显示的UI内容,要写在OnInspectorGUI方法里面。
由于现在OnInspectorGUI里面什么内容都没有,所以现在回到Unity编辑器,选择一个GameObject,会发现Transform组件里面什么都没有了。
在这里插入图片描述

  如果现在加上一句代码:

    public override void OnInspectorGUI(){//这里写需要显示的组件GUILayout.Label("this is a transform");}

  这时候回去编辑器,会看到这句话显示在Transform组件里面了。
在这里插入图片描述

二、 需要显示原来的界面内容:

  刚才的例子有一个问题,有时候我们可能并不想完全重写原来的组件的UI,而是在原有基础上加一点内容。那么怎么才能把原来的组件UI显示出来呢?
输入以下代码:

using System.Reflection;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Transform)), CanEditMultipleObjects]
public class CustomTransformEditor : Editor
{private Editor instance;private void OnEnable(){if(targets.Length<=0){return;}Transform tr = target as Transform;var editorType = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.TransformInspector");instance = CreateEditor(targets, editorType);//调用原编辑器的OnEnable方法editorType.GetMethod("OnEnable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, null);}public override void OnInspectorGUI(){if(instance!=null){instance.OnInspectorGUI();}//这里写需要显示的组件GUIStyle style = new GUIStyle();style.normal.textColor = Color.yellow;//这里只是改个字的颜色好看一点,不是必要的GUILayout.Label("this is a transform",style);}}

  保存之后回到Unity编辑器,会看到现在Transform组件的属性栏,显示了原有的UI内容,然后在最后面显示了一句新的内容。

在这里插入图片描述

  内容稍微复杂,说明一下:

1. 判断对象

  target是当前一个选中对象
  targets是在可以选择多个物体的情况下,选择的多个对象
  所谓的对象,比如这个是重写Transform组件的界面,所以target应该就是一个Transform,而targets就是一个Transform的数组。
  所以判断一下targets的长度,如果长度小于等于0,其实是没有需要显示的对象,所以直接return

2. 通过反射找到原来类型对应的编辑器类型

 var editorType = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.TransformInspector");

  由于需要显示原有的组件的Editor内容,所以需要找到原有组件的Editor类型。
  这个地方有点特别,比如Transform,它的原有Editor并不是UnityEditor.Transform,而是UnityEditor.TransformInspector。不同的组件的Editor可能类型不太一样。

3. 生成原来编辑器类型对应的实例

instance = CreateEditor(targets, editorType);

  通过Editor.CreateEditor方法可以把对象和类型传入,返回一个对应类型的Editor实例。
  这个Editor的实例就是我们能显示原组件UI的关键了。

4. 重写原编辑器对应的方法

  由于已经拿到了原组件类型对应的Editor实例,所以以下的操作都是围绕这个实例来进行的。
  比如要显示原编辑器的界面,就在重写的OnInspectorGUI方法里面调用实例的原方法

if(instance!=null)
{instance.OnInspectorGUI();
}

5. 调用原编辑器的生命周期

  关于原组件编辑器实例的其他生命周期方法,都可以通过实例来调用,使用反射的方法是这样调用:

editorType.GetMethod("OnEnable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, null);

  通过反射获取方法,然后通过Invoke来调用。

三、实用的扩展Transform例子

  上面简单的介绍了用法,接下来写一个有点实用价值的例子具体说明一下用法。
输入以下代码:

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Transform)), CanEditMultipleObjects]
public class CustomTransformEditor : Editor
{private Vector3 posVal;private Vector3 rotaVal;private Vector3 scaleVal;private Transform tr;private void OnEnable(){tr = target as Transform;posVal = tr.localPosition;rotaVal = tr.localRotation.eulerAngles;scaleVal = tr.localScale;}public override void OnInspectorGUI(){//这一行很重要,如果不先规定label的宽度,下面的layout里面的label就会显示得很宽,导致没法布局排版EditorGUIUtility.labelWidth = 15f;//获取对象的Transform属性posVal = tr.localPosition;rotaVal = tr.localRotation.eulerAngles;scaleVal = tr.localScale;//显示一个HelpBoxEditorGUILayout.HelpBox("这是一个阿赵修改过的面板",MessageType.Warning,true);//显示一个按钮,点击之后,对象的Transform全部都会重置if(GUILayout.Button("一键重置Transform")){Undo.RegisterCompleteObjectUndo(tr, "Reset Transform");posVal = Vector3.zero;rotaVal = Vector3.zero;scaleVal = Vector3.one;tr.localPosition = posVal;tr.localRotation = Quaternion.Euler(rotaVal.x, rotaVal.y, rotaVal.z);tr.localScale = scaleVal;}//显示位置属性EditorGUILayout.BeginHorizontal();if (GUILayout.Button("C", GUILayout.Width(20)))//显示一个按钮,点击之后会把对应的属性复制到剪切板{CopyValue(posVal);}EditorGUI.BeginChangeCheck();//检查属性是否被修改if (GUILayout.Button("P", GUILayout.Width(20)))//显示一个按钮,点击之后会把位置归零{posVal = Vector3.zero;}EditorGUILayout.LabelField("位置:", GUILayout.Width(40));posVal = DrawVector3(posVal);//为了不写重复代码,把显示Vector3的输入组装一个方法。用Vector3Field也行,但显示会没那么好看EditorGUILayout.EndHorizontal();if (EditorGUI.EndChangeCheck())//当输入了之后,对Transform的值进行修改{Undo.RegisterCompleteObjectUndo(tr, "Change Position");//在修改前把当前状态记录到可撤回的操作tr.localPosition = posVal;}//显示旋转属性,和显示位置雷同,所以不做额外备注EditorGUILayout.BeginHorizontal();if (GUILayout.Button("C", GUILayout.Width(20))){CopyValue(rotaVal);}EditorGUI.BeginChangeCheck();if (GUILayout.Button("P", GUILayout.Width(20))){rotaVal = Vector3.zero;}EditorGUILayout.LabelField("旋转:", GUILayout.Width(40));rotaVal = DrawVector3(rotaVal);EditorGUILayout.EndHorizontal();if (EditorGUI.EndChangeCheck()){Undo.RegisterCompleteObjectUndo(tr, "Change Rotation");tr.localRotation = Quaternion.Euler(rotaVal.x,rotaVal.y,rotaVal.z);}//显示缩放属性,和显示位置雷同,所以不做额外备注EditorGUILayout.BeginHorizontal();if (GUILayout.Button("C", GUILayout.Width(20))){CopyValue(scaleVal);}EditorGUI.BeginChangeCheck();if (GUILayout.Button("P", GUILayout.Width(20))){scaleVal = Vector3.one;}EditorGUILayout.LabelField("缩放:", GUILayout.Width(40));scaleVal = DrawVector3(scaleVal);EditorGUILayout.EndHorizontal();if (EditorGUI.EndChangeCheck()){Undo.RegisterCompleteObjectUndo(tr, "Change Scale");tr.localScale = scaleVal;}//再显示一个HelpBoxEditorGUILayout.HelpBox("下面还可以继续添加内容", MessageType.Warning, true);}/// <summary>/// 显示Vector3的输入/// </summary>/// <param name="value"></param>/// <returns></returns>private Vector3 DrawVector3(Vector3 value){GUILayoutOption opt = GUILayout.MinWidth(30f);value.x = EditorGUILayout.FloatField("X", value.x, opt);value.y = EditorGUILayout.FloatField("Y", value.y, opt);value.z = EditorGUILayout.FloatField("Z", value.z, opt);return value;}/// <summary>/// 复制值到剪切板/// </summary>/// <param name="obj"></param>private void CopyValue(object obj){GUIUtility.systemCopyBuffer = obj.ToString();}
}

  保存之后,回到Unity编辑器,会看到现在Transform组件的Inspector界面变成了这样了:
在这里插入图片描述

  代码上面已经有详细的备注,扩展了Transform的面板,可以对Transform一键重置,或者点C键复制内容到剪切板,或者点P键给对应属性重置,算是一个比较实用的小工具扩展。
需要注意一下的是

1. 控制label的宽度

EditorGUIUtility.labelWidth = 15f;

  在Inspector面板里面,label的宽度默认是很大的,如果不强制设置小一些,会发现很多时候layout自动布局会很乱。

2. 在编辑器状态检查值是否有改变

EditorGUI.BeginChangeCheck()
if (EditorGUI.EndChangeCheck())

  在BeginChangeCheck和EndChangeCheck之间的代码,如果中途有值发生了变化,就会在EndChangeCheck的时候触发,这时候就可以判断用户修改了对应的内容,就可以执行对应的修改操作了。

3. 可撤回操作

Undo.RegisterCompleteObjectUndo

  在代码里面的操作,按道理是不能通过Ctrl+Z或者菜单栏的撤销功能来撤回的。不过我们可以通过RegisterCompleteObjectUndo,把修改前的内容记录下来,就可以正常通过Ctrl+Z之类的操作来撤回了。

四、显示右键菜单

可以在组件的Inspector菜单上面鼠标右键弹出菜单出现特殊的选项,可以试试:

    [MenuItem("CONTEXT/Transform/ResetTransform")]static void ResetTransform(MenuCommand command){        Transform trans = command.context as Transform;Undo.RegisterCompleteObjectUndo(trans, "Reset Transform");trans.localPosition = Vector3.zero;trans.localRotation = Quaternion.identity;trans.localScale = Vector3.one;
}

  保存之后回到Unity编辑器,在Transform组件右键,会看到多出来自定义的选项
在这里插入图片描述

说明:

1. 显示右键菜单

[MenuItem("CONTEXT/Transform/ResetTransform")]

  MenuItem在之前介绍EditorWindow窗体时介绍过,这里指定的路径是CONTEXT/Transform,所以出现菜单的地方就会变成在Transform的Inspector右键菜单了

2. 获取需要控制的对象

Transform trans = command.context as Transform;

  由于MenuItem对应的方法都是要求Static的,所以不能通过target来获取当前选择对象的Transform。不过可以通过传入的MenuCommand 变量来获取到对应的content,就是选择对象对应的组件了。

五、 禁用某些功能

有时候如果某些条件出现时,可能我们会想禁用整个组件的Inspector菜单,试试一下代码:

    [MenuItem("CONTEXT/Transform/LockComponent")]static void LockComponent(MenuCommand command){Transform trans = command.context as Transform;Undo.RegisterCompleteObjectUndo(trans, "LockComponent");trans.hideFlags = HideFlags.NotEditable;}[MenuItem("CONTEXT/Transform/UnLockComponent")]static void UnLockComponent(MenuCommand command){Transform trans = command.context as Transform;Undo.RegisterCompleteObjectUndo(trans, "UnLockComponent");trans.hideFlags = HideFlags.None;
}

保存之后回到编辑器,可以看到Transform组件Inspector菜单右键多出2个选项
在这里插入图片描述

  如果选择LockComponent,会发现Transform的Inspector栏变成不可编辑状态了:
在这里插入图片描述

  这里是通过MenuItem菜单来触发的,也可以通过别的条件去触发锁定和解锁操作。

http://www.dtcms.com/wzjs/590307.html

相关文章:

  • 网站制作关键字排名宁波网站推广优化哪家正规
  • 专业网站建站公司上海网络seo公司
  • 常熟网站优化信誉好的企业网站开发
  • 网站建设有几种方案福州网站建设公司哪家比较好
  • 最方便在线网站开发建网站的客户
  • 如何做自己的业务网站网站优化推广是什么
  • 树莓派 做网站wordpress顺序设置别名
  • 类似携程网的网站石狮网站建设报价
  • python网站开发案例成都响应网站建设
  • 公司做网站的优势做网站必须要切图吗
  • 公司被其它人拿来做网站seo概念的理解
  • 上线了怎么做网站唐河永琚建筑公司网站
  • 我想给企业做网站怎么做建站之星怎么用
  • 网站建设万户如何做垂直网站
  • 北京建设规划许可证网站专业创业服务平台网站建设需求
  • 响应网站开发高性价比网站建设
  • 外贸通道支持asp的网站吗网站如何减少404跳转
  • 海宁网站制作好一点网站建设公司
  • 做农村电子商务的网站有哪些wordpress 可以做什么
  • 长沙做网站好的公司wordpress首页默认中文
  • 网站建站时间查询烟台网站排名系统
  • 求个没封的网站2022php mysql网站开发实例教程
  • 建设网站对公司起什么作用是什么万润 营销型网站建设
  • 深深圳市建设局网站我帮你建站
  • 南阳手机网站推广wordpress 4.8 漏洞
  • 怎样设计一个公司网站平面设计专业学校排名
  • 如何运营一个网站网站功能定制合同
  • 手机企业网站程序上海注册公司流程和费用
  • 网站做icp备案有哪些好处三亚h5网站定制开发公司
  • 建立网站的基本流程柳州市住房和城乡建设局网站首页