Pixel Destruction - Per pixel 2d destruction with unity

NEW INFO: no longer an open source project, now I am beginning work on creating an android game with the framework! Thanks for all those who helped get the bugs worked out early on!
Original Post:

Hey guys, I found this cool Java/Processing project, which uses a destructible pixel terrain. I decided to take a shot at converting to Unity’s C# and here are my efforts so far…

Link to original (Java/Processing) source:

So here is the deal, since I am porting it from an open source project (errr… tutorial) in Java/Processing, I say it could be an open source project for unity… If I can get the help I need to get it up and running, then we share the whole project with the community (asset store free section perhaps?) and everyone could make some cool stuff out of it. Think of all the interesting “cortex command” and “clonk” clones haha.

So I ask you fellow forum members, help me in my goal, and lets make something I have never seen in Unity… Download, disect, come back with answers/improvements to its problems… simple as that.

see further post for more info

1348363--93605--$PixelDestructionScreenshot.png

1 Like

Very awesome to see this actually happening. I saw your original question about it and wondered if this would actually progress. Hopefully we can all come together to make something magical happen!

That’s my hopes, I will still be grinding away at this the next few days, and hopefully I get some good feedback here in this thread, and get the ball rolling.

see further posts for more info

Tried to fix some,

Renderer.cs

original:

for (RenderObj obj : objects)
  obj.draw();

replace with:

foreach (RenderObj obj in objects)
  obj.draw();

and added public… to these (in Bullet.cs)

	// methods implemented as a PhysicsObj
	public float getX() { return x; }
	public float getY() { return y; }
	public float getVX() { return velX; }
	public float getVY() { return velY; }
	public void setX(float pX) { x = pX; }
	public void setY(float pY) { y = pY; }
	public void setVX(float vX) { velX = vX; }
	public void setVY(float vY) { velY = vY; }

ArrayList can be most likely replaced with List.

One problem is the millis()

Ok making changes to the upload to reflect these changes mgear, thank you.

see further posts for more info

Made one test from the original sources,
it can at least draw the terrain with transparent bg…
but nothing happens since those update/draw() functions are not done…(not sure if it would work anyways : )

  public void draw() {
    //fill(col);
    //noStroke();
    //rect(x,y, size, size);
  }

Download current source package:

For milliseconds, can use:

private System.Diagnostics.Stopwatch  stopwatch;
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
..
stopwatch.ElapsedMilliseconds; // returns ms

awesome, sounds promising, I will compare our work and see what I can do with it… I’ll check back when I’ve gotten anywhere…

see latest posts for more info

Spent the day working away at it, I completely started over from the Java source, then came up with a much cleaner, better formatted, better commented, still-not-working version of the same thing… which is available still from the first post.

I got through some errors, changing java/processing conventions over to C#, naming all the scripts with conflicting (unity built-in) names to CustomWhatever… I did a lot of testing but was not able to properly draw anything to screen… this is proving to be much more difficult than I had thought! I’ll check back tomorrow, hopefully someone else can have a look through it and figure something out.

see latest post for more info

Didnt check the latest package yet,
but in previous version you didnt have img.Apply(); after img.SetPixels(…)

I also had problems with graphics.drawtexture, it doesnt start from upper left corner when given 0,0…

Yes I think I fixed the img.apply part in this new package… but yes drawtexture doesnt work like I expected it to, maybe some unity 2D guru could give us a push in the right direction with that. I might even post a unity answers question with that particular code if I cant get it figured out today.

Edit - doh! I was trying to call Graphics.DrawTexture where I couldnt, it must be in OnPostRender, or OnGUI…(perhaps others as well, but not normal methods/update…)

Now it can:
-draw the terrain
-find every purple pixel
-replace every purple pixel with transparent pixel
-redraw the terrain
-spawn player

took hours of hacking at it to get it that far - but now we are really getting somewhere, and I’m learning a good bit of useless Java information… - although I owe much of this new update to mgear - for helping sort out a few big ones in his source that I picked through, or atleast pushing me in the right direction.

New info:
I made a webplayer to test out the current version (its broken right now, no shooting, no character controls)

In this webplayer you can see the glitch I am having problems with right now is that the player (just a green and black cube) starts floating upwards like gravity is reversed.

I tried just using negative value as gravity, only slows down the upwards movement, which led me to think it must be somewhere else effecting it. Anyway you can try it here:

see first post for links

and same old link for the source of it to maybe… help me out? haha

Nice work!

In customphysics modified this part, now it falls better (although still upwards),
see original code, that closingbracket/else position:

			if(obj.GetType() == typeof(Player))
				{
					if (!(((Player)obj).onGround  velY > 0))
						obj.setY (obj.getY () + velY * fixedDeltaTimeSeconds);  
				}
				else
					obj.setY (obj.getY () + velY * fixedDeltaTimeSeconds);

hmm that didnt do much even if disabled,
its getting moved up in here:

player.cs (~line 225)

y = yCheck - playerHeight / 2;

It’s hard getting to the bottom of this physics bug, disabling gravity from the customphysics.cs or inverting it (whatever it was * -1) doesnt bring him down (or leave him floating still) like expected. So I am really scratching my head on this one - but in other news lol, I managed to sorta figure out getting the sky to not be black, but transparent, but then as soon as I got it working I managed to screw it up again - go figure. Anyway those are the two issues im working on right now - the players bad gravity effect (im thinking its isPixelSolid() related by the way…read bottom part) and the non-transparent (yet 0 alpha) “sky” which only comes up black for now? I’ll report back if I get anything working today.

Oh and also… you can comment out a few sections of player.cs and the gravity will drop him to the bottom of the screen properly, it just wont have him stop on terrain, goes allll the way down to the bottom of the screen… so I am almost certain something is wrong with the player constraints coding… perhaps also again, isPixelSolid from CustomTerrain could be doing it.

EDIT: oh right good eye on that bracket thing! I’m changing it now. and yes noticed that that line seems to effect it too, I’ll see what I can figure out with it.

Oh another thing, isPixelSolid has debug stuff showing (atleast in mine, not sure if I uploaded it like that) and it seems to always report alpha of 1 no matter what pixel is tested… as if the part that assigns 0 alpha to certain pixels is not having an effect… hmmm… makes no sense because like, the sky is either becoming clear (seems like first run does this… and then black thereafter) and that means that it applied those effects to the image… maybe when I am running the isPixelSolid its only checking the source image? I had tried using a dummy version of Color[ ] to hold ONLY the alpha, so all 0, 0, 0, (1 or 0) once it was set was what I expected, but even running ispixelsolid on that STILL returns a 1 - no matter what???

Okay breakthrough on that part - its feeding bad pixel coordinates… I decided to try coloring the pixels ran through ispixelsolid with a green color, and bam at runtime I see this:

1354382--66915--$7h9t.png

and so I am gonna have some work to figure this out… is unity reading from bottom left corner? hmmm

somebody answer if they have insight

in customTerrain.cs

find:

return img.GetPixel(x,y) != Color.clear;

replace with:

return img.GetPixel(x,y) == Color.clear?true:false;

Now its bouncing… :slight_smile:

*edit: actually it should be opposite…since the original code is !=

oh sweet haha, be back in a few

yes this definitely fixes that part! okay, now I have updated this question here to get help with this aspect:

Getting inverted Y axis from Texture2D.GetPixel() - Questions & Answers - Unity Discussions has been answered

ok it seems the whole image is upside down somehow,
because if you do this SetPixel() in CustomTerrain, inside isPixelSolid()
it draws inside the terrain (not where the player is)

			img.SetPixel(x,y,Color.red);
			img.Apply(false);
			return img.GetPixel(x,y) != Color.clear?true:false;

*oh you had the same note in previous post :slight_smile:

New, much improved, almost as good as that java webplayer version. Now destruction is visible, you can destroy and add pixels to the terrain with left and right click. :slight_smile:

see the first post for a screenshot

You still cant see all the dynamic pixels properly (ones being blown up and spewed out with right click) until they land and become static pixels… but hey, I’m bustin my butt here people! lol

see further post for more info

Man I am losing steam pretty bad on this project. I am needing some assistance for sure, as the problems I am facing now are pretty difficult to overcome - first major issue is the hanging of the editor and webplayer - its doing this all the time, every time. I don’t use pro, and haven’t got a good way to profile whats causing this… and commenting out random bits of code here and there is proving difficult to narrow down the cause.

Another big issue I am dealing with, is getting off OnGUI() and trying to draw to a quad in front of the camera (which I got a prototype going) because it seems quicker (better FPS anyway, until you start clicking) but it still suffers from hangs every 5-10 mouse clicks… so its hard to gauge how much of a difference it makes…

Now don’t take me wrong, I am far from giving up on this project, but my free time is limited, and my 2D (expecially Texture2D) knowledge is limited… if I could get some people (like some 2D experts) to jump on board and start trying to fix some of these issues we could really polish this up nicely, and maybe get that performance you see in the java webplayer which seems to not even be phased by thousands of pixels all over the place…

Anyway, if I come up with any major changes I’ll be sure to upload what I have… but for now I am pretty much stuck in researching better ways to handle this stuff. My theory for now might be to try switching to setpixels32 instead of setpixels… word on the street is that its much faster.

I was also thinking it could be easier just to start from scratch…
just take exploded (moving pixels) into array, calculate physics, update them to Color[ ] array, then Apply()…repeat.

here’s profiler image from that last package:

that big spike must be a heavy Apply(), or wait is it an explosion? hmm, anyway I’ll think about that today, might try something like that.

I have tried using Color32 and SetColor32 / GetColor32 - but for some reason it only draws… nothing… hmm gonna work on dynamic pixels some more

and yaknow I was thinking, that in the java webplayer it didnt draw dynamic pixels to the terrain until they became static pixels, it just did Rect’s I think, but they worked different than unity, obviously they didnt require OnGUI calls, and they were 1x1 pixels in size I think… so if we try and draw those pixels to the terrain, it would cause collision problems and stuff, and make everything really heavy on the physics engine, but maybe it would be ok to make another quad (in my latest version I depend on a quad instead of Graphics.DrawTexture() ) on top of the first one, which is specifically for drawing dynamic pixels, so they dont interfere with the collision physics and such… hmm.

and also… I been tinkering towards an array of dynamic pixels, and color[ ] of them, but I keep running into a problem with keeping track of who is who… which pixels to draw, which pixels to destroy… hmm

I havent uploaded the quad drawing version because, well its more experimental than the Graphics.DrawTexture way… but its fairly simple to switch them out really if anyone wanted to try that vs doing drawtexture

EDIT: ok that hanging, its the dynamic pixels. I edited this out of Explode.cs:

// create the dynamic pixel
//								DynamicPixel pixel = new DynamicPixel (terrain.getColor (solidX, solidY), x, y, velX, velY, terrain.destructionRes);
//								pixel.stickiness = 800;
//								physics.add (pixel);
//								renderer.add (pixel);

and suddenly, less hanging, so then I commented the parts of dynamic pixel that “bounce” the pixel around (and uncommented the part in explode ofcourse)… NO MORE HANGING! Here is what collide() does in DynamixPixel now (ps this is old code, been replaced in latest updates):

for (int i = 0; i < size; i++)
			{ 
				for (int j = 0; j < size; j++)
				{
					terrain.addPixel (col, thisX + i, thisY + j);
					//DynamicPixelGraphic.AddPixel(col, thisX + i, thisY + j);
				}  
			}
			// remove this dynamic pixel
			renderer.remove (this);
			physics.remove (this);

and thats it, no more bouncing for right now… but that hang had to go, was wrecking my webplayer and test runs in editor, now I can focus on drawing the dynamic pixels in the first place…

thanks mgear for pushing me in the right direction. again. :smile:

New Info:

Ok figured out a way to draw those dang dynamic pixels… so check out the new (crash free hopefully) webplayer for an “interesting” solution haha. re-uploaded source with new somewhat janky method for drawing onto quads… but its faster… this way does makes some strange artifacts where pixels “used to be” so it has its drawbacks to drawing those dynamic pixels this way, but a step in the right direction. On another note, I think that its something about getting the normals of the terrain that is really causing the hang (if nobody gets this I mean its freezing the game permanently or at least for way too long to be acceptable - just occurred to me that its a vague description of what happens)

What do you guys think so far? Can unity reach the performance of that java webplayer? It still gets lag when it gets intense, but much better than Graphics.DrawTexture() did. And stopping the dynamic pixel bounce saves some FPS for sure, and so does only updating the images once per frame (OnGUI did it much more probably). Any ideas for further performance increases? Any ideas for getting that normal calculation (I think anyway) to stop freezing everything up?