Attempting to make a simple paint surface - two problems

I’m making a game that is entirely in unity UI. I’m trying to make a surface that the user can paint on. I have the basics of this working, but there are two things currently wrong with it:

  • Whatever I paint on the desired surface appears on every UI surface with an “Image” component with “None” selected as the source. The below image shows a panel on the right that I painted on, and another panel on the left that should not be updated, however it is.

  • I’m Using a Texture2D to “paint” on, and even though the surface that I use to set it up is after everything else in the hierarchy, the painted texture appears behind other elements. This image shows my painted lines moving behind the grid image, even though in the hierarchy my paint surface is after the grid image. The grid is supposed to be a “Background”.

My hierarchy looks like this:

“Draw Surface” is the last sibling in the hierarchy, yet the Texture2D always displays behind “Background Image”.

Here is my script for drawing:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DrawSurface : MonoBehaviour {

    public int drawWidth;

    private RectTransform drawSurfaceRectTransform;
    private Texture2D drawSurfaceTexture;
    private float drawSurfaceWidth;
    private float drawSurfaceHeight;

    private Vector2 localPointerPosition;

    // Use this for initialization
    void Start () {
        drawSurfaceRectTransform = this.gameObject.GetComponent<RectTransform>();
        drawSurfaceWidth = drawSurfaceRectTransform.rect.width;
        drawSurfaceHeight = drawSurfaceRectTransform.rect.height;
        drawSurfaceTexture = new Texture2D((int) drawSurfaceWidth, (int) drawSurfaceHeight);
        this.gameObject.GetComponent<Image>().material.mainTexture = drawSurfaceTexture;

        // Reset all pixels color to transparent
        Color32 resetColor = new Color32(255, 255, 255, 255);
        Color32[] resetColorArray = drawSurfaceTexture.GetPixels32();

        for (int i = 0; i < resetColorArray.Length; i++) {
            resetColorArray[i] = resetColor;
        }

        drawSurfaceTexture.SetPixels32(resetColorArray);
        drawSurfaceTexture.Apply();
      
        //Debug.Log(GetInstanceID() + " - Started");
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButton(0) || Input.GetMouseButton(1)) {
            Color drawColor = Color.black;
            if (Input.GetMouseButton(1)) {
                drawColor = Color.red;
            }

            if (RectTransformUtility.RectangleContainsScreenPoint(drawSurfaceRectTransform, Input.mousePosition, null))
            {
                RectTransformUtility.ScreenPointToLocalPointInRectangle (drawSurfaceRectTransform, Input.mousePosition, null, out localPointerPosition);
                for (int i = -(drawWidth / 2); i < (drawWidth / 2) ; i++)
                {
                    for (int j = -(drawWidth / 2); j < (drawWidth / 2) ; j++)
                    {
                        drawSurfaceTexture.SetPixel((int) (localPointerPosition.x + (drawSurfaceWidth / 2) + i), (int) (localPointerPosition.y + (drawSurfaceHeight / 2) + j), drawColor);
                    }
                }
                drawSurfaceTexture.Apply();
                Debug.Log(drawSurfaceTexture.GetInstanceID() + " - Drawn");
                //Debug.Log(GetInstanceID() + " - Drawn");
            }
        }
    }
}
2 Likes

Hey man. Thank you al ot for this code. I was used it as tutorial for making UI painting.

1 Like

Might be too late, but…for the first problem: creating a material and assigning it to the drawing surface Image should do the trick (Although all surfaces with that same material will be drawn on the same way)