小玩意儿
Gizmos 用于在场景视图中绘制形状。你可以使用这些形状来绘制有关 GameObjects 的额外信息,例如它们具有的截头体或检测范围。
以下是有关如何执行此操作的两个示例
例一
此示例使用 OnDrawGizmos 和 OnDrawGizmosSelected (magic)方法。
public class GizmoExample : MonoBehaviour {
public float GetDetectionRadius() {
return 12.5f;
}
public float GetFOV() {
return 25f;
}
public float GetMaxRange() {
return 6.5f;
}
public float GetMinRange() {
return 0;
}
public float GetAspect() {
return 2.5f;
}
public void OnDrawGizmos() {
var gizmoMatrix = Gizmos.matrix;
var gizmoColor = Gizmos.color;
Gizmos.matrix = Matrix4x4.TRS( transform.position, transform.rotation, transform.lossyScale );
Gizmos.color = Color.red;
Gizmos.DrawFrustum( Vector3.zero, GetFOV(), GetMaxRange(), GetMinRange(), GetAspect() );
Gizmos.matrix = gizmoMatrix;
Gizmos.color = gizmoColor;
}
public void OnDrawGizmosSelected() {
Handles.DrawWireDisc( transform.position, Vector3.up, GetDetectionRadius() );
}
}
在这个例子中,我们有两种绘制小玩意的方法,一种在对象处于活动状态时绘制(OnDrawGizmos),另一种用于在层次结构中选择对象时(OnDrawGizmosSelected)。
public void OnDrawGizmos() {
var gizmoMatrix = Gizmos.matrix;
var gizmoColor = Gizmos.color;
Gizmos.matrix = Matrix4x4.TRS( transform.position, transform.rotation, transform.lossyScale );
Gizmos.color = Color.red;
Gizmos.DrawFrustum( Vector3.zero, GetFOV(), GetMaxRange(), GetMinRange(), GetAspect() );
Gizmos.matrix = gizmoMatrix;
Gizmos.color = gizmoColor;
}
首先,我们保存 Gizmo 矩阵和颜色,因为我们将要更改它并希望在完成后将其还原为不影响任何其他 Gizmo 绘图。
接下来我们想绘制我们的对象所具有的平截头体,但是,我们需要更改 Gizmos 的矩阵,使其与位置,旋转和比例相匹配。我们还将 Gizmos 的颜色设置为红色以强调平截头体。完成后,我们可以调用 Gizmos.DrawFrustum 在场景视图中绘制平截头体。
当我们完成绘制我们想要绘制的内容时,我们重置了 Gizmos 的矩阵和颜色。
public void OnDrawGizmosSelected() {
Handles.DrawWireDisc( transform.position, Vector3.up, GetDetectionRadius() );
}
我们还想在选择 GameObject 时绘制检测范围。这是通过 Handles 类完成的,因为 Gizmos 类没有任何光盘方法。
使用这种形式的绘制小控件结果到下面显示的输出。
例二
此示例使用 DrawGizmo 属性。
public class GizmoDrawerExample {
[DrawGizmo( GizmoType.Selected | GizmoType.NonSelected, typeof( GizmoExample ) )]
public static void DrawGizmo( GizmoExample obj, GizmoType type ) {
var gizmoMatrix = Gizmos.matrix;
var gizmoColor = Gizmos.color;
Gizmos.matrix = Matrix4x4.TRS( obj.transform.position, obj.transform.rotation, obj.transform.lossyScale );
Gizmos.color = Color.red;
Gizmos.DrawFrustum( Vector3.zero, obj.GetFOV(), obj.GetMaxRange(), obj.GetMinRange(), obj.GetAspect() );
Gizmos.matrix = gizmoMatrix;
Gizmos.color = gizmoColor;
if ( ( type & GizmoType.Selected ) == GizmoType.Selected ) {
Handles.DrawWireDisc( obj.transform.position, Vector3.up, obj.GetDetectionRadius() );
}
}
}
这种方式允许你从脚本中分离 Gizmo 调用。除了两件事之外,其中大多数使用与其他示例相同的代码。
[DrawGizmo( GizmoType.Selected | GizmoType.NonSelected, typeof( GizmoExample ) )]
public static void DrawGizmo( GizmoExample obj, GizmoType type ) {
你需要使用 DrawGizmo 属性,该属性将枚举 GizmoType 作为第一个参数,将 Type 作为第二个参数。Type 应该是你要用于绘制 Gizmo 的类型。
绘制 Gizmo 的方法需要是静态的,公共的或非公共的,并且可以根据需要进行命名。第一个参数是类型,它应该与作为属性中第二个参数传递的类型匹配,第二个参数是枚举 GizmoType,它描述对象的当前状态。
if ( ( type & GizmoType.Selected ) == GizmoType.Selected ) {
Handles.DrawWireDisc( obj.transform.position, Vector3.up, obj.GetDetectionRadius() );
}
另一个区别是,为了检查对象的 GizmoType 是什么,你需要对参数和所需类型进行 AND 检查。