前几天项目需要就做了个类似于Collider EditCollider的功能

下面是我做的效果

基础代码如下:

  1. public class ExportCFGInputWindow : EditorWindow
  2. {
  3. public static ExportCFGInputWindow instance;
  4. Vector3 dot1, dot2, dot3, dot4;
  5.  
  6. void OnEnable() {
  7. instance = this;
  8. SceneView.duringSceneGui -= this.OnSceneGUI;
  9. SceneView.duringSceneGui += this.OnSceneGUI;
  10. dot1 = new Vector3(0, 0, 0);
  11. dot2 = new Vector3(0, 0, 1);
  12. dot3 = new Vector3(1, 0, 1);
  13. dot4 = new Vector3(1, 0, 0);
  14. mid1Cor = Color.green;
  15. mid2Cor = Color.green;
  16. mid3Cor = Color.green;
  17. mid4Cor = Color.green;
  18. }
  19. void OnDisable() {
  20. instance = null;
  21. SceneView.duringSceneGui -= this.OnSceneGUI;
  22. }
  23.  
  24. void OnSceneGUI(SceneView sceneView)
  25. {
  26. Handles.color = Color.green;
  27. Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1);
  28.  
  29. }
  30.  
  31. }

效果如图

下面是我踩的坑

    先不管先把小绿点画于是我在OnSceneGui方法里面插入了如下代码

  1. void OnSceneGUI(SceneView sceneView)
  2. {
  3. Handles.color = Color.green;
  4. Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1);
  5.  
  6. Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  7.  
  8.       //0.005f * sceneView.size 的作用是让小绿点无论你把场景放大或者缩小都是一样大。
  1. Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  2. Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  3. Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  4.  
  5. }

    这是画完绿点的样子

    虽然有了绿点但是没法控制于是我写了个方法来监听鼠标,这个方法在OnSceneGUI函数中调用。具体思路是:绿点的位置知道,只要监听鼠标在绿点下按下然后移动鼠标,我控制绿点两端的点跟着鼠标移动就可以完成了。

    但是!万事都怕但是。出现了一个令我头大的问题:鼠标左键的EventType.MouseUp事件我监听不到(这个问题求好心人帮忙解释一下。)导致我无法停止对相应点的控制,当然鼠标中键和鼠标右键没有问题,但是鼠标中键和鼠标右键会在编辑器下有其他操作。于是我放弃了这个思路。(这里代码就不上了)

    既然鼠标不行被逼无奈我就使用了键盘控制的方式 ,思路如下:

      4键控制上图最左边的小绿点,8键控制最上面的小绿点,6键控制最右面的小绿点,2键控制最下面的小绿点。+键表示该点向外伸,-键表示该点向外内缩。

    下面是代码

  1. int ExportDir = 0;//移动方向
    void CheckKey()//这个方法在OnSeneGui函数中调用
  2. {
  3. Event e = Event.current;
  4. if (e.type == EventType.KeyDown)
  5. {
  6.  
  7. if (e.keyCode == KeyCode.Keypad4)
  8. {
  9. ExportDir = 4;
  10. mid1Cor = Color.red;
  11. mid2Cor = Color.green;
  12. mid3Cor = Color.green;
  13. mid4Cor = Color.green;
  14. }
  15. if (e.keyCode == KeyCode.Keypad6)
  16. {
  17. ExportDir = 6;
  18. mid1Cor = Color.green;
  19. mid2Cor = Color.green;
  20. mid3Cor = Color.red;
  21. mid4Cor = Color.green;
  22. }
  23. if (e.keyCode == KeyCode.Keypad2)
  24. {
  25. ExportDir = 2;
  26. mid1Cor = Color.green;
  27. mid2Cor = Color.green;
  28. mid3Cor = Color.green;
  29. mid4Cor = Color.red;
  30. }
  31. if (e.keyCode == KeyCode.Keypad8)
  32. {
  33. ExportDir = 8;
  34. mid1Cor = Color.green;
  35. mid2Cor = Color.red;
  36. mid3Cor = Color.green;
  37. mid4Cor = Color.green;
  38. }
  39. if (e.keyCode == KeyCode.KeypadPlus)
  40. {
  41. //ExportDir = 4;
  42. Plus(ExportDir);
  43. }
  44. if (e.keyCode == KeyCode.KeypadMinus)
  45. {
  46. //ExportDir = 4;
  47. Minus(ExportDir);
  48. }
  49. }
  50.  
  51. }
      float EditorSpeed = 0.05f;
  52. void Plus(int dir)
  53. {
  54.  
  55. if (dir == 4)
  56. {
  57. dot1.x -= EditorSpeed;
  58. dot2.x -= EditorSpeed;
  59. }
  60. else if (dir == 6)
  61. {
  62. dot3.x += EditorSpeed;
  63. dot4.x += EditorSpeed;
  64. }
  65. else if (dir == 2)
  66. {
  67. dot1.z -= EditorSpeed;
  68. dot4.z -= EditorSpeed;
  69. }
  70. else if (dir == 8)
  71. {
  72. dot2.z += EditorSpeed;
  73. dot3.z += EditorSpeed;
  74. }
  75. else
  76. {
  77. return;
  78. }
  79. }
  80. void Minus(int dir)
  81. {
  82.  
  83. if (dir == 4)
  84. {
  85. dot1.x += EditorSpeed;
  86. dot2.x += EditorSpeed;
  87. }
  88. else if (dir == 6)
  89. {
  90. dot3.x -= EditorSpeed;
  91. dot4.x -= EditorSpeed;
  92. }
  93. else if (dir == 2)
  94. {
  95. dot1.z += EditorSpeed;
  96. dot4.z += EditorSpeed;
  97. }
  98. else if (dir == 8)
  99. {
  100. dot2.z -= EditorSpeed;
  101. dot3.z -= EditorSpeed;
  102. }
  103. else
  104. {
  105. return;
  106. }
  107. }

      这样一来我先按下数字键4在按下+键最左边的点就会向左移动了

      为了显示清楚我还对小绿点显示颜色左了相应的处理,当选择哪个点做动作时它就会变红,代码如下

  1. Color mid1Cor = Color.green;
  2. Color mid2Cor = Color.green;
  3. Color mid3Cor = Color.green;
  4. Color mid4Cor = Color.green;
  5. void OnSceneGUI(SceneView sceneView)
  6. {
  7. Handles.color = Color.green;
  8. Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1);
  9.  
  10. Handles.color = mid1Cor;
  11. Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  12. Handles.color = mid2Cor;
  13. Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  14. Handles.color = mid3Cor;
  15. Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  16. Handles.color = mid4Cor;
  17. Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  18. CheckKey();
  19.  
  20. }

    效果如下:

  这个功能也能勉强满足需求,暂时就这样了。

  后来有一天,我发现有人这样用

  1. Handles.FreeMoveHandle(target.pos,Quaternion.identity,2.0,Vector3.zero,Handles.DrawRectangle);

  Handles类的FreeMoveHandle函数我马上查了一下API发现

  1. public static Vector3 FreeMoveHandle(Vector3 position, Quaternion rotation, float size, Vector3 snap, DrawCapFunction capFunc);

  最后一个参数是个委托。我一下子就明白改怎么弄了。代码如下

  1. void OnSceneGUI(SceneView sceneView)
  2. {
  3. Handles.color = Color.green;
  4. Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1);
  5.  
  6. float m1px = Handles.FreeMoveHandle(new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x;
  7. dot1 = new Vector3(m1px, 0, dot1.z);
  8. dot2 = new Vector3(m1px, 0, dot2.z);
  9.  
  10. float m2px = Handles.FreeMoveHandle(new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z;
  11. dot2 = new Vector3(dot2.x, 0, m2px);
  12. dot3 = new Vector3(dot3.x, 0, m2px);
  13.  
  14. float m3px = Handles.FreeMoveHandle(new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x;
  15. dot3 = new Vector3(m3px, 0, dot3.z);
  16. dot4 = new Vector3(m3px, 0, dot4.z);
  17.  
  18. float m4px = Handles.FreeMoveHandle(new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z;
  19. dot4 = new Vector3(dot4.x, 0, m4px);
  20. dot1 = new Vector3(dot1.x, 0, m4px);
  21.  
  22. }

  这样就达到了我想要的鼠标控制小绿点的效果。但是键盘控制的代码我也保留了,因为我觉得这是个教训,而且在有时候键盘控制也蛮方便的。

完整代码如下:

  1. public class ExportCFGInputWindow : EditorWindow
  2. {
  3. public static ExportCFGInputWindow instance;
  4. Vector3 dot1, dot2, dot3, dot4;
  5. Color mid1Cor, mid2Cor, mid3Cor, mid4Cor;
  6. int ExportDir = 0;
  7. float EditorSpeed = 0.05f;
  8. void OnEnable() {
  9. instance = this;
  10. SceneView.duringSceneGui -= this.OnSceneGUI;
  11. SceneView.duringSceneGui += this.OnSceneGUI;
  12. dot1 = new Vector3(0, 0, 0);
  13. dot2 = new Vector3(0, 0, 1);
  14. dot3 = new Vector3(1, 0, 1);
  15. dot4 = new Vector3(1, 0, 0);
  16. mid1Cor = Color.green;
  17. mid2Cor = Color.green;
  18. mid3Cor = Color.green;
  19. mid4Cor = Color.green;
  20. }
  21. void OnDisable() {
  22. instance = null;
  23. SceneView.duringSceneGui -= this.OnSceneGUI;
  24. }
  25.  
  26. Vector3 m1, m2, m3, m4;
  27. void OnSceneGUI(SceneView sceneView)
  28. {
  29. Handles.color = Color.green;
  30. Handles.DrawAAPolyLine(2, dot1, dot2, dot3, dot4, dot1);
  31.  
  32. #region 鼠标控制
  33. float m1px = Handles.FreeMoveHandle(new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x;
  34. dot1 = new Vector3(m1px, 0, dot1.z);
  35. dot2 = new Vector3(m1px, 0, dot2.z);
  36.  
  37. float m2px = Handles.FreeMoveHandle(new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z;
  38. dot2 = new Vector3(dot2.x, 0, m2px);
  39. dot3 = new Vector3(dot3.x, 0, m2px);
  40.  
  41. float m3px = Handles.FreeMoveHandle(new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).x;
  42. dot3 = new Vector3(m3px, 0, dot3.z);
  43. dot4 = new Vector3(m3px, 0, dot4.z);
  44.  
  45. float m4px = Handles.FreeMoveHandle(new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, Vector3.zero, Handles.DotCap).z;
  46. dot4 = new Vector3(dot4.x, 0, m4px);
  47. dot1 = new Vector3(dot1.x, 0, m4px);
  48. #endregion
  49.  
  50. #region 键盘控制
  51. Handles.color = mid1Cor;
  52. Handles.DotHandleCap(0, new Vector3((dot1.x + dot2.x) * 0.5f, 0, (dot1.z + dot2.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  53. Handles.color = mid2Cor;
  54. Handles.DotHandleCap(0, new Vector3((dot2.x + dot3.x) * 0.5f, 0, (dot2.z + dot3.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  55. Handles.color = mid3Cor;
  56. Handles.DotHandleCap(0, new Vector3((dot3.x + dot4.x) * 0.5f, 0, (dot3.z + dot4.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  57. Handles.color = mid4Cor;
  58. Handles.DotHandleCap(0, new Vector3((dot4.x + dot1.x) * 0.5f, 0, (dot4.z + dot1.z) * 0.5f), Quaternion.identity, 0.005f * sceneView.size, EventType.Repaint);
  59. CheckKey();
  60. #endregion
  61.  
  62. }
  63.  
  64. void CheckKey()
  65. {
  66. Event e = Event.current;
  67. if (e.type == EventType.KeyDown)
  68. {
  69.  
  70. if (e.keyCode == KeyCode.Keypad4)
  71. {
  72. ExportDir = 4;
  73. mid1Cor = Color.red;
  74. mid2Cor = Color.green;
  75. mid3Cor = Color.green;
  76. mid4Cor = Color.green;
  77. }
  78. if (e.keyCode == KeyCode.Keypad6)
  79. {
  80. ExportDir = 6;
  81. mid1Cor = Color.green;
  82. mid2Cor = Color.green;
  83. mid3Cor = Color.red;
  84. mid4Cor = Color.green;
  85. }
  86. if (e.keyCode == KeyCode.Keypad2)
  87. {
  88. ExportDir = 2;
  89. mid1Cor = Color.green;
  90. mid2Cor = Color.green;
  91. mid3Cor = Color.green;
  92. mid4Cor = Color.red;
  93. }
  94. if (e.keyCode == KeyCode.Keypad8)
  95. {
  96. ExportDir = 8;
  97. mid1Cor = Color.green;
  98. mid2Cor = Color.red;
  99. mid3Cor = Color.green;
  100. mid4Cor = Color.green;
  101. }
  102. if (e.keyCode == KeyCode.KeypadPlus)
  103. {
  104. //ExportDir = 4;
  105. Plus(ExportDir);
  106. }
  107. if (e.keyCode == KeyCode.KeypadMinus)
  108. {
  109. //ExportDir = 4;
  110. Minus(ExportDir);
  111. }
  112. }
  113.  
  114. }
  115. void Plus(int dir)
  116. {
  117.  
  118. if (dir == 4)
  119. {
  120. dot1.x -= EditorSpeed;
  121. dot2.x -= EditorSpeed;
  122. }
  123. else if (dir == 6)
  124. {
  125. dot3.x += EditorSpeed;
  126. dot4.x += EditorSpeed;
  127. }
  128. else if (dir == 2)
  129. {
  130. dot1.z -= EditorSpeed;
  131. dot4.z -= EditorSpeed;
  132. }
  133. else if (dir == 8)
  134. {
  135. dot2.z += EditorSpeed;
  136. dot3.z += EditorSpeed;
  137. }
  138. else
  139. {
  140. return;
  141. }
  142. }
  143. void Minus(int dir)
  144. {
  145.  
  146. if (dir == 4)
  147. {
  148. dot1.x += EditorSpeed;
  149. dot2.x += EditorSpeed;
  150. }
  151. else if (dir == 6)
  152. {
  153. dot3.x -= EditorSpeed;
  154. dot4.x -= EditorSpeed;
  155. }
  156. else if (dir == 2)
  157. {
  158. dot1.z += EditorSpeed;
  159. dot4.z += EditorSpeed;
  160. }
  161. else if (dir == 8)
  162. {
  163. dot2.z -= EditorSpeed;
  164. dot3.z -= EditorSpeed;
  165. }
  166. else
  167. {
  168. return;
  169. }
  170. }
  171. private void OnGUI()
  172. {
  173. GUILayout.BeginVertical();
  174. //标签
  175. GUILayout.BeginHorizontal();
  176. GUILayout.Box("输入相应的参数", TitleBoxStyle(), GUILayout.Height(60),GUILayout.ExpandWidth(true));
  177. GUILayout.EndHorizontal();
  178. GUILayout.Space(10);
  179.  
  180. GUILayout.BeginHorizontal();
  181. GUIStyle boxStyle = new GUIStyle();
  182. boxStyle.alignment = TextAnchor.MiddleCenter;
  183. GUILayout.Box("当前移动速度"+ EditorSpeed, boxStyle, GUILayout.Height(30), GUILayout.Width(80));
  184. GUILayout.Space(10);
  185. EditorSpeed = GUILayout.HorizontalSlider(EditorSpeed, 0.01f, 1);
  186. GUILayout.EndHorizontal();
  187.  
  188. GUILayout.EndVertical();
  189. }
  190.  
  191. }

  希望这次的分享对大家有点收获,不好的地方希望大家能帮我指出。

Unity 编辑器开发SceneView GUI控制的更多相关文章

  1. 喵的Unity游戏开发之路 - 玩家控制下的球的滑动

  2. Unity编辑器 - 编辑器控制特效播放

    编辑器控制特效播放 Unity的动画编辑器不能预览粒子系统的播放,为了方便预览特效,设想制作一个预览特效的工具,通常一个特效有三种组件: - Animation - Animator - Partic ...

  3. 2017年Unity游戏开发视频教程(入门到精通)

    本文是我发布的一个Unity游戏开发的学习目录,以后我会持续发布一系列的游戏开发教程,都会更新在这个页面上,适合人群有下面的几种: 想要做独立游戏的人 想要找游戏开发相关工作的人 对游戏开发感兴趣的人 ...

  4. Unity编辑器 - 输入控件聚焦问题

    Unity编辑器整理 - 输入控件聚焦问题 EditorGUI的输入控件在聚焦后,如果在其他地方改变值,聚焦的框不会更新,而且无法取消聚焦,如下图: 在代码中取消控件的聚焦 取消聚焦的"时机 ...

  5. 全新的Unity跨平台开发 IDE JetBrains Rider 2019.2 x64特别版下载

    Rider 基于 JetBrains 的平台,JetBrains 的平台很受那些使用 IntelliJ IDEA 的 Java 开发者和使用 WebStorm 的 JavaScript 开发者的欢迎. ...

  6. 喵的Unity游戏开发之路 - 互动环境(有影响的运动)

    如图片.视频或代码格式等显示异常,请查看原文: https://mp.weixin.qq.com/s/Sv0FOxZCAHHUQPjT8rUeNw 很多童鞋没有系统的Unity3D游戏开发基础,也不知 ...

  7. unity 编辑器扩展简单入门

    unity 编辑器扩展简单入门 通过使用编辑器扩展,我们可以对一些机械的操作实现自动化,而不用使用额外的环境,将工具与开发环境融为一体:并且,编辑器扩展也提供GUI库,来实现可视化操作:编辑器扩展甚至 ...

  8. 定制你的Unity编辑器

    Unity的编辑器可以通过写脚本进行界面定制,包括添加功能菜单,今天写游戏Demo用到了记录一下. 为Unity添加子菜单 示例程序 [AddComponentMenu("Defend Ho ...

  9. Mobile Prototype Dev Res Collection(Unity原型开发资源储备)

    资源储备 本文针对mobile原型开发阶段的资源收集 在做移动端的开发时,当有灵感想做些东西时,若是此时缺少美术资源和可用的脚本,此刻会有些纠结,今天在Assets Store上Mark了一些移动端开 ...

随机推荐

  1. GitHub进阶之利用Git远程仓库篇

    #在上一篇文章,相信大家对GitHub已经有了一个基础的理解 接下来我们来学习一下如何利用git来远程仓库 一,git是什么 git:一个免费的开源版本控制软件 用途:利用Git管理GitHub上的代 ...

  2. Activiti服务任务(serviceTask)

    Activiti服务任务(serviceTask) 作者:Jesai 都有一段沉默的时间,等待厚积薄发 应用场景: 当客户有这么一个需求:下一个任务我需要自动执行一些操作,并且这个节点不需要任何的人工 ...

  3. Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name

    目前有发现的两种情况 第一种:是在继承jpa的时候检查实体类@id和@Entity引进的包是否是 import javax.persistence.Id imprt javax.persistence ...

  4. 高通量计算框架HTCondor(四)——案例准备

    目录 1. 正文 1.1. 任务划分 1.2. 任务程序 2. 相关 1. 正文 1.1. 任务划分 使用高通量计算第一步就是要针对密集运算任务做任务划分.将一个海量的.耗时的.耗资源的任务划分成合适 ...

  5. pandas时间序列常用操作

    目录 一.时间序列是什么 二.时间序列的选取 三.时间序列的生成 四.时间序列的偏移量 五.时间前移或后移 五.时区处理 六.时期及算术运算 七.频率转换 一.时间序列是什么 时间序列在多个时间点观察 ...

  6. 双指针,BFS与图论(一)

    (一)双指针 1.日志统计 小明维护着一个程序员论坛.现在他收集了一份”点赞”日志,日志共有 N 行. 其中每一行的格式是: ts id 表示在 ts 时刻编号 id 的帖子收到一个”赞”. 现在小明 ...

  7. Python中类属性和实例属性的区别

    在Python中经常会混淆类属性和实例属性的概念,今天专门记录一下个人理解以免日后忘记. 看下面的例子: class Tencent(): i = 10 # 此处i为类属性 def __init__( ...

  8. python,读取txt的方法和应用

    1.读取txt内的百度盘地址,循环保存到百度云中(直接访问下方地址) https://www.cnblogs.com/becks/p/11409467.html 2.读取txt内参数,循环执行查询,读 ...

  9. NodeJS+axios上传图片

    前端js部分 changeEvent (e) { ------ //change事件方法 let oFile = e.target.files[0] ------ //获取文件对象 let param ...

  10. Prometheus学习笔记之教程推荐

    最近学习K8S和基于容器的监控,发现了如下的教程质量不错,记录下来以备参考 K8S最佳实战(包括了K8S的Prometheus监控和EFK日志搜集) https://jimmysong.io/kube ...