# TerrainPaintToolWithOverlays<T>

> Base class for Terrain painting tools, which inherit from Editor Tools.

## Definition

* **Type:** Class
* **Namespace:** [UnityEditor.TerrainTools](/engine/6000.6/script-reference/unityeditor/terraintools.md)
* **Assembly:** UnityEditor
* **Inherits from:** [TerrainPaintToolWithOverlaysBase](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase.md)

```csharp
public abstract class TerrainPaintToolWithOverlays<T> : TerrainPaintToolWithOverlaysBase where T : TerrainPaintToolWithOverlays<T>
```

## Remarks

Derive from this class to implement your own terrain painting tools, which also appear in the Terrain Tools overlay.

## Examples

```csharp
using UnityEngine;
using UnityEditor;
using UnityEditor.TerrainTools;

class CustomTerrainToolWithOverlays : TerrainPaintToolWithOverlays<CustomTerrainToolWithOverlays>
{
    private float m_BrushRotation;

    // Return true for this property to show the brush selector overlay
    public override bool HasBrushMask => true;

    // Return true for this property to show the tool settings overlay
    public override bool HasToolSettings => true;

    // Return true for this property to display the brush attributes overlay
    public override bool HasBrushAttributes => true;

    // File names of the light theme icons - prepending d_ to the file name generates dark theme variants.
    // public override string OnIcon => "Assets/Icon_on.png";
    // public override string OffIcon => "Assets/Icon_off.png";

    // The toolbar category the icon appears under
     public override TerrainCategory Category => TerrainCategory.CustomBrushes;

    // Where in the icon list the icon appears
    public override int IconIndex => 100;

    // Name of the Terrain Tool. This appears in the tool UI
    public override string GetName()
    {
        return "Examples/Basic Custom Terrain Tool";
    }

    // Description for the Terrain Tool. This appears in the tool UI
    public override string GetDescription()
    {
        return "This Terrain Tool shows how to add custom UI to a tool and paint height.";
    }

    // Override this function to add UI elements to the inspector
    public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext)
    {
        EditorGUILayout.HelpBox("In Terrain Inspector", MessageType.None); 
        editContext.ShowBrushesGUI(5, BrushGUIEditFlags.All);
        m_BrushRotation = EditorGUILayout.Slider("Rotation", m_BrushRotation, 0, 360);
    }

    // Override this function to add UI elements to the tool settings overlay 
    public override void OnToolSettingsGUI(Terrain terrain, IOnInspectorGUI editContext)
    {
        EditorGUILayout.HelpBox("In Overlays", MessageType.None); 
        m_BrushRotation = EditorGUILayout.Slider("Rotation", m_BrushRotation, 0, 360);
    }

    // Ease of use function for rendering modified Terrain Texture data into a PaintContext. Both OnRenderBrushPreview and OnPaint use this.
    private void RenderIntoPaintContext(UnityEngine.TerrainTools.PaintContext paintContext, Texture brushTexture, float brushOpacity, UnityEngine.TerrainTools.BrushTransform brushXform)
    {
        // Get the built-in painting Material reference
        Material mat = UnityEngine.TerrainTools.TerrainPaintUtility.GetBuiltinPaintMaterial();
        // Bind the current brush texture
        mat.SetTexture("_BrushTex", brushTexture);
        // Bind the tool-specific shader properties
        var opacity = Event.current.control ? -brushOpacity : brushOpacity;
        mat.SetVector("_BrushParams", new Vector4(opacity, 0.0f, 0.0f, 0.0f));
        // Set up the material for reading from/writing into the PaintContext texture data. This step is necessary to set up the correct shader properties for appropriately transforming UVs and sampling textures within the shader
        UnityEngine.TerrainTools.TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
        // Render into the PaintContext's destinationRenderTexture using the built-in painting Material. The ID for the Raise/Lower pass is 0
        Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);
    }

    // Render Tool previews in the Scene view
    public override void OnRenderBrushPreview(Terrain terrain, IOnSceneGUI editContext)
    {
        // Don't render preview if this isn't a Repaint
        if (Event.current.type != EventType.Repaint) return;

        // Only do the rest if user mouse hits valid terrain
        if (!editContext.hitValidTerrain) return;

        // Get the current BrushTransform under the mouse position relative to the Terrain
        UnityEngine.TerrainTools.BrushTransform brushXform = UnityEngine.TerrainTools.TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.raycastHit.textureCoord, editContext.brushSize, m_BrushRotation);
        // Get the PaintContext for the current BrushTransform. This has a sourceRenderTexture from which to read existing Terrain texture data.
        UnityEngine.TerrainTools.PaintContext paintContext = UnityEngine.TerrainTools.TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);
        // Get the built-in Material for rendering Brush Previews
        Material previewMaterial = TerrainPaintUtilityEditor.GetDefaultBrushPreviewMaterial();
        // Render the brush preview for the sourceRenderTexture. This shows up as a projected brush mesh rendered on top of the Terrain
        TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainBrushPreviewMode.SourceRenderTexture, editContext.brushTexture, brushXform, previewMaterial, 0);
        // Render changes into the PaintContext destinationRenderTexture
        RenderIntoPaintContext(paintContext, editContext.brushTexture, editContext.brushStrength, brushXform);
        // Restore old render target
        RenderTexture.active = paintContext.oldRenderTexture;
        // Bind the sourceRenderTexture to the preview Material. This is used to compute deltas in height
        previewMaterial.SetTexture("_HeightmapOrig", paintContext.sourceRenderTexture);
        // Render a procedural mesh displaying the delta/displacement in height from the source Terrain texture data. When you modify Terrain height, this shows how much the next paint operation alters the Terrain height
        TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainBrushPreviewMode.DestinationRenderTexture, editContext.brushTexture, brushXform, previewMaterial, 1);
        // Cleanup resources
        UnityEngine.TerrainTools.TerrainPaintUtility.ReleaseContextResources(paintContext);
    }

    // Perform painting operations that modify the Terrain texture data
    public override bool OnPaint(Terrain terrain, IOnPaint editContext)
    {
        // Get the current BrushTransform under the mouse position relative to the Terrain
        UnityEngine.TerrainTools.BrushTransform brushXform = UnityEngine.TerrainTools.TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, m_BrushRotation);
        // Get the PaintContext for the current BrushTransform. This has a sourceRenderTexture from which to read existing Terrain texture data
        // and a destinationRenderTexture into which to write new Terrain texture data
        UnityEngine.TerrainTools.PaintContext paintContext = UnityEngine.TerrainTools.TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds());
        // Call the common rendering function that OnRenderBrushPreview and OnPaint use
        RenderIntoPaintContext(paintContext, editContext.brushTexture, editContext.brushStrength, brushXform);
        // Commit the modified PaintContext with a provided string for tracking Undo operations. This function handles Undo and resource cleanup for you
        UnityEngine.TerrainTools.TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Raise or Lower Height");

        // Return whether Trees and Details should be hidden while you paint with this Terrain Tool
        return true;
    }
}
```

## Inheritance

**Inherited Members:**

* [TerrainPaintToolWithOverlaysBase.OnToolSettingsGUI(Terrain, IOnInspectorGUI)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/ontoolsettingsgui.md)
* [TerrainPaintToolWithOverlaysBase.GetName()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/getname.md)
* [TerrainPaintToolWithOverlaysBase.GetDescription()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/getdescription.md)
* [TerrainPaintToolWithOverlaysBase.OnEnable()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onenable.md)
* [TerrainPaintToolWithOverlaysBase.OnDisable()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/ondisable.md)
* [TerrainPaintToolWithOverlaysBase.OnEnterToolMode()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onentertoolmode.md)
* [TerrainPaintToolWithOverlaysBase.OnExitToolMode()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onexittoolmode.md)
* [TerrainPaintToolWithOverlaysBase.OnInspectorGUI(Terrain, IOnInspectorGUI)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/oninspectorgui.md)
* [TerrainPaintToolWithOverlaysBase.OnSceneGUI(Terrain, IOnSceneGUI)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onscenegui.md)
* [TerrainPaintToolWithOverlaysBase.OnRenderBrushPreview(Terrain, IOnSceneGUI)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onrenderbrushpreview.md)
* [TerrainPaintToolWithOverlaysBase.OnPaint(Terrain, IOnPaint)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onpaint.md)
* [TerrainPaintToolWithOverlaysBase.OnActivated()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onactivated.md)
* [TerrainPaintToolWithOverlaysBase.OnWillBeDeactivated()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onwillbedeactivated.md)
* [TerrainPaintToolWithOverlaysBase.OnToolGUI(EditorWindow)](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/ontoolgui.md)
* [TerrainPaintToolWithOverlaysBase.OnIcon()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/onicon.md)
* [TerrainPaintToolWithOverlaysBase.OffIcon()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/officon.md)
* [TerrainPaintToolWithOverlaysBase.IconIndex()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/iconindex.md)
* [TerrainPaintToolWithOverlaysBase.Category()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/category.md)
* [TerrainPaintToolWithOverlaysBase.HasToolSettings()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/hastoolsettings.md)
* [TerrainPaintToolWithOverlaysBase.HasBrushMask()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/hasbrushmask.md)
* [TerrainPaintToolWithOverlaysBase.HasBrushAttributes()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/hasbrushattributes.md)
* [TerrainPaintToolWithOverlaysBase.Terrain()](/engine/6000.6/script-reference/unityeditor/terraintools/terrainpainttoolwithoverlaysbase/terrain.md)
* [EditorTool.PopulateMenu(DropdownMenu)](/engine/6000.6/script-reference/unityeditor/editortools/editortool/populatemenu.md)
* [EditorTool.IsAvailable()](/engine/6000.6/script-reference/unityeditor/editortools/editortool/isavailable.md)
* [EditorTool.SetHidden(bool)](/engine/6000.6/script-reference/unityeditor/editortools/editortool/sethidden.md)
* [EditorTool.targets](/engine/6000.6/script-reference/unityeditor/editortools/editortool/targets.md)
* [EditorTool.target](/engine/6000.6/script-reference/unityeditor/editortools/editortool/target.md)
* [EditorTool.toolbarIcon](/engine/6000.6/script-reference/unityeditor/editortools/editortool/toolbaricon.md)
* [EditorTool.gridSnapEnabled](/engine/6000.6/script-reference/unityeditor/editortools/editortool/gridsnapenabled.md)
* [EditorTool.isHidden](/engine/6000.6/script-reference/unityeditor/editortools/editortool/ishidden.md)
* [ScriptableObject.CreateInstance(string)](/engine/6000.6/script-reference/unityengine/scriptableobject/createinstance.md#createinstance\(string\))
* [ScriptableObject.CreateInstance(Type)](/engine/6000.6/script-reference/unityengine/scriptableobject/createinstance.md#createinstance\(type\))
* [ScriptableObject.CreateInstance\<T>()](/engine/6000.6/script-reference/unityengine/scriptableobject/createinstance.md)
* [Object.GetEntityId()](/engine/6000.6/script-reference/unityengine/object/getentityid.md)
* [Object.GetHashCode()](/engine/6000.6/script-reference/unityengine/object/gethashcode.md)
* [Object.InstantiateAsync\<T>(T)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, Transform, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, ReadOnlySpan\<Vector3>, ReadOnlySpan\<Quaternion>)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Transform, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Transform, Vector3, Quaternion, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Transform, ReadOnlySpan\<Vector3>, ReadOnlySpan\<Quaternion>)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Transform, ReadOnlySpan\<Vector3>, ReadOnlySpan\<Quaternion>, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, InstantiateParameters, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, InstantiateParameters, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, Vector3, Quaternion, InstantiateParameters, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, Vector3, Quaternion, InstantiateParameters, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.InstantiateAsync\<T>(T, int, ReadOnlySpan\<Vector3>, ReadOnlySpan\<Quaternion>, InstantiateParameters, CancellationToken)](/engine/6000.6/script-reference/unityengine/object/instantiateasync.md)
* [Object.Instantiate(Object, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object-vector3-quaternion\))
* [Object.Instantiate(Object, Vector3, Quaternion, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object-vector3-quaternion-transform\))
* [Object.Instantiate(Object)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object\))
* [Object.Instantiate(Object, Scene)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object-scene\))
* [Object.Instantiate\<T>(T, InstantiateParameters)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate\<T>(T, Vector3, Quaternion, InstantiateParameters)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate(Object, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object-transform\))
* [Object.Instantiate(Object, Transform, bool)](/engine/6000.6/script-reference/unityengine/object/instantiate.md#instantiate\(object-transform-bool\))
* [Object.Instantiate\<T>(T)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate\<T>(T, Vector3, Quaternion)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate\<T>(T, Vector3, Quaternion, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate\<T>(T, Transform)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Instantiate\<T>(T, Transform, bool)](/engine/6000.6/script-reference/unityengine/object/instantiate.md)
* [Object.Destroy(Object, float)](/engine/6000.6/script-reference/unityengine/object/destroy.md)
* [Object.DestroyImmediate(Object, bool)](/engine/6000.6/script-reference/unityengine/object/destroyimmediate.md)
* [Object.FindObjectsByType(Type)](/engine/6000.6/script-reference/unityengine/object/findobjectsbytype.md#findobjectsbytype\(type\))
* [Object.FindObjectsByType(Type, FindObjectsInactive)](/engine/6000.6/script-reference/unityengine/object/findobjectsbytype.md#findobjectsbytype\(type-findobjectsinactive\))
* [Object.DontDestroyOnLoad(Object)](/engine/6000.6/script-reference/unityengine/object/dontdestroyonload.md)
* [Object.FindAnyObjectByType\<T>()](/engine/6000.6/script-reference/unityengine/object/findanyobjectbytype.md#findanyobjectbytypet\(\))
* [Object.FindAnyObjectByType\<T>(FindObjectsInactive)](/engine/6000.6/script-reference/unityengine/object/findanyobjectbytype.md#findanyobjectbytypet\(findobjectsinactive\))
* [Object.FindObjectsByType\<T>()](/engine/6000.6/script-reference/unityengine/object/findobjectsbytype.md#findobjectsbytypet\(\))
* [Object.FindObjectsByType\<T>(FindObjectsInactive)](/engine/6000.6/script-reference/unityengine/object/findobjectsbytype.md#findobjectsbytypet\(findobjectsinactive\))
* [Object.FindAnyObjectByType(Type)](/engine/6000.6/script-reference/unityengine/object/findanyobjectbytype.md#findanyobjectbytype\(type\))
* [Object.FindAnyObjectByType(Type, FindObjectsInactive)](/engine/6000.6/script-reference/unityengine/object/findanyobjectbytype.md#findanyobjectbytype\(type-findobjectsinactive\))
* [Object.ToString()](/engine/6000.6/script-reference/unityengine/object/tostring.md)
* [Object.name](/engine/6000.6/script-reference/unityengine/object/name.md)
* [Object.hideFlags](/engine/6000.6/script-reference/unityengine/object/hideflags.md)

### Operators

| Operator                                                                           | Description                                                             |
| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [operator ==](/engine/6000.6/script-reference/unityengine/object/op-equality.md)   | Compares two object references to see if they refer to the same object. |
| [bool](/engine/6000.6/script-reference/unityengine/object/op-implicit.md)          | Determines whether the object exists.                                   |
| [operator !=](/engine/6000.6/script-reference/unityengine/object/op-inequality.md) | Compares if two objects refer to a different object.                    |
