Skip to content

GUIUtilities.TextureArrayGUIDrawer

Description

Unity Editor Only

Allows drawing textures stored in a Texture2DArray to the GUI as well as functions for reading and deleting the array

Automatically creates and manages its own array when textures are modified

Includes texture fields accompanied by:

  • Sliders
  • Int/Float fields
  • Color field

This is not a static class and an object must be created OnEnable of the inspector. Textures can be drawn by calling the object

Each texture array requires two variables in the shader

  • Texture Array (Texture2DArray)
  • Assigned Textures (int)

Example of using a TextureArrayGUIDrawer

using UnityEngine;
using TextureArrayUtilities.GUIUtilities;

#if UNITY_EDITOR
using UnityEditor;

public class ArrayGUIExample : ShaderGUI
{
    // The drawer can be used multiple times, once for each array
    private TextureArrayGUIDrawer _arrayDrawerSection1;
    private TextureArrayGUIDrawer _arrayDrawerSection2;

    // ShaderGUI doesnt have an OnEnable function, using this instead
    private bool _firstSetup = true;

    private void OnEnable(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        // Property names are the references from the shader
        // Replace them with your own
        MaterialProperty arraySection1Property = FindProperty("_ArraySection1", properties);
        MaterialProperty arraySection2Property = FindProperty("_ArraySection2", properties);
        MaterialProperty assignedTexturesSection1Property = FindProperty("_AssignedTexturesSection1", properties);
        MaterialProperty assignedTexturesSection2Property = FindProperty("_AssignedTexturesSection2", properties);

        // Texture amount should be changed to the max amount of textures you want in your array
        // In this example we will use a max of 4
        _arrayDrawerSection1 = new TextureArrayGUIDrawer(arraySection1Property, assignedTexturesSection1Property, 4);
        _arrayDrawerSection2 = new TextureArrayGUIDrawer(arraySection2Property, assignedTexturesSection2Property, 4);

        // Settings of the arrays can be modified by these variables
        // Most of these settings will only take effect when the array is created
        // Array is not created on initialization, only when needed so these can be modified afterwards
        _arrayDrawerSection1.ArrayCompressed = true;
        _arrayDrawerSection1.TransferMipmaps = true;
        _arrayDrawerSection1.ArrayLinear = false;

        _arrayDrawerSection2.ArrayCompressed = true;
        _arrayDrawerSection2.TransferMipmaps = true;
        _arrayDrawerSection2.ArrayLinear = false;
    }

    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        // OnEnable if first call
        if (_firstSetup) {
            OnEnable(materialEditor, properties);
            _firstSetup = false;
        }

        // Example for drawing all the textures in both arrays 
        // An array of GUIContent can be assigned for the label and tooltip of each field
        _arrayDrawerSection1.DrawTextures();
        GUILayout.Space(10); // Adds space in between arrays
        _arrayDrawerSection2.DrawTextures();
    }
}

#endif

TextureArrayGUIDrawer

Declaration

public TextureArrayGUIDrawer(MaterialProperty arrayProperty, MaterialProperty assignedTexturesProperty, int textureCount, string fileName = null)

Parameters

Parameter Description
arrayProperty The material property for the Array (Texture2DArray)
assignedTexturesProperty The material property for the Assigned Textures (float)
textureCount The max amount of textures this array will hold
fileName Default: Null
The filename of the Texture2DArray asset stored in a folder accompanying the material
Used only on creation of the asset. Array is retrieved from the material afterwards

Description

Create a TextureArrayGUIDrawer using the Array and Assigned Textures properties

The Texture2DArray asset will be stored in a folder accompanying the material. Can be moved after creation

TextureArrayGUIDrawer _arrayDrawer;

// ShaderGUI doesnt have an OnEnable function, using this instead
private bool _firstSetup = true;

private void OnEnable(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Property names are the references from the shader
    // Replace them with your own
    MaterialProperty arrayProperty = FindProperty("_Array", properties);
    MaterialProperty assignedTexturesProperty = FindProperty("_AssignedTextures", properties);

    // Create an array drawer
    // Texture amount should be changed to the max amount of textures you want in your array
    // In this example we will use a max of 4
    _arrayDrawer = new TextureArrayGUIDrawer(arrayProperty, assignedTexturesProperty, 4);

    // Settings of the arrays can be modified by these variables
    // Most of these settings will only take effect when the array is created
    // Array is not created on initialization, only when needed so these can be modified afterwards
    _arrayDrawerSection1.ArrayCompressed = true;
    _arrayDrawerSection1.TransferMipmaps = true;
    _arrayDrawerSection1.ArrayLinear = false;
}

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // OnEnable if first call
    if (_firstSetup) {
        OnEnable(materialEditor, properties);
        _firstSetup = false;
    }

    // Draw textures
}

Declaration

public TextureArrayGUIDrawer(Material material, string arrayPropertyName, string assignedTexturesPropertyName, int textureCount, string fileName = null)

Parameters

Parameter Description
material The targeted material
arrayPropertyName The reference name for the Array (Texture2DArray) shader property
assignedTexturesPropertyName The reference name for the Assigned Textures (Float) shader property
textureCount The max amount of textures this array will hold
fileName Default: Null
The filename of the Texture2DArray asset stored in a folder accompanying the material
Used only on creation of the asset. Array is retrieved from the material afterwards

Description

Create a TextureArrayGUIDrawer using a material and property names

The Texture2DArray asset will be stored in a folder accompanying the material. Can be moved after creation

TextureArrayGUIDrawer _arrayDrawer;

private void OnEnable()
{
    // Using the material and property names is a good alternative when you dont have access to the material properties

    // Replace with your material and property names
    Material material;
    string arrayPropertyName = "_Array";
    string assignedTexturesPropertyName = "_AssignedTextures";

    // Create an array drawer
    // Texture amount should be changed to the max amount of textures you want in your array
    // In this example we will use a max of 4
    _arrayDrawer = new TextureArrayGUIDrawer(material, arrayPropertyName, assignedTexturesPropertyName, 4);

    // Settings of the arrays can be modified by these variables
    // Most of these settings will only take effect when the array is created
    // Array is not created on initialization, only when needed so these can be modified afterwards
    _arrayDrawerSection1.ArrayCompressed = true;
    _arrayDrawerSection1.TransferMipmaps = true;
    _arrayDrawerSection1.ArrayLinear = false;
}

DrawTexture

Declaration

public Texture2D DrawTexture(int index, GUIContent content)

public Texture2D DrawTexture(Rect rect, int index, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
content The GUIContent for the field

Returns

The texture input into the inspector

Description

Draws a texture using the assigned array

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Draws the texture at index 0 with the label "Texture 1"
    Texture2D input = _arrayDrawer.DrawTexture(0, new GUIContent("Texture 1")));

    // Use the texture if needed
}

DrawTextureWithInt

Declaration

public (Texture2D, int) DrawTextureWithInt(int index, int intValue, GUIContent content)

public (Texture2D, int) DrawTextureWithInt(Rect rect, int index, int intValue, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
intValue The input integer value
content The GUIContent for the field

Returns

Item1: Texture, Item2: Int Value

Description

Draws a texture using the assigned array along with a integer value

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your integer value
    int intValue;

    // Draws the texture with an integer field at index 0 with the label "Texture 1"
    (Texture2D, int) input = _arrayDrawer.DrawTextureWithInt(0, intValue, new GUIContent("Texture 1")));

    // Use the texture and int values if needed
    // Texture: input.Item1
    // Int: input.Item2
}

DrawTextureWithIntSlider

Declaration

public (Texture2D, int) DrawTextureWithIntSlider(int index, int sliderValue, int sliderMin, int sliderMax, GUIContent content)

public (Texture2D, int) DrawTextureWithIntSlider(Rect rect, int index, int sliderValue, int sliderMin, int sliderMax, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
sliderValue The input slider value
sliderMin The minimum value that the slider will allow
sliderMax The maximum value that the slider will allow
content The GUIContent for the field

Returns

Item1: Texture, Item2: Slider Value

Description

Draws a texture using the assigned array along with a integer slider

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your slider value
    int slilderValue;

    // Draws the texture with an integer slider from 0-10 at index 0 with the label "Texture 1"
    (Texture2D, int) input = _arrayDrawer.DrawTextureWithIntSlider(0, slilderValue, 0, 10, new GUIContent("Texture 1")));

    // Use the texture and int values if needed
    // Texture: input.Item1
    // Int: input.Item2
}

DrawTextureWithFloat

Declaration

public (Texture2D, float) DrawTextureWithFloat(int index, float floatValue, GUIContent content)

public (Texture2D, float) DrawTextureWithFloat(Rect rect, int index, float floatValue, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
floatValue The input float value
content The GUIContent for the field

Returns

Item1: Texture, Item2: Float Value

Description

Draws a texture using the assigned array along with a float value

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your float value
    float floatValue;

    // Draws the texture with a float field at index 0 with the label "Texture 1"
    (Texture2D, float) input = _arrayDrawer.DrawTextureWithFloat(0, floatValue, new GUIContent("Texture 1")));

    // Use the texture and float values if needed
    // Texture: input.Item1
    // Float: input.Item2
}

DrawTextureWithSlider

Declaration

public (Texture2D, float) DrawTextureWithSlider(int index, float sliderValue, float sliderMin, float sliderMax, GUIContent content)

public (Texture2D, float) DrawTextureWithSlider(Rect rect, int index, float sliderValue, float sliderMin, float sliderMax, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
sliderValue The input slider value
sliderMin The minimum value that the slider will allow
sliderMax The maximum value that the slider will allow
content The GUIContent for the field

Returns

Item1: Texture, Item2: Slider Value

Description

Draws a texture using the assigned array along with a slider

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your slider value
    float floatValue;

    // Draws the texture with a float slider from 0-1 at index 0 with the label "Texture 1"
    (Texture2D, float) input = _arrayDrawer.DrawTexture(0, floatValue, 0, 1, new GUIContent("Texture 1")));

    // Use the texture and float values if needed
    // Texture: input.Item1
    // Float: input.Item2
}

DrawTextureWithColor

Declaration

public (Texture2D, Color) DrawTextureWithColor(int index, Color colorValue, bool hdr, GUIContent content)

public (Texture2D, Color) DrawTextureWithColor(Rect rect, int index, Color colorValue, bool hdr, GUIContent content)

Parameters

Parameter Description
rect The space that the field will use
index Index of the texture being changed in the desired array layout
Not the index of the current array layout or textures, think of it as a constant within the set texture count
colorValue The input color value
hdr If the color is HDR
content The GUIContent for the field

Returns

Item1: Texture, Item2: Color Value

Description

Draws a texture using the assigned array along with a color value

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your color value
    Color colorValue;

    // Draws the texture with a non-hdr color field at index 0 with the label "Texture 1"
    (Texture2D, float) input = _arrayDrawer.DrawTexture(0, colorValue, false, new GUIContent("Texture 1")));

    // Use the texture and color values if needed
    // Texture: input.Item1
    // Float: input.Item2
}

DrawTextures

Declaration

public Texture2D[] DrawTextures(GUIContent[] content = null)

Parameters

Parameter Description
content Default: Null
The GUIContent for each texture field in order
If unassigned each texture will be named "Texture 1", "Texture 2", ...

Returns

Array of textures input into the inspector

Description

Draws all the textures in the array using DrawTexture

In some situations this will request user input when changing textures with a popup

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

// GUIContents for each texture field
// Used for labels and tooltips for the fields
// Any fields as null will automatically be assigned to "Texture {index + 1}"
GUIContent[] textureContents = new GUIContent[] {
    new GUIContent("Texture 1", "This is texture 1"),
    new GUIContent("Texture 2", "This is texture 2"),
    new GUIContent("Texture 3", "This is texture 3")
};

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Draws all the textures in the Texture Array using the predefined GUIContent[]
    Texture2D[] input = _arrayDrawer.DrawTextures(textureContents);

    // Use the texture values if needed
}

TextureAssignedAt

Declaration

public bool TextureAssignedAt(int index)

Parameters

Parameter Description
index The index of the texture being checked

Returns

If the texture at the given index is assigned in the inspector

Description

Returns if a texture is assigned at the given index in the inspector

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Replace with your float value
    float floatValue;

    (Texture2D, float) input;

    // Draws a texture with a slider if the texture is set in the inspector
    // If not draw the texture field alone
    if(_arrayDrawer.TextureAssignedAt(0))
        input = _arrayDrawer.DrawTextureWithSlider(0, floatValue, 0, 1, new GUIContent("Texture 1"));
    else
        input.Item1 = _arrayDrawer.DrawTexture(0, new GUIContent("Texture 1"));

    // Use the texture and float values if needded if needed
}

DeleteArray

Declaration

public void DeleteArray()

Description

Clears the array and deletes its file and folder if empty

Does not prevent drawing further textures, acts more like a reset

// Assumes TextureArrayGUIDrawer object is already created
TextureArrayGUIDrawer _arrayDrawer;

public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
    // Button that clears the array
    // Will clear the array file and its folder if required
    // Good to use as a reset button for the textures, will not lock further texture drawing
    if(GUILayout.Button("Clear Texture Array")) {
        _arrayDrawer.DeleteArray();
    }
}