unity3d 刷新编辑器_unity 刷新编辑器 - CSDN
  • 在做开发的时候会写到一些编辑时脚本来方便开发,例如当我们用模板创建了脚本,但是Unity好像并不会立即刷新资源,需要点到外部然后再次点击Unity才会将新添加的资源刷新出来。刷新的方法的话就如下调用一下即可! ...

      在做开发的时候会写到一些编辑时脚本来方便开发,例如当我们用模板创建了脚本,但是Unity好像并不会立即刷新资源,需要点到外部然后再次点击Unity才会将新添加的资源刷新出来。刷新的方法的话就如下调用一下即可!

     AssetDatabase.Refresh();
    展开全文
  • Unity3d编辑器的使用

    2019-06-24 19:24:43
    第一步:双击Unity3d,点击New 第二步:填写项目信息,注意:工程必须放在空文件夹下 第三步:点击创建 第四步:工程创建完毕 文件夹介绍: Assets:放项目所有资源的文件夹 Library:文件资源库 ...

    1.创建工程

    第一步:双击Unity3d,点击New

    在这里插入图片描述

    第二步:填写项目信息,注意:工程必须放在空文件夹下

    在这里插入图片描述

    第三步:点击创建

    在这里插入图片描述

    第四步:工程创建完毕

    在这里插入图片描述

    文件夹介绍:

    Assets:放项目所有资源的文件夹

    Library:文件资源库

    ProjectSettings:项目配置文件夹

    Temp:临时文件夹,当项目关闭,Temp文件夹也会消失

    2.保存工程

    在这里插入图片描述

    或修改后关闭Unity时会提示是否保存工程

    在这里插入图片描述

    3.打开工程

    在这里插入图片描述

    或打开Unity编辑器,选择你的工程

    在这里插入图片描述

    4.改变布局及导入导出资源

    1.改变布局

    在这里插入图片描述

    2.导入资源

    注意:导入资源建议从编辑器中导入,不要直接粘贴到硬盘目录中。

    a.导入单个或多个资源

    在这里插入图片描述

    在这里插入图片描述

    b.导入资源包

    如果资源有很多,要一个一个选很麻烦,这时可以选择导入资源包

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    3.导出资源

    导出资源只能把资源导成资源包,也就是后缀为.unitypackage,如果小伙伴要单个资源就直接磁盘拷贝给他

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    5.工作区的介绍

    a.有五大视图,分别是场景视图,游戏视图,工程视图,结构视图,属性视图

    在这里插入图片描述

    b.七大菜单,分别是文件(File),编辑(Edit),资源(Assets),游戏对象(GameObject),组件(Component),窗口(Window),帮助(Help)

    在这里插入图片描述

    c.辅助工具,有工具栏,控制台,资源商店

    工具栏有以下工具:

    1.变换工具(用于场景视图)
    在这里插入图片描述

    2.变换Gizmo切换
    在这里插入图片描述
    ​ 第一个按钮是切换轴心点,第二个按钮是切换全局和局部坐标

    3.播放,暂停,逐帧按钮
    在这里插入图片描述

    4.层下拉菜单
    在这里插入图片描述
    ​ 控制哪层对象显示在场景视图

    5.布局下拉菜单
    在这里插入图片描述
    ​ 控制所有视图布局

    6.云服务,账户
    在这里插入图片描述

    控制台:

    在这里插入图片描述

    资源商店:

    在这里插入图片描述

    6.打开式例工程

    第一步:打开Unity,选择示例工程

    在这里插入图片描述
    在这里插入图片描述

    第二步:选择Car场景,双击

    在这里插入图片描述

    第三步:打开了汽车场景

    在这里插入图片描述

    7.场景视图

    场景视图,该视图主要是用于游戏的可视化制作

    鼠标聚焦到场景视图,可以进行以下操作

    1.变换工具(用于场景视图)

    在这里插入图片描述

    变换工具有手工具(Q),移动工具(W),旋转工具(E),缩放工具(R),缩放工具(T)

    手工具(Q):

    ​ 1.点击手工具按钮或按键盘Q,然后可以直接拖动场景,用于观察场景

    ​ 2.按住ALT再点击鼠标左键拖拽,则是改变摄像机的观察方向(以所选游戏对象为中心)

    ​ 3.按住ALT再点击鼠标右键拖拽,则是改变摄像机的观察距离

    ​ 4.按住Control再按鼠标的左键和单独按鼠标的右键一样功能,水平滑动改变摄像机的水平观察方向,竖直滑动改变摄像机的竖直观察方向(第一人称视角)

    ​ 5.按住鼠标中键,侧是手工具,滑动中键改变摄像机的观察距离

    移动工具(W):

    ​ 1.红色表示X轴,绿色表示Y轴,蓝色表示Z轴

    旋转工具(E):

    ​ 1.红色线圈表示围绕X轴旋转,绿色线圈表示围绕Y轴旋转,蓝色线圈表示围绕Z轴旋转

    缩放工具(R):

    ​ 1.红色表示沿X轴缩放,绿色表示沿Y轴缩放,蓝色表示沿Z轴缩放(不改变游戏对象的位置)

    缩放工具(T):

    ​ 1.以拖住的点或线的对角为基点或基线改变游戏对象的大小(会改变游戏对象的位置)

    2.辅助查看按钮

    在这里插入图片描述

    辅助查看按钮有Shaded,2D,太阳,声音,小图标,Gizmos,搜索栏

    Shaded:

    ​ 渲染模式菜单,可以查看场景的各种渲染模式

    2D:

    ​ 是否转换成2D

    太阳:

    ​ 是否开启光照

    声音:

    ​ 是否开启声音

    小图标:

    ​ 是否开启天空盒

    Gizmos:

    ​ 是否显示场景中的哪些对象

    搜索栏:

    ​ 搜索游戏对象,可以让其他非选中的游戏对象成灰色状态

    3.视图角度切换按钮

    在这里插入图片描述

    该按钮主要用于置摄像机观察角度

    是否启用该按钮

    在这里插入图片描述

    远近景切换

    在这里插入图片描述

    在这里插入图片描述

    X轴查看

    在这里插入图片描述

    Y轴查看

    在这里插入图片描述

    Z轴查看

    在这里插入图片描述

    透视,正交模式

    在persp模式下,物体在scene界面上所呈现的画面是给人一种距离摄像头近的物体显示的大,距离摄像头远的物体显示的小。

    在ISO模式下,不论物体距离摄像头远近都给人的感觉是一样大的

    在这里插入图片描述

    在这里插入图片描述

    4.场景视图的快捷键

    1.Ctrl+F聚焦到搜索栏

    2.Ctrl+A全选

    3.Ctrl+C复制

    4.Ctrl+V粘贴

    5.Ctrl+D复制粘贴

    6.Fn+退档键(mac),删除键(WIN)

    7.选中游戏对象按F键可以使游戏对象在Scene场景正中央

    8.游戏视图

    ​ 该视图是显示游戏运行时的图像,Game视图显示的内容取决于摄像机所观察到的景象

    在这里插入图片描述

    游戏视图上的操作按钮

    在这里插入图片描述

    Display 1:表示当前是哪个摄像机看到的画面

    Free Aspect:分辨率菜单

    Scale:放大视图

    Maximize on Play:是否在运行时最大化显示

    Mute audio :是否静音

    Stats :查看当前画面对应的数据

    Gizmos :是否显示Gizmos,和场景视图的Gizmos一样

    注意:运行游戏时也可以改变游戏对象等的属性,但是游戏结束都消失

    9.工程视图

    该视图罗列了工程的所有资源

    在这里插入图片描述

    1.工程视图的各块说明

    在这里插入图片描述

    从左到右分别是,创建资源,资源搜索栏,资源类型过滤,资源标签过滤,收为常用资源

    下面图为常用资源

    在这里插入图片描述

    下图为文件夹文件列表目录及显示视图

    在这里插入图片描述

    2.快捷键

    1 F定位到上次选择

    2 Tab在第一列和第二列之间切换焦点(适用两列布局)

    3 Ctrl/Cmd +F聚焦搜索栏中

    4 Ctrl/Cmd +A在列表中选择全部可见项

    5 Ctrl/Cmd +D复制选择的资源

    6 Delete带有对话框删除(Fn+Delete)

    7 Delete+Shift无对话框删除(Fn+Delete+Shift)

    8 Cmd+Backspace(退档键)(OSX)无对话框删除

    9 Enter重命名(OSX)

    10 F2重命名(WIN)

    11 Right arrow展开选择的项(树视图和搜索结果)

    12 Left arrow折叠选择的项(树视图和搜索结果)

    13 Alt+Right arrow展开列表所有项

    14 Alt+Left arrow塌陷列表所有项

    3.搜索

    1.直接输入名字

    在这里插入图片描述

    2.加t过渡条件来显示文件,如搜索场景文件(t:Scene)

    在这里插入图片描述

    3.加l标签过渡文件

    在这里插入图片描述

    4.资源类型过滤,其实和在搜索栏搜索是加t是一样的

    在这里插入图片描述

    5.标签过滤

    在这里插入图片描述

    6.收为常用资源

    在这里插入图片描述

    如果选择新建目录,如下图

    在这里插入图片描述

    4.创建资源及工程视图中的资源操作

    在这里插入图片描述

    右键出现的菜单说明:

    1 Create:创建各种资源

    ​ 1.1 Folder文件夹

    ​ 1.2 C#Script:脚本文件

    ​ 1.3 JavaScript:脚本文件

    ​ 1.4 Prefab:预制体

    ​ 1.5 Material材质

    2 Show in Explorer:在文件夹视图中显示资源

    3 Open:打开文件

    4 Delete:删除文件

    5 Import New Asset…:导入新资源

    6 Import Package:导入包

    7 Export Package…:导出包

    8 Find References In Scene:选中资源,右键点击该项,Scene视图中使用了该资源的游戏对象正常,其他显灰色,Hierarchy视图只显示使用该资源的游戏对象。

    9 Select Dependencies:资源本身和所依赖的所有资源会以蓝色高亮显示

    10 Refresh:刷新

    11 Reimport:重新导入选中资源

    12 ReimportAll:重新导入所有资源

    13 Open C# Project:打开编程文件

    10.结构视图

    显示场景中所有的游戏对象(以名字的方式显示)

    在这里插入图片描述

    1.层次结构关系

    1 父子关系

    在这里插入图片描述

    2 改变父子关系,通过拖拽方式来改变

    在这里插入图片描述

    在这里插入图片描述

    2.搜索条搜索对象

    其他对象程灰色的,突出搜索对象

    在这里插入图片描述

    3.搜索对象中的组件

    直接输入组件的全称,会显示使用了该组件的对象

    在这里插入图片描述

    4.快捷键的使用

    选中游戏对象,按上档键+F键,场景视图的游戏对象会出现在场景视图的正中央

    5.创建游戏对象

    在这里插入图片描述

    菜单说明:

    1 Create Empty:创建空的游戏对象

    2 Create Empty Child:创建空的子游戏对象

    3 3D Object:创建3D游戏对象

    4 2D Object:创建2D游戏对象

    5 Effects:特效

    6 Light:创建与光照有关游戏对象

    7 Audio:创建与声音有关游戏对象

    8 UI:创建与游戏界面UI有关游戏对象

    9 Camera:创建摄像机

    11.属性视图

    显示当前选中游戏对象的所有组件及组件的属性

    在这里插入图片描述

    1.游戏对象和组件及属性

    在这里插入图片描述

    2.游戏对象中的组件操作

    添加组件

    在这里插入图片描述

    在这里插入图片描述

    删除组件

    在这里插入图片描述

    禁止组件和恢复组件在游戏对象中的作用

    在这里插入图片描述

    3.改变游戏对象的属性

    改变组件中的数据其实就是改变游戏对象的属性

    在这里插入图片描述

    4.游戏对象中脚本组件中的属性定义及初始化

    第一步:创建脚本,取名为Maker

    在这里插入图片描述

    第二步:把脚本拖拽到游戏对象的属性视图中

    在这里插入图片描述

    在这里插入图片描述

    第三步:编辑脚本

    在这里插入图片描述

    第四步:定义一个公共的游戏对象,可以看到属性视图中显示了这个游戏对象

    在这里插入图片描述

    在这里插入图片描述

    第五步:从结构视图或工程视图中拖拽游戏对象填充到属性视图中的变量

    在这里插入图片描述

    在这里插入图片描述

    注意:

    1.脚本中定义的变量要是公共的才会在属性视图中显示

    2.拖拽的对象要和脚本中定义的变量类型一样

    12.视图之间的联合操作

    1.工程视图和场景视图的联合操作

    在这里插入图片描述

    2.工程视图和结构视图的联合操作

    在这里插入图片描述

    3.工程视图和属性视图的联合操作

    在这里插入图片描述

    4.结构视图和属性视图的联合操作

    在这里插入图片描述

    5.结构视图和场景视图的联合操作

    在这里插入图片描述

    总的来说视图之间的联合操作就用拖拽方式

    13.菜单介绍

    有七大菜单,分别是文件,编辑,资源,游戏对象,组件,窗口,帮助

    1.文件(File)

    1 New Scene:创建场景

    2 Open Scene:打开场景

    3 Save Scene:保存场景(游戏运行时不能保存场景)

    4 Save Scene as:另存场景(游戏运行时不能保存场景)

    5 New Project:创建工程

    6 Open Project:打开工程

    7 Save Project:保存工程

    8 Build Settings:建造设置

    9 Build&Run:建造并运行

    2.编辑(Edit)

    1 Undo:撤销

    2 Redo:重做

    3 Cut:剪切

    4 Copy:复制

    5 Paste:粘贴、

    6 Duplicate:复制粘贴(Ctrl+D)

    7 Delete:删除

    8 Frame Selecte:Scene视图里当前镜头移动到所选物体前

    9 Lock View to Selecte:在Hierarchy视图里选择游戏对象,Scene视图该游戏对象会变化

    10 Find:查找(Ctrl+F)

    11 Select All:选择全部(Ctrl+A)

    12 Preferences:偏好设置

    ​ 12.1设置使用哪种脚本编辑器

    ​ 12.2设置颜色

    13 Modules…:查看模块

    14 Play:播放

    15 Pause:暂停

    16 Step:逐帧

    17 Sign in:注册登记

    18 Sign out :注册离开

    19 Selection:载入和存储选择

    20 Project Settings:工程设置

    21 Netword Emulation :网络模拟

    22 Graphics Emulation :图形模拟

    23 Snap Settings :对齐设置

    3.资源(Asset)

    该菜单是创建各种资源,和工程视图右键出现的菜单一样

    1 Create:创建各种资源

    ​ 1.1 Folder文件夹

    ​ 1.2 C#Script:脚本文件

    ​ 1.3 JavaScript:脚本文件

    ​ 1.4 Prefab:预制体

    ​ 1.5 Material材质

    2 Show in Explorer:在文件夹视图中显示资源

    3 Open:打开文件

    4 Delete:删除文件

    5 Import New Asset…:导入新资源

    6 Import Package:导入包

    7 Export Package…:导出包

    8 Find References In Scene:选中资源,右键点击该项,Scene视图中使用了该资源的游戏对象正常,其他显灰色,Hierarchy视图只显示使用该资源的游戏对象。

    9 Select Dependencies:资源本身和所依赖的所有资源会以蓝色高亮显示

    10 Refresh:刷新

    11 Reimport:重新导入选中资源

    12 ReimportAll:重新导入所有资源

    13 Open C# Project:打开编程文件

    4.游戏对象(GameObject)

    和结构视图中的Create菜单一样

    1 Create Empty:创建空的游戏对象

    2 Create Empty Child:创建空的子游戏对象

    3 3D Object:创建3D游戏对象

    4 2D Object:创建2D游戏对象

    5 Effects:特效

    6 Light:创建与光照有关游戏对象

    7 Audio:创建与声音有关游戏对象

    8 UI:创建与游戏界面UI有关游戏对象

    9 Camera:创建摄像机

    5.组件(Component)

    1 Add:选择添加组件

    2 Mesh:网络模型

    3 Effect:效果

    4 Physics:物理

    5 Physics 2D:物理2D

    6 Navigation:导航

    7 Audio:声音

    8 Rendering:渲染

    9 Layout:布局

    10 Miscellaneous:其他

    11 Scipts:脚本

    12 Event:事件

    13 Netword:网络

    14 UI

    15 Image Effect:图片效果

    6.窗口(Window)

    1 Next Window:下个窗口

    2 Previous Window:上个窗口

    3 Layouts:布局

    4 Services:Unity服务

    5 Scene:场景窗口

    6 Game:游戏窗口

    7 Inspector:属性窗口

    8 Hierarchy:结构(层次)窗口

    9 Project:工程窗口

    10 Animation:动画窗口

    11 Profiler:分析器窗口(各种资源使用情况)

    12 Audio Mixer:音频混频器窗口

    13 Asset Store:资源商店窗口

    14 Version Control:版本控制窗口

    15 Animator:动画组件窗口

    16 Animator Parameter:动画参数窗口

    17 Sprite Packer:精灵状态机窗口

    18 Lighting:光照窗口

    19 Occlusion Culling:遮挡剪贴窗口

    20 Farme Debugger:框架调试窗口

    21 Navigation:导航窗口

    22 Console:控制台

    7.帮助(Help)

    1 About Unity…:关于Unity

    2 Manage License…:授权许可

    3 Unity Manual :Unity手册

    4 Scripting Reference:脚本手册

    5 Unity Connect:连接服务

    6 Unity Forum:论坛

    7 Unity Answers:问答

    8 Unity Feedback:反馈

    9 Check for Updates:检测新版本

    10 Download Beta…:下载

    11 Release Notes:发行说明

    12 Report a Bug…:报告Bug

    14.游戏对象介绍

    1 空游戏对象

    2 矩形:Cube

    3 球形:Spher

    4 胶囊:Capsule

    5 圆柱体:Cylinder

    6 平面:Plane

    7 空铅:Quad

    8 地形:Terrain

    9 树:Tree

    10 风:WindZone

    11 3D文本:3DText

    12 光:Light

    ​ 12.1方向光:Directional Light

    ​ 12.2点光源:Point Light

    ​ 12.3聚光源:Spotlight

    ​ 12.4区域光:Area Light

    13 粒子系统:Particle System

    14 摄像机:Camera

    展开全文
  • 被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做)。  刚接手这项工作时觉得没概念,没想法,不知道。后来就去看>中有关于自定义编辑器(自定义Inspector和自定义Scene或GUI)的一些例子,...

     被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做)。

        刚接手这项工作时觉得没概念,没想法,不知道。后来就去看<<Unity5.X从入门到精通>>中有关于自定义编辑器(自定义Inspector和自定义Scene或GUI)的一些例子,还包括看了 雨松的编辑器教程 和 自定义结构显示在Inspector的方法 看完之后也实战了一下就算入了门,就分析自己项目的人物对应的数据,如下图:

     

    上述数据其实很简单但是对于我这种初学者来说就有点难度,首先因为Actions 和 Frames(动作对应的帧集合) 需要有类似数组或者链表这些数据结构来存储。就去查了一些资料发现 几篇好的关于序列化和反序列化的博文 , 比如 大表哥的博文 提到 哪些数据能够序列化和反序列化 ,其中我们就可以用List<T>的结构来存储数据集合,关于为什么涉及到序列化和反序列化, 因为我们需要将一些数据保存到本地,而不是仅仅的放在内存中,再从本地取回到内存中就需要反序列化了。

      理解了上述的基础知识 ,便自己定义了特定的数据类(主要的):

    复制代码
      1     [System.Serializable]
      2     public class CharacterEditorStateData : ISerializationCallbackReceiver
      3     {
      4         public string m_animationName;
      5         public int m_totFrame;
      6         public CharacterStateType m_stateType;
      7         [HideInInspector]
      8         public CharacterStateType m_oldStateType;
      9         [HideInInspector][NonSerialized]
     10         public List<CharacterEditorAttackData> m_attackDatas = new List<CharacterEditorAttackData>();
     11         [HideInInspector][SerializeField]
     12         public List<CharacterEditorBombAttackData> m_attackBmDatas = new List<CharacterEditorBombAttackData>();
     13         [HideInInspector][SerializeField]
     14         public List<CharacterEditorNormalAttackData> m_attackNmDatas = new List<CharacterEditorNormalAttackData>();
     15         public CharacterEditorAttackData IsFrameDataExist(int frame)
     16         {
     17             foreach (CharacterEditorAttackData dt in m_attackDatas)
     18             {
     19                 if (frame == dt.m_iFrame)
     20                     return dt;
     21             }
     22             return null;
     23         }
     24 
     25         public bool AddFrameData(int newFrame)
     26         {
     27             CharacterEditorAttackData dt = CharacterEditorAttackData.CreateData(CharacterAttackType.BOMB);
     28             if (dt == null)
     29                 return false;
     30             dt.m_iFrame = newFrame;
     31             dt.m_attackType = CharacterAttackType.BOMB;
     32             this.m_attackDatas.Add(dt);
     33             return true;
     34         }
     35 
     36         public bool RemoveFrameData(int oldFrame)
     37         {
     38             CharacterEditorAttackData dt = this.IsFrameDataExist(oldFrame);
     39             if (dt == null)
     40                 return false;
     41             this.m_attackDatas.Remove(dt);
     42             return true;
     43         }
     44 
     45         public void ChangeFrameData(int index , CharacterAttackType attType)
     46         {
     47             CharacterEditorAttackData dt = this.m_attackDatas[index];
     48             int iFrame = dt.m_iFrame;
     49             if (attType != dt.m_attackType)
     50             {
     51                 dt = CharacterEditorAttackData.CreateData(attType);
     52                 dt.m_iFrame = iFrame;
     53                 dt.m_attackType = attType;
     54                 this.m_attackDatas[index] = dt;
     55             }
     56         }
     57 
     58         public int GetNewFrame()
     59         {
     60             if (m_attackDatas.Count == 0)
     61                 return 0;
     62             int frame = -1;
     63             foreach (CharacterEditorAttackData dt in m_attackDatas)
     64             {
     65                 if (frame <= dt.m_iFrame)
     66                     frame = dt.m_iFrame;
     67             }
     68             if (frame == this.m_totFrame)
     69                 return -1;
     70             return frame + 1;
     71         }
     72 
     73         public bool IsLegalFrame(int frame)
     74         {
     75             if (IsFrameDataExist(frame) != null || frame < 0 || frame > m_totFrame)
     76                 return false;
     77             return true;
     78         }
     79 
     80         public bool UpdateFramesSz()
     81         {
     82             int count = m_attackDatas.Count;
     83             for (int i = count - 1; i > m_totFrame - 1; i--)
     84             {
     85                 this.m_attackDatas.RemoveAt(i);
     86             }
     87             return true;
     88         }
     89 
     90         public void Init(CharacterStateType state)
     91         {
     92             m_animationName = "11111";
     93             m_totFrame = 12;
     94             m_stateType = state;
     95             m_oldStateType = state;
     96             m_attackDatas.Clear();
     97             m_attackBmDatas.Clear();
     98             m_attackNmDatas.Clear();
     99         }
    100 
    101         void ISerializationCallbackReceiver.OnBeforeSerialize()
    102         {
    103             if (m_attackBmDatas == null || m_attackNmDatas == null || m_attackDatas == null)
    104                 return;
    105             m_attackBmDatas.Clear();
    106             m_attackNmDatas.Clear();
    107             foreach(CharacterEditorAttackData item in m_attackDatas)
    108             {
    109                 switch(item.m_attackType)
    110                 {
    111                     case CharacterAttackType.BOMB:m_attackBmDatas.Add((CharacterEditorBombAttackData)item); break;
    112                     case CharacterAttackType.NORMAL: m_attackNmDatas.Add((CharacterEditorNormalAttackData)item);break;
    113                 }
    114             }
    115         }
    116 
    117         void ISerializationCallbackReceiver.OnAfterDeserialize()
    118         {
    119             if (m_attackBmDatas == null || m_attackNmDatas == null || m_attackDatas == null)
    120                 return;
    121             m_attackDatas.Clear();
    122             foreach (CharacterEditorAttackData item in m_attackBmDatas)
    123             {
    124                 m_attackDatas.Add(item);
    125             }
    126             foreach (CharacterEditorAttackData item in m_attackNmDatas)
    127             {
    128                 m_attackDatas.Add(item);
    129             }
    130         }
    131     }
    复制代码

      对于上述的数据结构,可能会有疑问,首先为什么需要实现 ISerializationCallbackReceiver , 和这个接口的作用;为什么需要用到三个List结构。首先,来

    理解一下 ISerializationCallbackReceiver 这个接口的作用 。 关于这个 接口介绍的博文 ,其实看完这个博文,我还是没有理解作者想讲的意思,后来自己翻阅

    了其他资料,

    void ISerializationCallbackReceiver.OnBeforeSerialize()
    
    这个接口的作用就是 序列化快开始了 , 你可以在序列化开始前做些操作 。 比如C#结构中Dict是不能够序列化的,所以在开始前可以将Dict的键和值都保存在List中 这样就达到了序列化的目的。
    
    
    void ISerializationCallbackReceiver.OnAfterDeserialize()
    
    这个接口的作用就是 反序列化结束了 , 你可以在反序列化后做一些操作 。还是上面的例子,我们可以在反序列化后从list中拿到对应的数据,把List中的键和值存储在对应的Dict中。
    
      关于两个接口的作用已经讲完了,来解决下为什么要用那么多List的原因,首先先说一下我遇到的问题,之前访问子类和存储都是通过new子类对象后,用父类的指针保存在List上,所以就会存在问题,在序列化时,序列化的是父类而不是子类,在反序列化后,就会出现数据丢失。所以需要在上述的两个接口做一个序列化前和反序列化后的数据操作,保证数据的正确。
    
      通过上述,我们可以得到可靠的序列化流程,接下来就可以就可以自定义编辑器了,编辑器代码相对简单,由于界面主要在InspectorUI上操作,就写在OnInspector上。其实在写之前对于OnInspectorUI这个函数的调用是有疑问的,后来亲自实践了一下,发现只有有UI发生更改时或者切入切出(调到另一个)显示对象都会调用,代码如下:
    复制代码
      1 using UnityEngine;
      2 using UnityEditor;
      3 using System.Collections;
      4 using TKGame;
      5 using System.Collections.Generic;
      6 using System;
      7 
      8 [CustomEditor(typeof(CharacterEditorData))]
      9 public class CharacterEditor : Editor {
     10 
     11     enum AddState { NONE, NEWSTATE, FULLSTATE };
     12     public const string TAG = "[CharacterEditor]";
     13     public CharacterEditorData m_chaEditData = null;
     14     private AddState m_addState;
     15     public void OnEnable(){
     16         m_chaEditData = target as CharacterEditorData;
     17         if (m_chaEditData == null)
     18             return;
     19         m_addState = AddState.NONE;
     20     }
     21 
     22     public override void OnInspectorGUI()
     23     { 
     24         if (m_chaEditData == null)
     25         {
     26             PrintLog("the chaEditorData is null");
     27             return;
     28         }
     29         m_chaEditData.m_id = EditorGUILayout.IntField("PlayerID: ", m_chaEditData.m_id);
     30         m_chaEditData.m_resID = EditorGUILayout.IntField("PlayerResourceID:", m_chaEditData.m_resID);
     31         m_chaEditData.m_defaultName = EditorGUILayout.TextField("PlayerDefaultName: ", m_chaEditData.m_defaultName);
     32         m_chaEditData.m_scale = EditorGUILayout.FloatField("PlayerScale:", m_chaEditData.m_scale);
     33         m_chaEditData.m_walkSpeedX = EditorGUILayout.IntField("PlayerXSpeed: ", m_chaEditData.m_walkSpeedX);
     34         m_chaEditData.m_walkSpeedY = EditorGUILayout.IntField("PlayerYSpeed:", m_chaEditData.m_walkSpeedY);
     35         m_chaEditData.m_hatred = EditorGUILayout.FloatField("PlayerHatred:", m_chaEditData.m_hatred);
     36         m_chaEditData.m_lowFireAngle = EditorGUILayout.FloatField("PlayerLowFireAngle:", m_chaEditData.m_lowFireAngle);
     37         m_chaEditData.m_higFireAngle = EditorGUILayout.FloatField("PlayerHigFireAngle:", m_chaEditData.m_higFireAngle);
     38         m_chaEditData.m_fireRange = EditorGUILayout.IntField("PlayerFireRange:", m_chaEditData.m_fireRange);
     39         m_chaEditData.m_weaponPosition = EditorGUILayout.Vector2Field("PlayerWeaponPos", m_chaEditData.m_weaponPosition);
     40         m_chaEditData.m_beAttackBoxMinX = EditorGUILayout.IntField("PlayerBAtkBoxMinX:", m_chaEditData.m_beAttackBoxMinX);
     41         m_chaEditData.m_beAttackBoxMinY = EditorGUILayout.IntField("PlayerBAtkBoxMinY:", m_chaEditData.m_beAttackBoxMinY);
     42         m_chaEditData.m_beAttackBoxMaxX = EditorGUILayout.IntField("PlayerBAtkBoxMaxX:", m_chaEditData.m_beAttackBoxMaxX);
     43         m_chaEditData.m_beAttackBoxMaxY = EditorGUILayout.IntField("PlayerBAtkBoxMaxY:", m_chaEditData.m_beAttackBoxMaxY);
     44         if (GUILayout.Button("Add New State"))
     45         {
     46             if (m_chaEditData.IsAllStateExist())
     47                 m_addState = AddState.FULLSTATE;
     48             else
     49                 m_addState = AddState.NEWSTATE;
     50         }
     51         EditorGUILayout.Space();
     52         if (m_addState == AddState.FULLSTATE)
     53             EditorGUILayout.LabelField("all states is used");
     54         else if (m_addState == AddState.NEWSTATE)
     55         {
     56             CharacterStateType newestState = m_chaEditData.GetNewestState();
     57             m_chaEditData.AddNewState(newestState);
     58             m_addState = AddState.NONE;
     59         }
     60 
     61         EditorGUILayout.Space();
     62         ///Debug.Log("yes");
     63         for (int index = 0; index < m_chaEditData.m_lsStates.Count; index++)
     64         {
     65             CharacterEditorData.CharacterEditorStateData chaState = m_chaEditData.m_lsStates[index];
     66             //Debug.Log(EditorGUILayout.EnumPopup("state:", chaState.m_newState));
     67             CharacterStateType state = (CharacterStateType)EditorGUILayout.EnumPopup("state:", chaState.m_stateType);
     68             m_chaEditData.ChangeByState(chaState, state);
     69             chaState.m_animationName = EditorGUILayout.TextField("AnimationName:", chaState.m_animationName);
     70             int totFrame = EditorGUILayout.IntField("TotalFrame:", chaState.m_totFrame);
     71             if (totFrame != chaState.m_totFrame)
     72             {
     73                 chaState.m_totFrame = totFrame;
     74                 chaState.UpdateFramesSz();
     75             }
     76             if (chaState.m_stateType == CharacterStateType.ATTACK)
     77             {
     78                 if (GUILayout.Button("Add Frame Data", GUILayout.MaxWidth(130), GUILayout.MaxHeight(20)))
     79                 {
     80                     int newFrame = chaState.GetNewFrame();
     81                     //Debug.Log(newFrame);
     82                     if (newFrame != -1)
     83                     {
     84                         chaState.AddFrameData(newFrame);
     85                     }
     86                 }
     87                 EditorGUILayout.Space();
     88                 for (int i = 0; i < chaState.m_attackDatas.Count; i++)
     89                 {
     90                     CharacterEditorData.CharacterEditorAttackData frameData = chaState.m_attackDatas[i];
     91                     int frame = EditorGUILayout.IntField("Frame:", frameData.m_iFrame);
     92                     if (chaState.IsLegalFrame(frame))
     93                     {
     94                         //Debug.Log(frame);
     95                         frameData.m_iFrame = frame;
     96                     }
     97                     CharacterAttackType attackType = (CharacterAttackType)EditorGUILayout.EnumPopup("AttackType:", frameData.m_attackType);
     98                     chaState.ChangeFrameData(i , attackType);
     99                     EditorGUILayout.Space();
    100                     if (frameData.m_attackType == CharacterAttackType.BOMB)
    101                     {
    102                         CharacterEditorData.CharacterEditorBombAttackData bomb = (CharacterEditorData.CharacterEditorBombAttackData)frameData;
    103                         bomb.m_bombCofigID = EditorGUILayout.IntField("BombConfigID:", bomb.m_bombCofigID);
    104                         bomb.m_damage = EditorGUILayout.IntField("Damge:", bomb.m_damage);
    105                         bomb.m_centerDamage = EditorGUILayout.IntField("CenterDamage:", bomb.m_centerDamage);
    106                     }
    107                     if (GUILayout.Button("Remove this Frame"))
    108                     {
    109                         chaState.RemoveFrameData(frameData.m_iFrame);
    110                     }
    111                     EditorGUILayout.Space();
    112                     EditorGUILayout.Space();
    113                 }
    114             }
    115             if (GUILayout.Button("remove this state"))
    116             {
    117                 m_chaEditData.RemoveOldState(index);
    118             }
    119             EditorGUILayout.Space();
    120             EditorGUILayout.Space();
    121         }
    122         EditorUtility.SetDirty(m_chaEditData);
    123     }
    124 
    125     private void PrintLog(string str)
    126     {
    127         Debug.Log(TAG+" "+ str);
    128     }
    129 }
    复制代码
      最后一句的SetDirty表示当前的数据对象有更改,可以通知UI刷新。
    展开全文
  • Unity3D编辑器插件开发

    2019-02-27 17:05:54
    Unity3D插件开发.png 一,菜单项相关操作 1.菜单项(MenuItem) 首先在Asset目录下新建一个Editor文件夹,然后在该目录下添加一个脚本MenuTest.cs 代码内容: using UnityEngine; using System.Collections; ...

    学习视频连接地址
    目录:

    Unity3D插件开发.png

    一,菜单项相关操作

    1.菜单项(MenuItem)

    首先在Asset目录下新建一个Editor文件夹,然后在该目录下添加一个脚本MenuTest.cs
    代码内容:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MenuTest : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
    
        /// <summary>
        /// _w 单一的快捷键 W
        /// #w shift + w
        /// %w ctrl + w
        /// &w alt + w
        /// </summary>
        [MenuItem("菜单/Test _w")]
        public static void Test1()
        {
            Debug.Log("Test_-----");
        }
    
        [MenuItem("菜单/Test# #w")]
        public static void Test2 ()
        {
            Debug.Log("Test#-----");
        }
    
        [MenuItem("菜单/Test% %w")]
        public static void Test3 ()
        {
            Debug.Log("Test%-----");
        }
    
        [MenuItem("菜单/Test& &w")]
        public static void Test4 ()
        {
            Debug.Log("Test&-----");
        }
    }
    
    

    在编辑器中选择菜单点击效果如下:

    test1.gif

    2.组件菜单(AddComponentMenu)

    就是将自己所写的脚本添加到Component菜单下面

     

    Paste_Image.png

     

    在Scripts目录下新建一个脚本组件,Test1.cs

    Paste_Image.png

     

    代码内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    [AddComponentMenu("菜单组件/MenuTest")]
    public class Test1 : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
    }
    
    

    然后就可以在Component组件中看到 菜单组件下的MenuTest组件

    test1.gif

    然后在一个GameObject Add Component下也可以看到刚才添加的菜单组件

    test1.gif

    3.上下文菜单(ContextMenu)

    就是在一个物体的组件上添加上下文菜单,即点击右键出现的菜单
    就在上文的Test1中添加一个上下文菜单
    代码内容如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    [AddComponentMenu("菜单组件/MenuTest")]
    public class Test1 : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
        [ContextMenu("ContextMenu")]
        public void Test()
        {
            Debug.Log("上下文测试");
        }
    
    }
    
    

    然后将Test1.cs这个组件添加到物体上,然后再点击右键,可以看到如下效果:

    test1.gif

    4.必要组件菜单(RequireComponent)

    必要组件是在添加改组件的同时添加其他的组件,而且是依赖于这个组件的,
    同样在上文的Test.cs中添加必要组件,
    代码内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    [RequireComponent(typeof(Rigidbody))]
    [AddComponentMenu("菜单组件/MenuTest")]
    public class Test1 : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
        [ContextMenu("ContextMenu")]
        public void Test()
        {
            Debug.Log("上下文测试");
        }
    
    }
    

    此时在一个物体上添加Test.cs组件的同时就将Rigidbody组件也添加上去了。在移除这个组件的时候要先移除Test1组件,然后才能移除Rigidbody,否则不能移除成功

    test1.gif


    二,自定义Inspector界面

    1.属性相关标识

    1)隐藏属性显示 (HideInInspector)
    2)不显示的属性(NonSerialized)
    3)关键字序列化(Serializable)
    4)序列化域(SerializeField)

    首先新建脚本文件,InspectorTest.cs 和脚本Type1.cs
    InspectorTest.cs:

    using System;
    using UnityEngine;
    using System.Collections;
    
    public class InspectorTest : MonoBehaviour
    {
    
        public int number1 = 3;
        [HideInInspector]  //单纯的隐藏属性
        public int number2 = 3;
       [NonSerialized]   //不但隐藏,防止变量序列化
        public int number3 = 3;
        [SerializeField]    //将私有变量强制显示出来
        private int number4 = 5;
        
        //[Serializable]可以让自定义的类显示在视图面板
        public Type1 mytype;
    
    }
    
    

    Type1.cs脚本内容:(Type1类已经被序列化了)

    using UnityEngine;
    using System.Collections;
    using System;
    
    [Serializable]
    public class Type1
    {
        public int val1;
    
        public float val2;
    
        public Color color;
    
    }
    

    在界面上显示的效果为:

    test1.gif

    2.自定义界面属性

    这里会用到2个类 Editor 和CustomEditor
    Editor是自定义面板的基类
    CustomEditor是对应标识的组件脚本

    案例1:自定义一个属性面板
    1)首先在Scripts文件夹下新建一个脚本文本OwnerUITest.cs
    脚本内容为:

    using System;
    using UnityEngine;
    using System.Collections;
    
    public class OwerUITest : MonoBehaviour
    {
    
        public int IntVal;
    
        public float FlatVal;
    
        public string StrVal;
    
        public Type3 mType = new Type3();
    
    
    }
    
    [Serializable]
    public class Type3
    {
        public int mInt;
    
        public int mInt2;
    }
    
    

    2)在Editor文件下新建脚本OwnerUIInspector.cs 这个类要继承Editor类,而且要在类的前面声明:[CustomEditor(typeof(OwerUITest))] 关联刚才新建的脚本
    脚本的内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    [CustomEditor(typeof(OwerUITest))]
    public class OwnerUIInspector : Editor
    {
    
        public SerializedObject mObj;
    
        public SerializedProperty mInt;
    
        public SerializedProperty mFloat;
    
        public SerializedProperty mStr;
    
        public SerializedProperty mtype;
    
    
    
    
        /// <summary>
        /// 选择当前的游戏对象时执行
        /// </summary>
        public void OnEnable()
        {
            Debug.Log("OnEnable()------");
            this.mObj = new SerializedObject(target);
            this.mInt = this.mObj.FindProperty("IntVal");
            this.mFloat = this.mObj.FindProperty("FlatVal");
            this.mStr = this.mObj.FindProperty("StrVal");
            this.mtype = this.mObj.FindProperty("mType");
        }
    
    
    
        /// <summary>
        /// 绘制
        /// </summary>
        public override void OnInspectorGUI()
        {
            Debug.Log("OnInspectorGUI()------");
            this.mObj.Update();
    
            EditorGUILayout.PropertyField(this.mInt);
            EditorGUILayout.PropertyField(this.mFloat);
            EditorGUILayout.PropertyField(this.mStr);
            //true,表示显示出类的子节点
            EditorGUILayout.PropertyField(this.mtype, true);
    
        }
    
    
        
    }
    
    
    

    3)然后将OwerUITest 挂在一个物体上,然后点击物体,可以看到绘制的效果:

    test1.gif


    案例2:实现 点击按钮中选择Transtion不同的值,属性面板绘制出不同的属性,效果如下:

    test1.gif

    1)首先在Scripts文件夹中新建一个脚本组件InspectorZiDingYi.cs,脚本代码如下:

    using UnityEngine;
    using System.Collections;
    
    public class InspectorZiDingYi : MonoBehaviour
    {
    
        public MyEnum mEnum;
    
        public int mInt;
    
        public float FlatVal;
    
        public string StrVal;
    
        public Color mColor;
    }
    
    
    public enum MyEnum
    {
        None,
        IntVal,
        FloatVal,
        StrVal,
        CocolVal
    }
    
    

    2)然后在Editor文件下新建一个类InspectorZiDingYIEditor 继承Editor,然后与InspectorZiDingYi组件关联,脚本代码如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    [CustomEditor(typeof(InspectorZiDingYi))]
    public class InspectorZiDingYIEditor : Editor
    {
    
        public SerializedObject mObject;
    
        public SerializedProperty mEnum;
    
        public SerializedProperty mInt;
    
        public SerializedProperty mFloat;
    
        public SerializedProperty mStr;
    
        public SerializedProperty mColor;
    
        public void OnEnable()
        {
            this.mObject = new SerializedObject(target);
            this.mEnum = this.mObject.FindProperty("mEnum");
            this.mInt = this.mObject.FindProperty("mInt");
            this.mFloat = this.mObject.FindProperty("FlatVal");
            this.mStr = this.mObject.FindProperty("StrVal");
            this.mColor = this.mObject.FindProperty("mColor");
    
    
        }
    
    
        public override void OnInspectorGUI()
        {
            this.mObject.Update();
    
            EditorGUILayout.PropertyField(this.mEnum);
    
            switch (this.mEnum.enumValueIndex)
            {
                case 1:
                    EditorGUILayout.PropertyField(this.mInt);
                    break;
                case 2:
                    EditorGUILayout.PropertyField(this.mFloat);
                    break;
                case 3:
                    EditorGUILayout.PropertyField(this.mStr);
                    break;
                case 4:
                    EditorGUILayout.PropertyField(this.mColor);
                    break;
            }
            
            this.mObject.ApplyModifiedProperties();
    
        }
    }
    
    

    3)然后在物体上挂上组件InspectorZiDingYi.cs 编辑器运行效果如下:

    test1.gif

    3.自定义窗口

    -----------------------------界面的启动和关闭--------------------------
    创建自定义窗口需要继承 基类:EditorWindow

    案例1:点击菜单项,弹出一个窗口
    1)首先在Editor文件夹中创建一个脚本MyTestWindow.cs,脚本内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MyTestWindow : EditorWindow 
    {
        [MenuItem("菜单/显示窗口")]
        public static void showWindow()
        {
           MyTestWindow.CreateInstance<MyTestWindow>().Show();
        }
    }
    
    

    运行效果:

    test1.gif

    若修改显示方式:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MyTestWindow : EditorWindow 
    {
        [MenuItem("菜单/显示窗口")]
        public static void showWindow()
        {
           MyTestWindow.CreateInstance<MyTestWindow>().ShowUtility();
        }
    
    }
    
    

    显示效果:

    test1.gif

    再换一种其他的显示方式:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MyTestWindow : EditorWindow 
    {
        [MenuItem("菜单/显示窗口")]
        public static void showWindow()
        {
            MyTestWindow.CreateInstance<MyTestWindow>().ShowPopup();
        }
    
    }
    
    

    运行效果:

    test1.gif

    这样显示的面板是一个空的面板,无法关闭,我们再这个面板上增加一个关闭按钮:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MyTestWindow : EditorWindow 
    {
        [MenuItem("菜单/显示窗口")]
        public static void showWindow()
        {
            MyTestWindow.CreateInstance<MyTestWindow>().ShowPopup();
        }
    
    
        public void OnGUI ()
        {
            if (GUILayout.Button("关闭"))
            {
                this.Close();
            }
        }
    
    }
    
    

    运行效果如下图所示:

    Paste_Image.png

    -----------------------------界面的相关事件机制------------------------

    界面的相关事件机制总共有9个:
    1.public void OnGUI() ->绘制窗口
    2.public void Update() ->刷新方法,100次/秒
    3.public void OnInspectorUpdate() ->刷新方法,比Update()少
    4.public void OnSelectionChange() ->选择一个对象
    5.public void OnDestroy ->销毁窗口
    6.public void OnFocus() ->获得焦点
    7.public void OnLostFocus() ->失去焦点

    8.public void OnHierarchayChange() ->Hierarchay视图窗口文件发生改变
    9.public void OnProjectChange() ->Project视图窗口文件发生改变

    案例测试:
    首先在Editor文件夹系新建脚本文件:MyWindow2,同样首先继承EditorWindow类,然后实现上述的9个事件机制函数,脚本内容如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class MyWindow2 : EditorWindow
    {
    
        [MenuItem("菜单/窗口2")]
        public static void showWindwo()
        {
            //利用单例只可以打开一个窗口
            EditorWindow.GetWindow<MyWindow2>().Show();
        }
    
        /// <summary>
        /// 绘制操作面板
        /// </summary>
        public void OnGUI()
        {
            if(GUILayout.Button("关闭"))
            {
                this.Close();
            }
        }
    
        public int index_update = 0;
    
        public int index_OnInspectorUpdate = 0;
    
        /// <summary>
        /// 刷新,每秒100次
        /// </summary>
        public void Update()
        {
            index_update ++;
           // Debug.Log("index_update:" + index_update);
        }
    
        /// <summary>
        /// 刷新方法,比Update少
        /// </summary>
        public void OnInspectorUpdate()
        {
            index_OnInspectorUpdate ++;
           // Debug.Log("index_OnInspectorUpdate:" + index_OnInspectorUpdate);
        }
        /// <summary>
        /// 视图被删除
        /// </summary>
        public void OnDestroy()
        {
            Debug.Log("视图被删除");
        }
    
        /// <summary>
        /// 选择对象发生改变
        /// </summary>
        public void OnSelectionChange()
        {
    
            //打印出场景里选择的对象
            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                Debug.Log("选择一个场景内对象:" + Selection.gameObjects[i].name);
            }
    
            //打开所有选择的对象
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                Debug.Log("选择一个对象:" + Selection.objects[i].name);
            }
    
        }
    
        public void OnFocus()
        {
            Debug.Log("OnFocus");
        }
    
        public void OnLostFocus()
        {
            Debug.Log("OnLostFocus");
        }
    
        /// <summary>
        /// HirearchyChange更改
        /// </summary>
        public void OnHierarchyChange()
        {
        
            Debug.Log("OnHierarchyChange");
           
        }
    
        /// <summary>
        /// Project 更改
        /// </summary>
        public void OnProjectChange()
        {
            Debug.Log("OnProjectChange");
        }
    
    }
    
    

    演示效果如下:

    test1.gif

    -----------------------------文本颜色字段------------------------
    输入框:

    EditorGUILayout.TextField(string) 文本输入框
    EditorGUILayout.TextArea(string); 可换行的文本输入框

    EditorGUILayout.PasswordField(string); 文本输入框
    EditorGUILayout.ColorField(Color); 颜色输入框

    1)首先在Editor文件夹下新建脚本TextColorwindow.cs,文件内容如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class TextColorwindow : EditorWindow
    {
    
        [MenuItem("菜单/文本颜色窗口")]
        public  static void showWindow()
        {
            EditorWindow.GetWindow<TextColorwindow>().Show();
        }
    
        public string mText = "please input a string";
    
        public Color mColor = Color.black;
    
    
        public void OnGUI()
        {
            this.mText = EditorGUILayout.TextField(this.mText);
            this.mText = EditorGUILayout.TextArea(this.mText);
            this.mText = EditorGUILayout.PasswordField(this.mText);
    
            this.mColor = EditorGUILayout.ColorField(this.mColor);
    
    
    
        }
    
    
    
    }
    
    

    2)运行效果如下:

    test1.gif

    -----------------------------标签字段------------------------

    标签:
    EditorGUILayout.LabelField(string) 文本标签
    EditorGUILayout.SelectableLabel(string); 选择标签
    EditorGUILayout.Space(); 空一行

    1)首先在Editor文件中新建脚本LabelWindow.cs 文件内容如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class LabelWindow : EditorWindow
    {
    
    
        public string mText = "please input a string";
    
        public Color mColor = Color.black;
    
        [MenuItem("菜单/标签窗口")]
        public static void showWindwo()
        {
            EditorWindow.GetWindow<LabelWindow>().Show();
        }
    
    
        public void OnGUI()
        {
            //文本标签
            EditorGUILayout.LabelField("输入文本");
            this.mText = EditorGUILayout.TextField(this.mText);
            //空一行
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("输入文本");
            this.mText = EditorGUILayout.TextArea(this.mText);
            //选择标签
            EditorGUILayout.SelectableLabel("输入密码");
    
            this.mText = EditorGUILayout.PasswordField(this.mText);
            EditorGUILayout.LabelField("选择颜色");
            this.mColor = EditorGUILayout.ColorField(this.mColor);
        
        }
    
    }
    
    

    运行效果如下:

    test1.gif

    -----------------------------数字输入框------------------------

    数字输入
    EditorGUILayout.IntField(this.mIntVal); 整数输入
    EditorGUILayout.FloatField(this.mFloatVal); 浮点数输入

    1)首先在Editor文件夹中加入脚本Numberwindow.cs,文件内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class Numberwindow : EditorWindow 
    {
    
        [MenuItem("菜单/数字输入窗口")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<Numberwindow>().Show();
        }
    
        public int mIntVal;
    
        public float mFloatVal;
    
    
        public void OnGUI()
        {
            EditorGUILayout.LabelField("输入整数");
            this.mIntVal = EditorGUILayout.IntField(this.mIntVal);
    
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("输入浮点数");
    
    
            this.mFloatVal = EditorGUILayout.FloatField(this.mFloatVal);
    
    
        }
    
    }
    
    

    运行效果图:

    test1.gif

    -----------------------------滚动条------------------------

    EditorGUILayout.Slider(...) 浮点数滚动条
    EditorGUILayout.IntSlider(...)整数滚动条
    EditorGUILayout.MinMaxSlider(...)

    1)首先在Editor文件夹下新建一个脚本ScrollWindow.cs,脚本内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class ScrollWindow : EditorWindow
    {
    
        [MenuItem("菜单/滚动条窗口")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<ScrollWindow>().Show();
        }
    
        public float mFloat;
    
        public int mIntVal;
    
        public float mMinVal;
        public float mMaxVal;
        
    
        public void OnGUI()
        {
    
            this.mFloat = EditorGUILayout.Slider(this.mFloat, 0, 100);
    
            this.mIntVal = EditorGUILayout.IntSlider(this.mIntVal, 0, 100);
    
            EditorGUILayout.Space();
    
    
            this.mMinVal = EditorGUILayout.Slider(this.mMinVal, 0, 100);
    
            this.mMaxVal = EditorGUILayout.Slider(this.mMaxVal, 0, 100);
    
            EditorGUILayout.MinMaxSlider(ref this.mMinVal, ref this.mMaxVal, 0 , 100);
        }
    
       
    
        
    }
    
    

    运行效如果下:

    test1.gif

    -----------------------------位置大小输入字段------------------------

    位置字段:
    EditorGUILayout.Vector2Field(string, Vector2) 二维坐标
    EditorGUILayout.Vector3Field(string,Vector3); 三维坐标
    EditorGuILayout.Vector4Field(string,Vector4);四维坐标
    EditorGUILayout.RectFiled(Rect); 矩阵
    EditorGUILayout.BoundsFiled();距离

    1)首先在Editor文件夹下新建脚本PositionWindow.cs ,脚本内容如下:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class PositionWindow : EditorWindow
    {
    
        public Vector2 mPos2;
    
        public Vector3 mPos3;
    
        public Vector4 mPos4;
    
        public Rect mRect;
    
        public Bounds mBounds;
    
    
    
    
        [MenuItem("菜单/位置输入窗口")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<PositionWindow>().Show();
        }
    
        public void OnGUI()
        {
    
            this.mPos2 = EditorGUILayout.Vector2Field("二维坐标",this.mPos2);
    
            this.mPos3 = EditorGUILayout.Vector3Field("三维坐标", this.mPos3);
    
            this.mPos4 = EditorGUILayout.Vector4Field("四维坐标", this.mPos4);
    
            EditorGUILayout.Space();
    
            EditorGUILayout.LabelField("矩阵");
            this.mRect = EditorGUILayout.RectField(this.mRect);
            
            EditorGUILayout.Space();
    
            EditorGUILayout.LabelField("距离");
            this.mBounds = EditorGUILayout.BoundsField(this.mBounds);
    
    
    
    
        }
    }
    
    

    运行效果如下:

    test1.gif

    -----------------------------选择字段------------------------

    选择字段:
    EditorGUILayout.Popup(int, string[]); 字符串选择,返回字符串数组下标
    EditorGUILayout.IntPopup(int,int[],string[]) 字符串选择,返回字符串对应下标的整形数组值
    EditorGUILayout.EnumPopup(Enum) 枚举选择,返回枚举
    1)首先在Editor文件夹下新建文件SelectWindow.cs ,脚本内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class SelectWindow : EditorWindow 
    {
    
        public  int index;
    
        public EnumTest mEnum;
    
    
        [MenuItem("菜单/选择字段测试窗口")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<SelectWindow>().Show();
        }
    
    
    
        public void OnGUI()
        {
            string[] strs = new[]
            {
                "数组下标0",
                "数组下标1",
                "数组下标2",
            };
    
            int[] intArr = new[]
            {
                1,
                2,
                3,
            };
            //字符选择,返回选择的字符数组下标
            this.index = EditorGUILayout.Popup(this.index, strs);
    
            //字符选择,返回对应的整数数组的整数值
            this.index = EditorGUILayout.IntPopup(this.index, strs,intArr);
    
            Debug.Log("index:" + index);
    
    
            //枚举选择
            this.mEnum = (EnumTest)EditorGUILayout.EnumPopup(this.mEnum);
    
    
    
        }
    
    
    }
    
    
    public enum EnumTest
    {
        Int1,
        Str2,
        Float3,
        Color4
    }
    
    

    程序运行的效果为:

    test1.gif

    -----------------------------标签、层、对象选择字段------------------------

    1)首先在Editor文件夹下新建一个脚本TagLayer.cs,脚本的内容为:

    using System;
    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class TagLayer : EditorWindow 
    {
    
        [MenuItem("菜单/标签、层、对象选择")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<TagLayer>().Show();
        }
    
        public String mTag;
    
        public int mLayer;
    
        public UnityEngine.Object mObject;
    
        public void OnGUI()
        {
            mTag = EditorGUILayout.TagField(this.mTag);
    
            mLayer = EditorGUILayout.LayerField(this.mLayer);
    
            mObject = EditorGUILayout.ObjectField(this.mObject, typeof(Camera));
        }
    
        
    }
    
    

    2)编译运行结果截图:

    test1.gif

    -----------------------------单选选择字段-----------------
    1)首先在Editor文件夹下新建ToggleWindow.cs脚本文件,脚本内容:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class ToggleWindow : EditorWindow 
    {
    
        [MenuItem("菜单/单选字段选择")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<ToggleWindow>().Show();
        }
    
        public bool mIsSelect;
    
    
    
        public void OnGUI()
        {
    
            this.mIsSelect = EditorGUILayout.Toggle("选择", this.mIsSelect);
    
    
            this.mIsSelect = EditorGUILayout.Foldout(this.mIsSelect, "折叠");
    
            if(this.mIsSelect)
            {
                EditorGUILayout.LabelField("you and me");
                EditorGUILayout.LabelField("you and me");
                EditorGUILayout.LabelField("you and me");
                EditorGUILayout.LabelField("you and me");
                EditorGUILayout.LabelField("you and me");
            }
    
        }
    
    }
    
    

    2)运行效果:

    test1.gif

    -----------------------------字段分组-----------------

    1)首先在Editor文件夹下新建脚本文件GroupWindow,脚本内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class GroupWindow : EditorWindow
    {
    
        [MenuItem("菜单/字段分组")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<GroupWindow>().Show();
    
        }
    
    
        public bool mSelect;
    
        public Vector2 mPos;
    
    
        public void OnGUI()
        {
            //滚动分组----Begin
            this.mPos = EditorGUILayout.BeginScrollView(this.mPos);
            Debug.Log("滚动分组测试位置:" + this.mPos);
    
            //Toggle分组----Begin
            this.mSelect = EditorGUILayout.BeginToggleGroup("选择分组",this.mSelect);
    
            EditorGUILayout.LabelField("1");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("2");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("3");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("4");
            EditorGUILayout.TextField("sdk");
    
            EditorGUILayout.EndToggleGroup();
            //Toggle分组-----End
    
            EditorGUILayout.Space();
    
            //水平分组----Begin
            Rect rect1 = EditorGUILayout.BeginHorizontal();
    
            EditorGUILayout.LabelField("5");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("6");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("7");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("8");
            EditorGUILayout.TextField("sdk");
            Debug.Log( "水平分组测试数据:" + rect1);
    
            EditorGUILayout.EndHorizontal();
            //水平分组----End
    
    
            //垂直分组----Bengin
            Rect rect2 = EditorGUILayout.BeginVertical();
    
            EditorGUILayout.LabelField("5");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("6");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("7");
            EditorGUILayout.TextField("sdk");
            EditorGUILayout.LabelField("8");
            EditorGUILayout.TextField("sdk");
    
            EditorGUILayout.EndVertical();
            //垂直分组----End
    
    
            //滚动分组-----End
            EditorGUILayout.EndScrollView();
    
        }
    }
    
    

    2)运行效果为:

    test1.gif

    -----------------------------其他字段-----------------
    1)首先在Editor文件夹下新建OtherWindow.cs脚本文件,脚本内容为:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    
    public class OtherFiledWindow : EditorWindow 
    {
        [MenuItem("菜单/其他字段")]
        public static void showWindow()
        {
            EditorWindow.GetWindow<OtherFiledWindow>().Show();
        }
    
        public AnimationCurve mAC = new AnimationCurve();
    
    
        public bool mSelect;
    
        public Object mObj;
    
        public void OnGUI()
        {
            //动画字段
            this.mAC = EditorGUILayout.CurveField("动画片段",this.mAC);
    
            //获得选择的物体
            this.mObj = EditorGUILayout.ObjectField(this.mObj, typeof (Transform));
    
            //将选择的物体放在面板上
            this.mSelect = EditorGUILayout.InspectorTitlebar(this.mSelect,this.mObj);
        }
    }
    
    

    2)运行效果为:

    test1.gif



    作者:young路在脚下
    链接:https://www.jianshu.com/p/183695196f02
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    展开全文
  • Unity 3d曲线编辑器

    2018-06-23 17:13:33
    参考:https://blog.csdn.net/jxw167/article/details/77717012 https://blog.csdn.net/jxw167/article/details/77732605 https://blog.csdn.net/jxw167/article/details/77836509 ...
  • 节奏游戏编辑器制谱工具个人需求实现效果思路原理代码实现节点存储类编辑器环境音乐播放APIInspector制谱GUI与交互:未来优化GIT 地址 在之前的项目中有遇到过负责开发节奏游戏的需求,查阅网上相关资料后了解了...
  • 原文链接 : ... ...今天我们来说说如何在Unity3D中为编辑器开发扩展程序。提到扩展程序,相信大家都不会陌生了。不管是Google的Chrome浏览器还是经典的FireFo
  • 环境:Unity2017.2 语言:C# 总起:今天同事在做自动化的工具,需要在脚本编译完成之后回调一个函数。我在Google上找到UnityEditor.Callbacks.DidReloadScripts这个标签可以在编译完成后,Unity自动帮忙回调。 ...
  • Unity3D编辑器的扩展提高了开发的效率,一般我们使用的是对Inspector面板和Scene视图的扩展,其实对于它们的扩展有一定的局限性。那今天就和大家讨论一下对选中对象的操作处理(Selection类)即用鼠标选中对象,就...
  • Unity3d编辑器扩展中,常常需要兼容Undo的操作即:`Cmd/Ctrl + z`。在Unity3d对应的接口`Undo.RecordObjects`可以完成这项工作,本文介绍了一种封装的方法
  • Unity3D Editor 编辑器扩展实战 Project窗口全文件夹折叠 https://blog.csdn.net/u012632851/article/details/80841606 总起: 在使用Project窗口时,总在不停地找资源和找代码过程中,将Project中的文件夹展开,...
  • 成功安装好Unity3d后会在你的安装文件夹下有两个文件夹
  • 这里需要注意的是,编辑器模式下读写文本是很方便的,但是一旦打包发布,Assets/目录都不存在了,运行时是无法读取它目录下的文本的。 using System.IO; using System.Text; using UnityEditor; using UnityEngine...
  • Unity3d自定义Editor保存编辑数据[CustomEditor(typeof(MyPlanet))]//此编辑针对MyPlanet类 public class MyEditor : Editor { SerializedProperty companyName;//MyPlanet类必须有属性companyName Serialize.....
  • 最近遇到一个需求,就是我们在做完一个场景后,美工感觉字体不好看,效果不是很好,想要换一种字体。UGUI的界面已经搭完,如果要一个一个Text寻找,工作量将是巨大。而且作为程序人员是不会容忍...using UnityEditor...
  •  Scene【场景面板】:该面板为Unity3D编辑面板;你可以将你所有的模型、灯光、以及其他材质对象拖放到该场景中。构建游戏中所能呈现景象。  Game【游戏面板】:与场景面板不同,该面板是用来渲染场景面板中...
  • 很惭愧从事游戏开发三年半才开始...第一次写拓展编辑器,做好之后超级兴奋的说,哈哈~这个工具主要是根据某类人物的AnimatorController的模板,拷贝并将当前人物的动作自动赋值的过程,避免了手动拖拽动作操作的繁...
  • 在这篇教程中你会学习如何扩展你的Unity3D编辑器,以便在你的项目中更好的使用它。你将会学习如何绘制你自己的gizmo,用代码来实现创建和删除物体,创建编辑器窗口,使用组件,并且允许用户撤销他们所作出的任何动作...
1 2 3 4 5 ... 20
收藏数 1,268
精华内容 507
关键字:

unity3d 刷新编辑器