Unity中的Gizmos 功能是用于在场景视图中绘制辅助图形或图标的工具,帮助开发者在编辑模式下直观调试和可视化游戏对象的位置、范围、方向等信息。
一.定义概述
Gizomsd 概述
Gizoms是Unity提供的一个API,或者叫做一个工具类,包含一系列静态方法。
既然提到Gizoms不得不提到OnDrawGizmosxxx 系列函数。命名相近需要区分一下。
OnDrawGizmosxxx 概述
包含OnDrawGizmos( )和OnDrawGizmoselected( ),它们是Unity的MonoBehaviour中的生命周期函数,作为绘制Gizmos的入口点,开发者需要再此方法内调用Gizmos的绘制函数,定义需要的图形

OnDrawGizmosxxx
是定义何时绘制 和如何触发 的入口方法,而Gizmos
是提供具体绘制能力的工具类。
二.Gizmos的核心功能
1.调试可视化
无需运行游戏,直接在场景视图中显示自定义图形。
常用函数
DrawLine:绘制直线
DrawSphere:绘制球体
DrawFrustum:绘制视椎体
DrawWireCube:绘制空心立方
属性控制
Gizmos.color:后续绘制颜色
Gizmos.matrix:基于对象坐标系绘制
示例代码
cs
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.matrix=transform.localToWorldMatrix;
Gizmos.DrawCube(Vector3.forward,Vector3.one*0.5f);
Gizmos.matrix = Matrix4x4.identity;
}
示例效果
基于物体自身坐标系的forward方向渲染立方体

开关控制
场景视图中的Gizmos菜单可全局启用或禁用Gizmos显示

下拉Gizmos菜单中且可以控制所有目标脚本内及其他的Gizmos绘制显示

2.图标标记
DrawIcon()可绘制icon或Tex,便于显示定位。
示例代码:
cs
private void OnDrawGizmos()
{
Gizmos.DrawIcon(transform.position, "tree.jpg");
}
DrawIcon( )第二个输入参数string name 表示位于Assets/Gizmos路径下的资源名称。

经过多次实验,我认为需要带上资源的图片格式后缀(如jpg,png)。
实验结果:

三.Gizmos的相关应用
1.逻辑/碰撞检测可视化
在制作像平台游戏中的敌人AI时,我们经常需要多重射线和碰撞盒进行检测判断,此时可视化检测范围是较为重要的可提高效率的手段。
例如我们需要绘制一条竖直的射线来检测玩家是否到达地面。
或者敌人需要对面前一定距离或区域进行检测,查看是否看到了玩家进入追击状态等。
这里拿我以前的一个小项目举例:
敌人身上的白色圆形可视化区域是来检测是否可以进行攻击,白色的短直线用来可视化检测前方是否是地面边缘。

2.自定义图形绘制(仅场景视图)
我分别在四个空物体上挂载测试脚本,并在场景中绘制了四个空心立方体。
示例代码
cs
//每帧在Scene内绘制
void OnDrawGizmos()
{
Gizmos.color = Color.cyan;//绘制青色空心立方体
Gizmos.DrawWireCube(transform.position, Vector3.one * 0.5f);
}
实验结果

接着我们来实现一个小功能:在场景视图内,当我们选择一个游戏物体时,渲染一条自原点与该游戏物体的连线。
这里我写一个专门用于编辑器下的功能脚本,在Editor文件夹下新建脚本。

示例代码
cs
using UnityEditor;
using UnityEngine;
public class GizmosEditor
{
//挂载目标脚本的对象被选中且激活状态下绘制
[DrawGizmo(GizmoType.Active | GizmoType.Selected)]
static void CustomOnDrawGizmos(GizmosText traget, GizmoType type)
{
//物体被选中时将会显示自身至原点的一条连线
Gizmos.color = Color.blue;
Gizmos.DrawLine(Vector3.zero, traget.transform.position);
}
}
实验效果

接着我想加工一下这四个立方体,当我选中一个立方体时,该立方体会更复杂一些。
另外需要注意的是:
OnDrawGizmos()//在Scene视图内每帧绘制
OnDrawGizmosSelected() //选中该脚本挂载对象时每帧在Scene内绘制
为减少不必要的性能消耗,我们可以使用一个bool变量来决定如何渲染。
这里我采用了一个bool变量来控制立方体是否在选中时绘制图形。
示例代码
cs
using UnityEngine;
public class GizmosText : MonoBehaviour
{
[Header("仅在被选中时绘制")]
public bool isOnSelectedCanDraw = true;
//每帧在Scene内绘制
void OnDrawGizmos()
{
Gizmos.color = Color.cyan;
Gizmos.DrawWireCube(transform.position, Vector3.one * 0.5f);
if (!isOnSelectedCanDraw)
DrawMyCube();
}
//选中该脚本挂载对象时每帧在Scene内绘制
//只有选中该物体才会绘制
private void OnDrawGizmosSelected()
{
if (isOnSelectedCanDraw)
DrawMyCube();
}
void DrawMyCube()
{
Gizmos.color = Color.red;
Gizmos.DrawCube(transform.position, Vector3.one * 0.4f);//绘制一个小实心立方体
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, 0.6f);//绘制一个空心黄球体
}
}
实验结果

本篇完~