- Home /
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:
Is there a Unity3D library/plugin for this? or am gonna have to look at some of the .NET libraries?
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 Vectrosity. 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?
Vectrosity does free-hand lines pretty well; see here. (Click once in the window and use the mouse to draw.) I am of course biased, but if I were program$$anonymous$$g this, I would totally use Vectrosity since it would get the best results with $$anonymous$$imum effort.
@Eric5h5: "Vectrosity does free-hand lines pretty well; see here." I'm struggling with my UnityWebPlayer, could you post a video perhaps? - Guys, all I'm asking for is something similar to what you see in the picture. I want to be able to perform free hand writing. Just like the writings/markers you see in the picture. Eric, your asset can do all that right? (I can erase as well right?)
@Eric5h5: $$anonymous$$an that was sick!! I just fixed my player (Removed ID$$anonymous$$ and cleared cache) - Your demos are great! The link you posted above when you mentioned free hand-writing is exactly what I'm looking for. But whenever I draw something, it gets cleared out the next time I draw something else. (that's how the demo works right? - I can draw as many times I want, with anything getting erased unless I order it to, right?) - Hope you answer me on that, and one last thing, what about documentation and API, thanks a lot!
@Eric5h5: That's it, I'm buying :D - Just curious, hope you don't $$anonymous$$d me asking, how did you become that good? - thanks.
@Eric5h5: Out of curiosity, how did you solve the 65k vertices limit problem? I remember running into that when writing my own line-drawing utility a few years back for an oil-sim (wire-line logs).
Answer by Sajidfarooq · Aug 17, 2013 at 01:37 PM
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.
Thanks for your answer. No, I'm not thinking to let the player write using text, we're thinking more of letting him use the map like he's sitting in $$anonymous$$S Paint, he'll have to write manually using the tools. I'm not thinking of letting him change the thickness or whatever, just markers, pencils and erasers (how can I erase?).
Panning isn't really important unless we have a big map, but it would be definitely nice to have around, same for zoo$$anonymous$$g in and out, I expect my game designer to have big maps, so it's better to take caution measures.
If Eric's tool does all that, I'm going for it. Have you worked with it? can it does all what I'm asking? - thanks.
And about GL.Lines, Eric mentioned some inconvenience about them, so I tend to avoid them XD
TextureDrawLine didn't look too great for me.
But one thing worth mentioning, is that zoo$$anonymous$$g in/out and panning isn't actually related to any of the tools, because mostly I'm gonna be viewing the map via NGUI's camera, which is orthogonal, I can zoom in and out by changing the size of the viewport, and pan by maybe casting a ray, hitting the map, then changing the position of the camera (or the map for that matter)
If you are using a texture, then zoo$$anonymous$$g-in, by "any" means, will cause either pixelation, or blurriness, depending on your texture filter.
$$anonymous$$S-Paint is a bitmap editing tool. Basically, it allows you to modify individual pixels. If that is what you want to do, then you will want to manipulate the texture. Erasing can be done at a "pixel" level on a texture because you can simply choose the opposite colour (i.e, draw in the BG colour).
In terms of Vector/$$anonymous$$esh/Vectrocity, you will be dealing with "lines" rather than pixels. So the smallest element a user can draw, is a line. Sure, they can draw a really short line to make it look like a pixel, but its not the same thing. You have to store the lines yourself, and an Erasor will work by removing them from your list.
In short, texture = pixels, and mesh/vectrocity = lines. You can do all of what you are asking with either of the 3 methods I have mentioned. You just have to ask yourself what you need most.
Vectrocity or meshes are a much better choice when you want to be able to modify the lines "after" you have drawn them, or to modify individual lines like their thickness, texture, etc.
Texture manipulation is better when you want to do pixel-manipulation in the traditional sense, i.e, a single pixel can only have a single colour at a time. Once changed, the old value is lost. Just like drawing on a real paper. You overwrite everything below.
Good morning everyone :D - Wow! I missed a lot :D - I read somewhere that my question wasn't clear. I don't want lines, I don't care about the method used, I just wanna be able to draw curves in the best way possible, whether it be continuous lines or pixels, etc. But I prefer to avoid manual pixel manipulations, cuz I'm not that graphics guru. I'll check out UnityPaint to see what's up. Thank you both for your great comments and help, appreciate it.
@vexe, Eric has provided the solution:
http://www.starscenesoftware.com/vectrositydemo9.html
just use Vectrosity. (Vectrosity is one of the 2 or 3 packages you have to have, realistically, to use Unity so you'll need it anyway.)
Answer by toddisarockstar · Mar 12, 2017 at 04:57 AM
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();
}
}
}
Answer by samwoodard · Mar 11, 2017 at 07:51 AM
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.