Can you make gizmos intersect geometry?

Gizmos always draw on top. Sometimes that is handy, but often it is detrimental. For example, when trying to place an object on the ground, since there is no intersection between the gizmo and the ground, it is very hard to line it up.

Is there any way around this? There must be, so maybe my question should be "what's the easiest way to create custom gizmos that clip against the meshes?"

The shader used for the gizmos is not settable, and it doesn't perform a depth test, so you're SOL with built-in Gizmos. You'll have to create your own objects/scripts that run in the Editor. This is a good use for the "EditorOnly" tag.

Thanks to Jessy for the info about it not being possible with the built-in Gizmos. Here's my hacky work-around:

  1. I made a prefab to be the gizmo. I just used a cube scaled down nearly flat and positioned it at y=0 inside another game object. I added an alpha grid texture for bonus points.
  2. Tag the prefab "EditorOnly". Given the other steps this is probably not strictly necessary, but won't hurt.
  3. In the component that needed positioning, I did this:

    private static GameObject goGizmoPlane = null;
    private static string pathToGizmoPlane = "Assets/Gizmos/MyGizmoPlane.prefab";
    
    void OnDrawGizmosSelected()
    {
        if( Application.isEditor )
        {
            if( goGizmoPlane == null )
            {
                // create one
                GameObject prefab = Resources.LoadAssetAtPath( pathToGizmoPlane, typeof( GameObject ) ) as GameObject;
                if( !prefab )
                {
                    Debug.LogError( "Could not load " + pathToGizmoPlane );
                }
                else
                {
                    goGizmoPlane = GameObject.Instantiate( prefab ) as GameObject;
                    goGizmoPlane.hideFlags = HideFlags.HideAndDontSave;
                }
            }
            // position it
            if( goGizmoPlane.transform.position != transform.position )
                goGizmoPlane.transform.position = transform.position;
            if( goGizmoPlane.transform.rotation != transform.rotation )
                goGizmoPlane.transform.rotation = transform.rotation;
        }
    }
    
    

Presumably the hideFlags ensure it isn't saved to the scene, and it doesn't even show up in the hierarchy. It does modify the scene though, even if you just select an object with this in it; definitely not ideal, but a small price to pay for actually having stuff placed on the ground. Anyway, not the most elegant solution (and I suspect I'll think of a better way in the morning), but it seems to get the job done for now.