When using procedural tools, usually think about runtime generation (i.e. while the player is playing), but we can obviously also pregenerate things such as heightmaps or bitmaps, which is why I am sharing this simple script that allows writing arrays to textures and writing these textures to disk.

When using this script, there are a few things to keep in mind:

  • We’ll be writing texture files to the Resources folder. Remember that files in the Resources folder are loaded with Resources.Load, and are not loaded by default. This is useful if you have, say, a single actual play scene with a terrain on which you are applying a heightmap and textures; you don’t need all your pregenerated textures loaded in memory if you’re only using one!
  • The Resources folder is deprecated by Addressables, but you can still use it.
  • Textures written to disk might not be immediately available/shown in the editor; you’ll likely have to refresh the asset database manually or by using the AssetDatabase.Refresh function.

Anyway here’s a (tentative) first draft for this utility script.

The code, along with other utils, is also available on my UnitySimpleUtils repository on Github.

using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class TextureWriter
{
    public static void WriteArrayToDisk_AsTexture(float[,] arr, string pathInResourcesFolder)
    {
        WriteTextureToDisk(WriteArrayToTexture(arr), pathInResourcesFolder);

    }

    public static Texture2D WriteArrayToTexture(float[,] arr)
    {
        Texture2D tex = new Texture2D(arr.GetLength(0), arr.GetLength(1));

        for (int i = 0; i < arr.GetLength(0); i++)
        {
            for (int j = 0; j < arr.GetLength(1); j++)
            {
                tex.SetPixel(i, j, new Color(arr[i, j], 0f, 0f));


            }
        }

        tex.Apply();

        return tex;
    }

    public static void WriteArrayToDisk_AsTexture(Vector3[,] arr, string pathInResourcesFolder)
    {
        WriteTextureToDisk(WriteArrayToTexture(arr), pathInResourcesFolder);

    }

    public static Texture2D WriteArrayToTexture(Vector3[,] arr)
    {
        Texture2D tex = new Texture2D(arr.GetLength(0), arr.GetLength(1));

        for (int i = 0; i < arr.GetLength(0); i++)
        {
            for (int j = 0; j < arr.GetLength(1); j++)
            {
                tex.SetPixel(i, j, new Color(arr[i, j].x, arr[i, j].y, arr[i, j].z));

            }
        }

        tex.Apply();

        return tex;
    }


    public static void WriteTextureToDisk(Texture2D texture, string pathInResourcesFolder)
    {
        File.WriteAllBytes("Assets/Resources/" + pathInResourcesFolder + ".png", texture.EncodeToPNG());

    }

}