What is a good in-game drawing solution?

Edit - the OP is talking, apparently, ONLY about the black handwriting where it says “REAR STAIRWELL”.


Hello, in my game, the player can display a map to check out his environment. It’s not like a ResidentEvil/Hitman/IGI maps where you get to see your enemies, locked doors, etc.
It’s just a normal paper, no electronics.

However, what’s really cool about it, is that you can write/jot things down on it, notes, put land marks, mark locked doors, areas, put reminders of item places, etc.
Basically something like this:

(Just ignore the Red=…, Yellow=…, etc)

So basically, this is the map. And the player’s gonna be able to put those red markers, and writings you see.

How am I gonna do that?
More specifically:

  1. Is there a Unity3D library/plugin
    for this? or am gonna have to look
    at some of the .NET libraries?

  2. After I figured out what to use, how
    is it gonna be done? I mean, the
    map’s a texture, and since I’m gonna
    be making changes on it, it must be
    saved, so that it could be loaded
    later, right? - If somebody could
    put some light on that it would be
    appreciated.

Thanks a lot.

EDIT: OK, I just found out about Eric’s plugin/tool . It looks good, but I don’t know if it is what I’m looking. So far it looks like it’s the best Unity-related solution.

Has anybody experienced it? is it able to achieve that I’m after?

There are several ways to achieve this.

  1. Your map is a texture. Use this line-drawing method to draw lines on your texture. You save changes to the texture using myTexture.Apply(). Plus, the texture can be saved easily to disk using myTexture.EncodeToPNG(). BTW text is going to be much harder, unless you want them to write text using lines.

  2. Use an orthographic camera, and draw all your lines as rectangular Meshes (or even boxes). The plus side of that is that you can “zoom-in” and “pan” etc. Your lines are true vectors. They don’t appear jagged. You can also create text using TextMesh and it will play nice with your lines. The downside is that you have to manage the data-structures yourself, and even the saving/loading.

  3. If you cant be bothered to implement your own line drawing etc, then simply use Vectrocity. You cant go wrong with anything done by Eric Haines (Eric5h5). You can have 3D lines as well, so you retain the advantages of (2).

UPDATE

If you have Unity Pro, you could also use GL.Lines. Same advantages as (2).

You can use UnityPaint as a base-line to build your own stuff.

I really liked this question so i decided to write you a basic script to get you started and give you the idea of how to draw on top of a texture.

right mouse button erases. left mouse draws!!!

let me know if you have any questions!!!

using UnityEngine;
using System.Collections;

public class paint : MonoBehaviour {
	int i;
	int i2;
	Color c;
	float f;
	
	int sw;
	int sh;
	
	float mx;
    float my;
	
	int px;
	int py;

	//drop a texture into the inpector 
	//in the texture import settings you must set the type to "advanced"
	//and then set "read/write" to true!!!!!!!

	public Texture2D original;

	Texture2D myimage;

	public int brush;
	public int erase;
	int oldp;

	public Color drawcolor;
	
	
	
	void Start () {

        if (original == null) {original = new Texture2D (400, 300);}

		// change these next three variables to whatever you want!!!
		drawcolor = Color.red;
		brush = 6;
		erase = 20;

		//copy our original into our new paintable image 
		myimage = new Texture2D(original.width,original.height);

		i = original.width;
		while (i>0) {
			i--;
			i2 = original.height;
			while (i2>0) {
				i2--;
				c=original.GetPixel(i,i2);
				myimage.SetPixel(i,i2,c);}}
		
		myimage.Apply ();
		myimage.filterMode=FilterMode.Point;//<remove this if you want it more fuzzy

}
	
	void OnGUI (){
		GUI.DrawTexture (new Rect (0, 0, Screen.width, Screen.height), myimage);
	}
	
	void Update () {


		sw=Screen.width;
		sh=Screen.height;
		
		mx = Input.mousePosition.x/sw;
		my = Input.mousePosition.y/sh;
		
		px = Mathf.RoundToInt(myimage.width * mx);
		py = Mathf.RoundToInt(myimage.height * my)-1;
		
		
		if(px+py!=oldp){// <-- only draw when mouse moves for proficiency
			oldp=px+py;

			if (Input.GetMouseButton (0)) {//------mouse right button  draws--------

				px+=-Mathf.RoundToInt(brush*.5f);
				py+=-Mathf.RoundToInt(brush*.5f);

				i=0;
				while(i<brush){i++;//<--next two loops for brush size
					i2=0;
					while(i2<brush){i2++;
				    if(px+i>-1&&px+i<myimage.width){//<---dont try to draw off image width
					if(py+i2>-1&&py+i2<myimage.height){//<---dont try to draw off image height
						
						myimage.SetPixel(px+i,py+i2,drawcolor);
					
						
							}}}}
				myimage.Apply();
			
			}

			
			if (Input.GetMouseButton (1)) {//-----mouse left erases----

				px+=-Mathf.RoundToInt(erase*.5f);
				py+=-Mathf.RoundToInt(erase*.5f);

				i=0;
				while(i<erase){i++;
					i2=0;
					while(i2<erase){i2++;
						if(px+i>-1&&px+i<myimage.width){
						if(py+i2>-1&&py+i2<myimage.height){
					
						c=original.GetPixel(px+i,py+i2);//<--grab pixel from original for erasing
						   myimage.SetPixel(px+i,py+i2,c);
						
						
							}}}}
				   myimage.Apply();
			}
			
		}
		
		
		
		
	}

Quick update on this for anyone who found this thread looking for an easy way to implement freeform lines for freehand drawing.

A Line Renderer component renders a line through a list of points. You can use this to implement drawing using a script that adds the mouse positions to the line renderer positions list while the mouse is dragging.

With a Line Renderer you can also adjust many properties including the width and smoothness of the line.