Painter

Open World - Scripts - Painter

How to paint a Texture in Unity3D with C#

To paint an object / Texture in Unity3D first i use a Raycast to get the RaycastHit and then use the textureCoord from the hit.

Vector2 pixelUV = hit.textureCoord;

Now with the textureCoord witch is a Vector2 multiply the x by the texture width and the y by the texture height :

pixelUV.x *= texture.width;
pixelUV.y *= texture.height;

Now after the multipilcation use two for loops to run threw the width and height of the brush / ammount of pixels around the textureCoord.

for (int x = -size / 2; x < size / 2; x++)
for (int y = -size / 2; y < size / 2; y++)

Then use texture.SetPixel() to color the pixels on the texture.

texture.SetPixel((int)(pixelUV.x + x), (int)(pixelUV.y + y), colorPicker.colorPicked);

Finally once the two for loops are finished make sure to use texture.Apply() and now its just a case of setting the mainTexture on the Material that you are modifying.

texture.Apply();

Painting a pixel

materialToPaint.mainTexture = PaintPixel(pixelUV, brushSize);

Painting a Texture On Texture

materialToPaint.mainTexture = PaintCircleOutline(pixelUV, circleSize);

Painting a circle outline

materialToPaint.mainTexture = PaintTextureOnTextue(pixelUV, spriteToDraw);

How to paint a cirle outline onto a Texture in Unity3D with C#

To paint an circle on a Texture in Unity3D the steps are the same.

How to paint a Texture onto a Texture in Unity3D with C#

To paint an Texture on a Texture in Unity3D the steps are the same like for painting a pixel but this time instead of looping the brush size loop though the texture size you wish to paint. and on setting the pixel also get the pixel from the texture.

texture.SetPixel((int)(pixelUV.x + x), (int)(pixelUV.y + y), spriteTexture.GetPixel(mainX, mainY));

Painter.cs 4.1KB

Color Picker 988B

New Input 3.9KB


using UnityEngine;
using UnityEngine.InputSystem;


public class Painter : MonoBehaviour
{
    public string dirName = "Saved2D_Textures";
    public string fileName = "textToPng";
    public enum PaintBrush { Pixel , CircleOutLine, Texture};
    public PaintBrush brush;
    public ColorPicker colorPicker = new ColorPicker();
    public Texture2D spriteToDraw;
    public Material materialToPaint;
    public int picSize = 128;
    public int brushSize = 4;
    public int circleSize = 4;
    public float end;
    public bool newImg;
    public bool saveImg;
    Texture2D texture;
    void Start() 
    {
        colorPicker = new ColorPicker();
        NewImage(); 
    }
    
    void NewImage()
    {
        texture = new Texture2D(picSize, picSize);
        materialToPaint.mainTexture = texture;
    }
    void Update()
    {
        if (newImg == true)
        {
            NewImage();
            newImg = false;
        }
        if (saveImg == true)
        {
            texture.SaveTxt2D(dirName, fileName);
            saveImg = false;
        }
        if (NewInput.Instance.RawFire==1)
        {
            Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                HandleRaycastHit(hit);
            }
        }
    }

    private void HandleRaycastHit(RaycastHit hit)
    {
        Vector2 pixelUV = hit.textureCoord;
        pixelUV.x *= texture.width;
        pixelUV.y *= texture.height;
        switch (brush)
        {
            case PaintBrush.Pixel:
                materialToPaint.mainTexture = PaintPixel(pixelUV, brushSize);
                break;
            case PaintBrush.CircleOutLine:
                materialToPaint.mainTexture = PaintCircleOutline(pixelUV, circleSize);
                break;
            case PaintBrush.Texture:
                materialToPaint.mainTexture = PaintTextureOnTextue(pixelUV, spriteToDraw);
                break;
        }
    }

    public Texture2D PaintTextureOnTextue(Vector2 pixelUV, Texture2D spriteTexture)
    {
        for (int x = -spriteTexture.width / 2; x < spriteTexture.width / 2; x++)
        {
            for (int y = -spriteTexture.height / 2; y < spriteTexture.height / 2; y++)
            {
                int mainX = x + spriteTexture.width / 2;
                int mainY = y + spriteTexture.height / 2;
                if (spriteTexture.GetPixel(mainX, mainY).a != 0)
                {
                    texture.SetPixel((int)(pixelUV.x + x), (int)(pixelUV.y + y), spriteTexture.GetPixel(mainX, mainY));
                }
            }
        }
        texture.Apply();
        return texture;
    }
    Texture2D PaintPixel(Vector2 pixelUV, int size)
    {
        for (int x = -size / 2; x < size / 2; x++)
        {
            for (int y = -size / 2; y < size / 2; y++)
            {
                texture.SetPixel((int)(pixelUV.x + x), (int)(pixelUV.y + y), colorPicker.colorPicked);
            }
        }

        texture.Apply();
        return texture;
    }

    Texture2D PaintCircleOutline(Vector2 pixelUV, int radious)
    {
        

        //center
        int cx = (int)pixelUV.x;
        int cy = (int)pixelUV.y;
        var y = radious;
        var d = 1 / 4 - y;
        float end = Mathf.Ceil(y / Mathf.Sqrt(2));

        Color col = colorPicker.colorPicked;
        for (int x = 0; x <= end; x++)
        {
            texture.SetPixel(cx + x, cy + y, col);
            texture.SetPixel(cx + x, cy - y, col);
            texture.SetPixel(cx - x, cy + y, col);
            texture.SetPixel(cx - x, cy - y, col);
            texture.SetPixel(cx + y, cy + x, col);
            texture.SetPixel(cx - y, cy + x, col);
            texture.SetPixel(cx + y, cy - x, col);
            texture.SetPixel(cx - y, cy - x, col);

            d += 2 * x + 1;
            if (d > 0)
            {
                d += 2 - 2 * y--;
            }

        }

        texture.Apply();
        return texture;
    }
}
Powered by w3.css