Unity 编辑器篇|(十)Handles (全面总结 | 建议收藏)

目录

  • 1. 前言
  • 2 参数总览
  • 3 Handles两种使用方式
    • 3.1 基于Editor类的OnSceneGUI
    • 3.2 基于EditorWindow
  • 4 Handles绘制
    • 4.1 Draw:绘制元几何体(点、线、面)
      • 4.1.1 抗锯齿: DrawAAPolyLine 、 DrawAAConvexPolygon
      • 4.1.2 绘制实线: DrawLine 、 DrawLines 、DrawPolyLine
      • 4.1.3 绘制虚线: DrawDottedLine 、 DrawDottedLines
      • 4.1.4 绘制贝塞尔曲线: DrawBezier
      • 4.1.5 绘制圆形圆盘: DrawSolidDisc 、 DrawSolidArc 、 DrawSolidRectangleWithOutline
      • 4.1.6 绘制圆弧: DrawWireDisc 、 DrawWireArc 、 DrawWireCube
      • 4.1.7 绘制 3D 纹理: DrawTexture3DVolume 、 DrawTexture3DSlice 、 DrawTexture3DSDF
    • 4.2 Handle:可视化操作数值(Vector3、Vector2、float等)
      • 4.2.1 FreeMoveHandle
      • 4.2.2 FreeRotateHandle
      • 4.2.3 PositionHandle
      • 4.2.4 RadiusHandle
      • 4.2.5 RotationHandle
      • 4.2.6 ScaleHandle
      • 4.2.7 ScaleValueHandle
    • 4.3 Caps:绘制多边形几何体(如方块,点精灵,球形,圆锥等)
      • 4.3.1 ArrowHandleCap
      • 4.3.2 CircleHandleCap
      • 4.3.3 ConeHandleCap
      • 4.3.4 CubeHandleCap
      • 4.3.5 CylinderHandleCap
      • 4.3.6 DotHandleCap
      • 4.3.7 RectangleHandleCap
    • 4.4 GUI
      • 4.4.1 Label
      • 4.4.2 Button
      • 4.4.3 ScaleSlider
      • 4.4.4 Slider
      • 4.4.5 Slider2D
    • 4.5 Camera:摄像机

1. 前言

  • Sceneview(场景视图中)自定义3D GUI 控制器与绘制的类
  • Handles是Unity在场景视图中,用于操控物体的3D控制器,已内置许多操作GUI,比如我们熟悉的基于Transform对位置、缩放、旋转坐标的操作工具。当然,我们使用自定义的Editor,定义自己的Handle GUI操作显示也是可能的。这种GUIs将会非常有用于程序化生成的场景内容、“不可见”的子对象与组。比如路径点与坐标标记点。

2 参数总览

静态函数描述
ArrowHandleCap绘制一个类似于移动工具所用箭头的箭头。
BeginGUI在 3D 手柄 GUI 内开始一个 2D GUI 块。
Button创建一个 3D 按钮。
CircleHandleCap绘制一个圆形手柄。将此手柄传递给 handle 函数。
ClearCamera清除摄像机。
ConeHandleCap绘制一个锥体手柄。将此手柄传递给 handle 函数。
CubeHandleCap绘制一个立方体手柄。将此手柄传递给 handle 函数。
CylinderHandleCap绘制一个圆柱体手柄。将此手柄传递给 handle 函数。
Disc创建一个可使用鼠标拖动的 3D 圆盘。
DotHandleCap绘制一个圆点手柄。将此手柄传递给 handle 函数。
DrawAAConvexPolygon绘制使用点数组指定的抗锯齿凸多边形。
DrawAAPolyLine绘制使用点数组和宽度指定的抗锯齿线。
DrawBezier绘制通过给定切线的起点和终点的纹理化贝塞尔曲线。
DrawCamera在矩形内绘制一个摄像机。
DrawDottedLine绘制一条从 p1p2 的虚线。
DrawDottedLines从 p1 到 p2 绘制一条线。
DrawGizmos在给定相机的后处理之前或之后绘制 GizmoSubset。
DrawLine绘制一系列虚线段。
DrawLines绘制一系列线段。
DrawOutline在场景视图中围绕指定游戏对象绘制轮廓。
DrawPolyLine绘制一条穿过 points 列表的线。
DrawSelectionFrame在指定位置和旋转处创建一个具有指定大小的正方形。
DrawSolidArc在 3D 空间中绘制一个圆扇形(饼图)。
DrawSolidDisc在 3D 空间中绘制一个实心平面圆盘。
DrawSolidRectangleWithOutline在 3D 空间中绘制一个实心轮廓矩形。
DrawTexture3DSDF在 3D 空间中使用有符号距离场渲染模式绘制 3D 纹理。
DrawTexture3DSlice在 3D 空间中使用切片渲染模式绘制 3D 纹理。
DrawTexture3DVolume在 3D 空间中使用体积渲染模式绘制 3D 纹理。
DrawWireArc在 3D 空间中绘制圆弧。
DrawWireCube使用 center 和 size 绘制一个线框盒体。
DrawWireDisc在 3D 空间中绘制扁平圆盘的轮廓。
EndGUI结束一个 2D GUI 块并返回到 3D 手柄 GUI。
FreeMoveHandle创建一个不受约束的移动手柄。
FreeRotateHandle创建一个不受约束的旋转手柄。
GetMainGameViewSize获取主游戏视图的宽度和高度。
Label为位于 3D 空间中的手柄创建文本标签。
MakeBezierPoints返回表示贝塞尔曲线的点数组。
PositionHandle创建一个位置手柄。
RadiusHandle创建一个场景视图半径手柄。
RectangleHandleCap绘制一个矩形手柄。将此手柄传递给 handle 函数。
RotationHandle创建一个场景视图旋转手柄。
ScaleHandle创建一个场景视图缩放手柄。
ScaleSlider创建一个定向缩放滑动条。
ScaleValueHandle创建一个缩放单个浮点的 3D 手柄。
SetCamera设置当前摄像机,以便所有手柄和辅助图标均使用相应设置进行绘制。
ShouldRenderGizmos确定是否绘制 Gizmos。
Slider创建一个沿着一个轴移动的 3D 滑动条。
Slider2D创建一个沿两个轴定义的平面移动的 3D 滑动条。
SnapToGrid将每个 Transform.position 或 Vector3 舍入为 EditorSnapSettings.gridSize 的最接近倍数。
SnapValue如果对齐为 active,则将 value 四舍五入到 snap 的最接近倍数。注意,snap 只能为正数。
SphereHandleCap绘制一个球体手柄。将此手柄传递给 handle 函数。
TransformHandle创建变换手柄。

3 Handles两种使用方式

3.1 基于Editor类的OnSceneGUI

  • 在继承自Editor的类中,可以定义【OnSceneGUI()】
  • 这样当此Edtior在活跃状态时(比如一个Inspector面板展开),在【OnSceneGUI()】方法内的内容将根据SceneView的刷新而调用,触发对应逻辑。
using UnityEngine;public class HandlesScript : MonoBehaviour
{}
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Debug.Log("在Editor OnSceneGUI中 调用....");}
}
  • 在【Hierarchy】中新建空对象,挂载脚本,点击对象在【Inspector】中显示【HandlesScript】信息,就可以看见信息打印:
    1
    注:下文实例代码都是在OnSceneGUI中编写调用。

3.2 基于EditorWindow

  • 有些时候,我们更想在一个Window中进行数据编辑与操作,但是EditorWindow可没有OnSceneGUI,怎么办呢?这时候,需要手动对SceneView的刷新事件进行注册了。
using UnityEngine;
using UnityEditor;
public class HandlesWindow : EditorWindow
{public static HandlesWindow m_mainWindow;[MenuItem("MyWindows/HandlesWindow")]public static void OpenWindow() //打开窗口{m_mainWindow = EditorWindow.GetWindow<HandlesWindow>();m_mainWindow.Show();}private void OnEnable() {SceneView.duringSceneGui += OnSceneGUI; //对SceneView的刷新事件进行注册}private void OnDisable() {SceneView.duringSceneGui -= OnSceneGUI; //对SceneView的刷新事件取消注册}private void OnSceneGUI(SceneView sceneView) //自定义刷新事件的委托方法{Debug.Log("在 Window OnSceneGUI中 调用...."); //具体逻辑}
}

4 Handles绘制

4.1 Draw:绘制元几何体(点、线、面)

4.1.1 抗锯齿: DrawAAPolyLine 、 DrawAAConvexPolygon

  • DrawAAPolyLine: 绘制使用点数组和宽度指定的抗锯齿线。
    • 注意:如果您希望拥有恒定屏幕大小的手柄,请使用 HandleUtility.GetHandleSize。
    • 注意:要获得抗锯齿效果,请使用 1x2 像素(一个透明的白色像素和一个不透明的白色像素)的纹理。
  • DrawAAConvexPolygon: 绘制使用点数组指定的抗锯齿凸多边形。

DrawAAPolyLine

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawAAPolyLine(new Vector3[] { Vector3.zero, Vector3.one, new Vector3(2, 0, 2) });}
}

1

DrawAAConvexPolygon

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawAAConvexPolygon(new Vector3[] { Vector3.zero, Vector3.one, new Vector3(2, 0, 2) });}
}

2

4.1.2 绘制实线: DrawLine 、 DrawLines 、DrawPolyLine

  • DrawLine:从 p1 到 p2 绘制一条线。
  • DrawLines:绘制一系列线段。
  • DrawPolyLine:绘制一条穿过 points 列表的线。

DrawLine

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawLine(Vector3.zero, Vector3.one);}
}

2
DrawLines

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] lineSegments = new Vector3[4]{//线段一Vector3.zero, Vector3.one,//线段二Vector3.one, new Vector3(2,0,2)};private void OnSceneGUI(){ Handles.DrawLines(lineSegments);}
}

2
DrawPolyLine

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] positions = new Vector3[4]{Vector3.zero, Vector3.one, new Vector3(2,0,2), Vector3.zero};private void OnSceneGUI(){Handles.DrawPolyLine(positions);}
}

3

4.1.3 绘制虚线: DrawDottedLine 、 DrawDottedLines

  • DrawDottedLine:绘制一条从 p1p2 的虚线。
  • DrawDottedLines:绘制一系列虚线段。

DrawDottedLine

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize = 4.0f;private void OnSceneGUI(){Handles.DrawDottedLine(Vector3.zero, Vector3.one, screenSpaceSize);}
}

1
DrawDottedLines

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] lineSegments = new Vector3[4]{//线段一Vector3.zero, Vector3.one,//线段二Vector3.one, new Vector3(2,0,2)};//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize = 4.0f;private void OnSceneGUI(){Handles.DrawDottedLines(lineSegments, screenSpaceSize);}
}

1

4.1.4 绘制贝塞尔曲线: DrawBezier

  • DrawBezier:绘制通过给定切线的起点和终点的纹理化贝塞尔曲线。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{public Vector3 startPoint = new Vector3(-0.0f, 0.0f, 0.0f);//贝塞尔曲线的起点。public Vector3 endPoint = new Vector3(-2.0f, 1.0f, 0.0f);//贝塞尔曲线的终点。public Vector3 startTangent = new Vector3(-2.0f, 2.0f, 0.0f);//贝塞尔曲线的起始切线。public Vector3 endTangent = Vector3.zero;//贝塞尔曲线的终点切线。private void OnSceneGUI(){Handles.DrawBezier(startPoint, endPoint, startTangent, endTangent, Color.red, null, 2f);}
}

2

4.1.5 绘制圆形圆盘: DrawSolidDisc 、 DrawSolidArc 、 DrawSolidRectangleWithOutline

  • DrawSolidDisc:在 3D 空间中绘制一个实心平面圆盘。
  • DrawSolidArc:在 3D 空间中绘制一个圆扇形(饼图)。
  • **DrawSolidRectangleWithOutline **:在 3D 空间中绘制一个实心轮廓矩形。

DrawSolidDisc

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.DrawSolidDisc(center, normal, radius);}
}

1
DrawSolidArc

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即扇形的起点。Vector3 from = Vector3.left;//扇形的角度(以度为单位)。float angle = 180;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.DrawSolidArc(center, normal, from, angle, radius);}
}

2
DrawSolidRectangleWithOutline

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){HandlesScript t = target as HandlesScript;Vector3 pos = t.transform.position;Vector3[] verts = new Vector3[]{new Vector3(pos.x -2, pos.y, pos.z -2),new Vector3(pos.x -2, pos.y, pos.z + 2),new Vector3(pos.x + 2, pos.y, pos.z + 2),new Vector3(pos.x +2, pos.y, pos.z -2)};Handles.DrawSolidRectangleWithOutline(verts, new Color(0.5f, 0.5f, 0.5f, 0.1f), new Color(0, 0, 0, 1));}
}

3

4.1.6 绘制圆弧: DrawWireDisc 、 DrawWireArc 、 DrawWireCube

  • DrawWireDisc:在 3D 空间中绘制扁平圆盘的轮廓。
  • DrawWireArc:在 3D 空间中绘制圆弧。
  • DrawWireCube:使用 center 和 size 绘制一个线框盒体。

DrawWireDisc

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//条粗细(零粗细绘制单像素线条)。float thickness = 3;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireDisc(center, normal, radius, thickness);}
}

1
DrawWireArc

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即圆弧的起点。Vector3 from = Vector3.left;//条粗细(零粗细绘制单像素线条)。float thickness = 3;//圆的半径。float angle = 180;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireArc(center, normal, from, angle, radius, thickness);}
}

2
DrawWireCube

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3 center = Vector3.zero;Vector3 size = Vector3.one;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireCube(center, size);}
}

3

4.1.7 绘制 3D 纹理: DrawTexture3DVolume 、 DrawTexture3DSlice 、 DrawTexture3DSDF

  • DrawTexture3DVolume:在 3D 空间中使用体积渲染模式绘制 3D 纹理。
  • DrawTexture3DSlice:在 3D 空间中使用切片渲染模式绘制 3D 纹理。
  • DrawTexture3DSDF:在 3D 空间中使用有符号距离场渲染模式绘制 3D 纹理。

DrawTexture3DVolume

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//非线性体积不透明度修改器。使用它来控制可视化的不透明度。有效值为 0-1(含)。//值为 1 时完全不透明,值为 0 时完全透明。默认值为 1。float opacity = 0;//设置每个纹理像素计数的样本。值越高,渲染质量越高。默认值为 1。float qualityModifier = 0;//设置要使用的纹理过滤模式。FilterMode filterMode = FilterMode.Trilinear;//启用颜色渐变可视化。bool useColorRamp = true;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DVolume(texture, opacity, qualityModifier, filterMode,useColorRamp, useColorRamp ? customColorRamp : null);}
}

DrawTexture3DSlice

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//纹理采样平面的位置。public Vector3 slicePositions;//设置要使用的纹理过滤模式。FilterMode filterMode = FilterMode.Trilinear;//启用颜色渐变可视化。bool useColorRamp = true;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DSlice(texture, slicePositions, filterMode,useColorRamp, useColorRamp ? customColorRamp : null);}
}

DrawTexture3DSDF

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//与光线步长相乘的数字。光线步长是两个相邻像素之间的距离。默认值为 1。float stepScale;//渲染表面时的像素强度。当该值为正数时,Unity 将扩展渲染表面。//当该值为负数时,Unity 会将空的空间渲染为表面,并将表面渲染为空的空间。默认值为 0。float surfaceOffset;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DSDF(texture, stepScale, surfaceOffset, customColorRamp);}
}

4.2 Handle:可视化操作数值(Vector3、Vector2、float等)

4.2.1 FreeMoveHandle

  • FreeMoveHandle: 创建一个不受约束的移动手柄。
 protected virtual void OnSceneGUI(){HandlesScript example = (HandlesScript)target;float size = HandleUtility.GetHandleSize(example.targetPosition) * 0.5f;Vector3 snap = Vector3.one * 0.5f;EditorGUI.BeginChangeCheck();Vector3 newTargetPosition = Handles.FreeMoveHandle(example.targetPosition, Quaternion.identity, size, snap, Handles.RectangleHandleCap);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(example, "Change Look At Target Position");example.targetPosition = newTargetPosition;example.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 targetPosition { get { return m_TargetPosition; } set { m_TargetPosition = value; } }[SerializeField]private Vector3 m_TargetPosition = new Vector3(1f, 0f, 2f);public virtual void Update(){transform.LookAt(m_TargetPosition);}
}

1

4.2.2 FreeRotateHandle

  • FreeRotateHandle: 创建一个不受约束的旋转手柄。
 public void OnSceneGUI(){HandlesScript t = (target as HandlesScript);EditorGUI.BeginChangeCheck();Quaternion rot = Handles.FreeRotateHandle(0, t.rot, Vector3.zero, 2);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Free Rotate");t.rot = rot;t.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Quaternion rot = Quaternion.identity;public void Update(){transform.rotation = rot;}
}

1

4.2.3 PositionHandle

  • PositionHandle: 创建一个位置手柄。
 protected virtual void OnSceneGUI(){HandlesScript example = (HandlesScript)target;EditorGUI.BeginChangeCheck();Vector3 newTargetPosition = Handles.PositionHandle(example.targetPosition, Quaternion.identity);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(example, "Change Look At Target Position");example.targetPosition = newTargetPosition;example.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 targetPosition { get { return m_TargetPosition; } set { m_TargetPosition = value; } }[SerializeField]private Vector3 m_TargetPosition = new Vector3(1f, 0f, 2f);public virtual void Update(){transform.LookAt(m_TargetPosition);}
}

1

4.2.4 RadiusHandle

  • RadiusHandle: 创建一个场景视图半径手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public float areaOfEffect = 1;
}
public void OnSceneGUI()
{HandlesScript t = (target as HandlesScript);EditorGUI.BeginChangeCheck();float areaOfEffect = Handles.RadiusHandle(Quaternion.identity, t.transform.position, t.areaOfEffect);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Changed Area Of Effect");t.areaOfEffect = areaOfEffect;}
}

1

4.2.5 RotationHandle

  • RotationHandle: 创建一个场景视图旋转手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Quaternion rot = Quaternion.identity;public void Update(){transform.rotation = rot;}
}
 public void OnSceneGUI(){HandlesScript t = (target as HandlesScript );EditorGUI.BeginChangeCheck();Quaternion rot = Handles.RotationHandle(t.rot, Vector3.zero);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Rotated RotateAt Point");t.rot = rot;t.Update();}}

1

4.2.6 ScaleHandle

  • ScaleHandle:创建一个场景视图缩放手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 scale = Vector3.one;public void Update(){transform.localScale = scale;}
}
 public void OnSceneGUI(){HandlesScript t = (target as HandlesScript );EditorGUI.BeginChangeCheck();Vector3 scale = Handles.ScaleHandle(t.scale, Vector3.zero, Quaternion.identity, 1);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Scaled ScaleAt Point");t.scale = scale;t.Update();}}

1

4.2.7 ScaleValueHandle

  • ScaleValueHandle:创建一个缩放单个浮点的 3D 手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{[SerializeField]private Color m_Color1 = Color.red;[SerializeField]private Color m_Color2 = Color.green;public float amount { get { return m_Amount; } set { m_Amount = Mathf.Clamp01(value); } }[SerializeField, Range(0f, 1f)]private float m_Amount = 1f;private Light m_Light;protected virtual void OnEnable(){m_Light = GetComponent<Light>();}public virtual void Update(){m_Light.color = Color.Lerp(m_Color1, m_Color2, m_Amount);}
}
 protected virtual void OnSceneGUI(){LightColorLerp colorLerp = (LightColorLerp)target;float size = HandleUtility.GetHandleSize(colorLerp.transform.position) * 5f;float snap = 0.1f;EditorGUI.BeginChangeCheck();float newAmount = Handles.ScaleValueHandle(colorLerp.amount, colorLerp.transform.position, Quaternion.identity, size, Handles.ArrowHandleCap, snap);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(colorLerp, "Change Light Color Interpolation");colorLerp.amount = newAmount;colorLerp.Update();}}

1

4.3 Caps:绘制多边形几何体(如方块,点精灵,球形,圆锥等)

4.3.1 ArrowHandleCap

  • ArrowHandleCap:绘制一个类似于移动工具所用箭头的箭头。
using System.Drawing.Drawing2D;
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.2 CircleHandleCap

  • CircleHandleCap:绘制一个圆形手柄。将此手柄传递给 handle 函数。
using System.Drawing.Drawing2D;
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.3 ConeHandleCap

  • ConeHandleCap:绘制一个锥体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.4 CubeHandleCap

  • CubeHandleCap:绘制一个立方体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.5 CylinderHandleCap

  • CylinderHandleCap:绘制一个圆柱体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.6 DotHandleCap

  • DotHandleCap:绘制一个圆点手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.3.7 RectangleHandleCap

  • RectangleHandleCap:绘制一个矩形手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}

1

4.4 GUI

4.4.1 Label

  • Label:为位于 3D 空间中的手柄创建文本标签。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Handles.color = Color.red;Handles.Label(Vector3.zero,"测试Label");}
}

1

4.4.2 Button

  • Button:创建一个 3D 按钮。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){if (Handles.Button(Vector3.zero, Quaternion.identity, 1, 2, Handles.RectangleHandleCap))Debug.Log("The button was pressed!");}
}

1

4.4.3 ScaleSlider

  • ScaleSlider:创建一个定向缩放滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){float scale = Handles.ScaleSlider(1, Vector3.zero, Vector3.right, Quaternion.identity, 1, 0.5f);}
}

1

4.4.4 Slider

  • Slider:创建一个沿着一个轴移动的 3D 滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Vector3 newTargetPosition = Handles.Slider(Vector3.zero, Vector3.right, 1, Handles.ConeHandleCap, 0.5f);}
}

1

4.4.5 Slider2D

  • Slider2D:创建一个沿两个轴定义的平面移动的 3D 滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Vector3 newTargetPosition = Handles.Slider2D(Vector3.zero, Vector3.up, Vector3.right, Vector3.forward, 1, Handles.CircleHandleCap, 0.5f);}
}

1

4.5 Camera:摄像机

  • DrawCamera:在矩形内绘制一个摄像机。此函数还将 Camera.current 设置为 camera。它将摄像机的 pixelRect 设置为 position,但采用屏幕坐标。如果您使用高 DPI 显示屏,这可能会与 GUI 坐标有所不同。
  • ClearCamera:清除摄像机。Handle 类使用的摄像机将在使用前被清除
  • SnapValue:如果对齐为 active,则将 value 四舍五入到 snap 的最接近倍数。注意,snap 只能为正数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序:非递归的归并排序

目录 递归与非递归的思想对比&#xff1a; 递归&#xff1a; 非递归&#xff1a; 代码解析&#xff1a; 完整代码&#xff1a; 递归与非递归的思想对比&#xff1a; 递归&#xff1a; 在之前的归并排序&#xff0c;它的核心思想是通过不断的分割&#xff0c;从一个数组变…

HTML 表单

文章目录 表单什么是表单GET和POST两种提交方式有什么不同?表单元素表单项外文本单行文本输入框单行文本密码框单选框复选框下拉列表框上传文件隐藏域填写邮箱填写电话填写数字填写日期进度条多行文本输入框提交按钮取消按钮 用户注册案例 表单 什么是表单 form:表单元素 此…

机器人强化学习-双机械臂

概要 基于 robosuite 库&#xff0c;进行双臂机器人学习训练 环境测试 下面展示下分别控制两个机械手随机运动的画面&#xff1a; 双臂显示场景如下&#xff1a;双臂调用代码如下&#xff1a; import numpy as np import robosuite as suite import robomimic import rob…

【vue2】状态管理之 Vuex

文章目录 一、介绍1、概念 2、工作示意图3、安装4、简单示例 二、核心1、State1.1 组件中获取 Vuex 的状态1.2 mapState 辅助函数1.3 对象展开运算符 2、Getter2.1 基本使用2.2 通过属性访问2.3 通过方法访问2.4 mapGetters 辅助函数 3、Mutation3.1 定义 mutation3.2 commit 提…

多线程排序(java版)

&#x1f4d1;前言 本文主要是【排序】——多线程排序的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&#x…

Docker-02-镜像项目部署

Docker-02-镜像&项目部署 文章目录 Docker-02-镜像&项目部署一、镜像①&#xff1a;镜像结构②&#xff1a;Dockerfile③&#xff1a;构建镜像01&#xff1a;构建02&#xff1a;查看镜像列表03&#xff1a;运行镜像 二、网络①&#xff1a;容器的网络IP地址②&#xff…

数据中心负载测试的常用工具和技术有哪些?

数据中心负载测试是评估系统在高负载下的性能和稳定性的重要手段。通过模拟大量用户并发访问&#xff0c;可以检测系统的瓶颈和潜在问题&#xff0c;为优化系统性能提供依据。以下是一些常用的数据中心负载测试工具和技术&#xff1a; Apache JMeter&#xff1a;JMeter是一个开…

《世界之外》提前开测,网易打响国乙大战

1月18日&#xff0c;国乙市场迎来了一场大战。 原定于1月26日开服的网易新乙游《世界之外》&#xff0c;突然宣布在1月18日进行不删档、不限量测试&#xff0c;从某种意义上来说&#xff0c;其实就等同于提前公测。 而同一天开服的还有叠纸的全新3D乙游《恋与深空》&#xff…

基于R语言的NDVI的Sen-MK趋势检验

本实验拟分析艾比湖地区2010年至2020年间的NDVI数据&#xff0c;数据从MODIS遥感影像中提取的NDVI值&#xff0c;在GEE遥感云平台上将影像数据下载下来。代码如下&#xff1a; import ee import geemap geemap.set_proxy(port7890)# 设置全局网络代理 Map geemap.Map()# 指定…

2024年宜昌市中级职称评定条件能力业绩要求是什么?

1.参与完成 4 项中型以上工程建筑项目的勘察、设计&#xff0c;并通过审查 2.参与完成标准&#xff08;含国家标准、行业标准、地方标准、团体、标准&#xff09;、省级标准设计&#xff0c;参与工法、管理办法、规定、规程细则的编写&#xff0c;并正式发布实施 3.参与完成新技…

文件上传时报413错误

原因&#xff1a;nginx上传文件大小有限制&#xff0c;如果不配置nginx上传文件大小&#xff0c;则上传时会出现 413 (Request Entity Too Large) 异常&#xff08;请求实体过大&#xff09; 解决方案&#xff1a;1、打开nginx主配置文件nginx.conf&#xff0c;找到http{ }&…

go语言(三)----函数

1、函数单变量返回 package mainimport "fmt"func fool(a string,b int) int {fmt.Println("a ",a)fmt.Println("b ",b)c : 100return c}func main() {c : fool("abc",555)fmt.Println("c ",c)}2、函数多变量返回 pack…

表的增删改查CURD(基础)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 新增&#xff08;Create&#xff09; 全列插入 指定列…

高校教务系统登录页面JS分析——河北地质大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密码加…

鹅厂有料有趣的程序员交流圈重磅官宣!加入立享福利

号外&#xff01;腾讯云开发者社区重磅上线海量社群&#xff0c;覆盖开发者技术学习交流、工作成长、生活分享等多元场景需求&#xff0c;用最新鲜的内容&#xff0c;最好玩的互动&#xff0c;与你一起共创最有料有趣的技术人交流圈&#xff5e; 最有料有趣交流圈在这里你可以畅…

Git学习笔记(第5章):Git团队协作机制

目录 5.1 团队内协作 5.2 跨团队协作 Git进行版本控制都是在本地库操作的。若想使用Git进行团队协作&#xff0c;就必须借助代码托管中心。 5.1 团队内协作 问题引入&#xff1a;成员1&#xff08;大佬&#xff09;利用Git在宿主机上初始化本地库&#xff0c;完成代码的整体…

thinkphp+vue+mysql大学生心理健康测试分析系统g4i4o

学生心里测试分析系统由管理员和学生、教师交互构成。学生对于本系统的使用&#xff0c;学生可以通过系统注册、登录&#xff0c;修改个人信息&#xff0c;查看交流区、心理测试卷、新闻资讯等功能。 教师对于本系统的使用&#xff0c;教师可以通过系统注册、登录&#xff0c;修…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷6

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

人工智能之卷积神经网络(CNN)

前言&#xff1a;今天我们重点探讨一下卷积神经网络(CNN)算法。 _ 20世纪60年代&#xff0c;Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性&#xff0c;继而提出了卷积神经网络CNN&#xff08;Convo…

大模型学习与实践笔记(九)

一、LMDeply方式部署 使用 LMDeploy 以本地对话方式部署 InternLM-Chat-7B 模型&#xff0c;生成 300 字的小故事 2.api 方式部署 运行 结果&#xff1a; 显存占用&#xff1a; 二、报错与解决方案 在使用命令&#xff0c;对lmdeploy 进行源码安装是时&#xff0c;报错 1.源…