HOW TO DRAW IN UNITY.

PATATJES4LIFE
9 min readAug 7, 2020

--

lisa mantel — @patatjes4life — katpatat.com

omg, drawing is my liiiiife

[INTRO]

Hey arrivederci it’s ya homie lisa, with something new(isch) today. We are going to make a scene, in unity, in which we can draw :) (super basic of course).

Let’s see, we are going to make use of a canvas and an image. Use some code and in the end we can make drawings, with mouse input, nothing fancy.

I will show all the code needed and explain the aspects.

Disclaimer, again I made this together with Neander Giljam (my homie from katpatat).

Something about me (your handsome narrator)… I consider myself to be a digital artist. I’m really into experimental, weird and happy stuff :). Also we want to use our projects to address socially and cultural (or personal) stuff and make people “aware” of these topics through interactive art/games. Together with Neander and Esther we are a collective called Katpatat, we do almost everything together and they helped me alot with these “tutorials” and my project VOIDSCAPES 4 LIFE BABY… voidscapes 4 life? what is that, you say? It’s a game but not technically a game, but more of an interactive art piece made in unity. I wanted to experiment with different forms of visual stuff but it’s also about my own process in and out of depression (you can find it on the website, if interested).

These tutorials are a write up of different (code based) solutions I/we used during the project and I wanted to share them :)

You are always welcome to message me, and for now, have fun reading this article.

LIST WITH TOPICS:

  • set up
  • make the canvas
  • PARTICLES
  • the code + explanation

[SET UP]

jajajaja let’s set everything up

steppie de plannie:

  • first download and install unity, open a new scene and don’t forget to save it.
  • get rid of the directional light, we don’t need their kind over here
  • and I want the scene to be somewhat decent looking, so we go to our lighting tab, change the skybox material to none, change environmental lighting source to color (we are not going to use it though).
  • now we fix our main camera, go to that son of a batch and change clear flags (why is it called like this?) to solid color and change background to another color, like black.
  • now your scene should look like this (ignore my project folder)

[EXTRA EXTRA]

I feel like making a few particles to make it look more fun, you can skippa the bibba this part. But if you are a fun person and like fun things, you should definitely stay.

I created this monstrosity

NOW I WILL SHOW YOU HOW (my computer didn’t like this, but I don’t listen to machines)

first start with you boring old particle system (right mouse click in hierarchy, special effects, particles system)

I want some color, so → check color over lifetime → set it to random between 2 gradients → and change the colors

Now, I like me some noise, next → check the option for noise → set strength and frequency to 1 → set scroll speed to 2 → quality to 1D → and last position amount to 5 :) and voi de la

Go to particle system (above Emission) and → check prewarm → set start lifetime to 10 → and start speed to 0 → last, set start size to 10

Before we go faaaarther, go to the tab “renderer” and → set min particle size to 1 → and max particle size to 10

GO TO SHAPE → set shape to edge → set radius to 5 → and mode to ping pong → last, set spread to 1. You will not see much of a difference and I’m not sure there is… buh eeeeh

LASTLY WE ARE GOING TO USE TRAILS, so check that son of a b on → set life time to 0.0007 → minimum vertex distance to 0.2 → I also checked worldspace but I don’t think it’s necessary :) and voila we have this thing.

Don’t forget to check the transform of the particle set, everything should be 0 except for scale. Scale is números unos.

[CREATING A CANVAS]

Yesss my sweet babies, you have been doing fine until now, let’s make a canvas so we have something to draw upon.

Poopdie do a right click on the hierarchy, go to ui and select canvas. Now we have a canvas and I hate those extremely much because they never do what I want them to do. But luckily you shouldn’t have to change anything in the canvas. It should look something like this (the settings it is)

Now for the next step, click with the right mouse button on the canvas (in the hierarchy) and select image. We need to change a few things in the inspector. The anchor preset needs to be changed to… stretch x stretch, and left, top, posz, right and bottom must be 0.

here a gif to make it more easily (you baby)

Everything for the canvas should be ready, I like to make a prefab out of this but it’s not necessary.

[THE CODE, HERE WE GO]

So like before, I will post the code needed and add extra descriptions :) be careful when copy pasting the code, you probably want to delete the explanations, or comment them out.

FIRST you need to add using UnityEngine.UI; above your class, before it’s too late, no jokey, otherwise we can’t make use of an image object.

public class DrawingTool : MonoBehaviour{public int penWidth = 5;public Color drawingColor = new Color(0, 0, 0, 1);public GameObject Canvas;public Image drawingImage;private bool canDraw = true;private Texture2D currentTexture;private int canvasWidth;private int canvasHeight;private Color32[] currentColors;private Vector3 previousMousePosition;public void SetDrawingState(bool state){Canvas.SetActive(state);canDraw = state;}private void Awake(){ResetCanvas();SetDrawingState(canDraw);}

Lalalala so keep in mind that your piece of code also needs to be called DrawingTool.

The penWidth and drawingColor will allow you to change the size and color of

the strokes.

Canvas and drawingImage makes it able to link our “prefab” or object in our

hierarchy, now we are able to use those :)

candraw is something we can use for later, but it is not necessary right now.

currentTexture will be the thing we are actually drawing on.

canvasWidth and canvasHeight are needed to set the size of currentTextures and are used in other functions.

currentColors is an array of used colors, we aren’t realllly using it, but it works if you change to color while in play mode. When you are in a creative mood you can add some UI implementation to make it more useful and use it to its full potential, muhahahaha.

previousMousePosition is used for marking the pixels, which need to change.

SetDrawingState is used for “activating” the ability to draw, we are not really using this, but it’s build in for potential later use

In the awake, we are activating the ability to draw, but also, we are making a new “canvas”, or better a new Texture2D which we will use.

private void ResetCanvas(){canvasWidth = (int)drawingImage.rectTransform.rect.width;canvasHeight = (int)drawingImage.rectTransform.rect.height;currentColors = new Color32[canvasWidth * canvasHeight];currentTexture = new Texture2D(canvasWidth, canvasHeight, TextureFormat.RGBA32, false);currentTexture.alphaIsTransparency = true;Color startColor = new Color(1, 1, 1, 0);for (int x = 0; x < canvasWidth; x++){for (int y = 0; y < canvasHeight; y++){MarkPixelToChange(x, y, startColor);}}ApplyPixelChanges();}

okokok fun times. In this function we are saving the width and height of our drawingImage in canvasWidth/Height. We are using this to make a new Texture2D which we will use for drawing. We are marking the pixels who need to change in the double for loop with the method MarkPixelToChange. We apply the changes in ApplyPixelChange. ApplyPixelChange is a super duper heavy function, so don’t call it too often.

private void Update(){if (Input.GetKeyDown(KeyCode.R)){ResetCanvas();}if (canDraw){bool isMouseDown = Input.GetMouseButton(0);if (isMouseDown){Draw();}else if (!isMouseDown){previousMousePosition = Vector3.zero;}}}

Nice right? With “if input R” we can reset, and make a new Texture2D, with the press of a button (which is R in this case). Comes in really handy when you want to draw something new.

Next (candraw is for now always “true”) when you press the left mouse button, isMouseDown will be set to true then we can call upon the Draw function. If the left mouse button is not pressed, then the previousMousePosition will be set to a new vector 0,0,0. yeeeeeeah :)

private void Draw(){Vector3 penPosition = Input.mousePosition;if (previousMousePosition == Vector3.zero){MarkPixelsToColour(penPosition);}else{ColourBetween(penPosition);}ApplyPixelChanges();previousMousePosition = penPosition;}

LETS GO TO THE DRAW method. We are going to save the mouse input in penPosition which we will use in MarkPixelToColour en ColourBetween. MarkPixelsToColour will be activated if the previousMousePosition is equal to 0,0,0. After this the pixel change will be applied and the previousMousePosition will be changed.

private void ColourBetween(Vector3 currentPenPosition){float distance = Vector2.Distance(previousMousePosition, currentPenPosition);float lerpSteps = 1 / distance;for (float lerp = 0; lerp <= 1; lerp += lerpSteps){Vector2 currentPosition = Vector2.Lerp(previousMousePosition, currentPenPosition, lerp);MarkPixelsToColour(currentPosition);}}

This method calculates a line between the current mouse position and the previous one.

private void MarkPixelsToColour(Vector3 currentPenPosition){int center_x = (int)currentPenPosition.x;int center_y = (int)currentPenPosition.y;for (int x = center_x - penWidth; x <= center_x + penWidth; x++){if (x >= canvasWidth || x < 0)continue;for (int y = center_y - penWidth; y <= center_y + penWidth; y++){MarkPixelToChange(x, y, drawingColor);}}}

We are adding the penWidht to the pixel, which needs to be changed, in the snippet above. These are given to MarkPixelToChange.

private void MarkPixelToChange(int x, int y, Color color){int arrayPos = y * canvasWidth + x;if (arrayPos > currentColors.Length || arrayPos < 0)return;currentColors[arrayPos] = color;}

Here we are giving a color to the pixels who need changing.

private void ApplyPixelChanges(){currentTexture.SetPixels32(currentColors);currentTexture.Apply();drawingImage.sprite = Sprite.Create(currentTexture, new Rect(0, 0, canvasWidth, canvasHeight), Vector2.zero);}}

The last snippet. We are changing the pixels in the current Texture and are also

applying it. After this, we are turning the texture into a sprite, and will apply this sprite to the drawingImage.

[CONCLUSION]

THANKS FOR READING, I hope yall can use it. I think this is one of my lesser writings but eh… if it’s useful I shan’t complain.

If you have more questions, or find incorrect stuff, or want to say something nice.

you can send me an email or message me on instagram

CHEEERS

[Special thanks to Neander and Esther ❤]

take a look at our website : katpatat.com

instagram : @patatjes4life

email : lisagameart@gmail.com

hahahha no sources for you this time

--

--

PATATJES4LIFE

This is what I do, I sit on you… I’m part of the Katpatat collective. We make playful digital “experiences” and installations. (we are also for hire)