小玩意儿

Gizmos 用于在场景视图中绘制形状。你可以使用这些形状来绘制有关 GameObjects 的额外信息,例如它们具有的截头体或检测范围。

以下是有关如何执行此操作的两个示例

例一

此示例使用 OnDrawGizmosOnDrawGizmosSelected (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 检查。

结果

未选中的

StackOverflow 文档

StackOverflow 文档