unity3d Gizmos

示例

Gizmos用于在场景视图中绘制形状。您可以使用这些形状绘制有关您的GameObject的其他信息,例如它们具有的平截头体或检测范围。

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

例子一

本示例使用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作为第二个参数。类型应该是您要用来绘制Gizmo的类型。

绘制Gizmo的方法需要是静态的,公共的或非公共的,并且可以随意命名。第一个参数是类型,应该与作为属性中第二个参数传递的类型匹配,第二个参数是描述对象当前状态的枚举GizmoType。

if ( ( type &GizmoType.Selected) ==GizmoType.Selected) {
    Handles.DrawWireDisc( obj.transform.position, Vector3.up, obj.GetDetectionRadius() );
}

另一个区别是,要检查对象的GizmoType是什么,您需要对所需的参数和类型进行“与”检查。

结果

未选中的

示例一未选择

已选

示例一