- Home /
Snap isn't always being accurate...
I'm working on a 2D platformer (big surprise haha), and I'm using my Snap settings to move 2D planes by set distances so that they can easily be placed together with pixel perfect accuracy. Also so that things in general can keep a consistent distance since it's all pixel art in point filtering mode.
My issue though, is that the snap settings seem to sometimes add random fractions to my translations. My snap settings are set to 3.2 (32 pixels is how I'm working that out in relation to camera distance), and sometimes it translates it the right amount, so that I retain a value with only 1 or 2 decimal places, but sometimes it will add random decimal places and numbers, so I'll end up with something like 3.1999999 or even more off than that, and from there it will compound the problem further since it is now working off a multi-decimal place number.
The problem happens instantly if you move the object from a positive position to a negative one, but also happens while only moving in a positive position as well after a while.
So, is anyone aware of this issue? I couldn't find any posts about it. Perhaps it's just the most recent version of Unity? This is my first time really using this engine.
(side question related to this. Would there be any negatives to working at a full 1unit=1pixel scale? As this would make my job even easier by only needing to work with integer values for most of the code. I'm just worried about things like player physics not being able to work as well? Or something else unknown to me)
Try using this: $$anonymous$$athf.floor
$$anonymous$$athf.$$anonymous$$ax (3.2, testnumber)
, it will give you the largest of the 2, and its a float. You can use mathf.ceil or floor within the $$anonymous$$athf.max(3.2, mathf.ceil(testnumber))
World space to screen space conversion wont give you pixel perfect accuracy, so your snapping has to be done by proximity detection and checking bounds.
See also renderer.bounds, bound are independent of rotation, they are just world space positions.
So either the above soltion works or you have to use int's. Physics is handled in floats, so if the object changes position, it will jitter in which case you need to use Vector3.lerp, which will smoothen the transition.
Hope it helps.
Thanks, although I'm aware that I can script the objects to snap to better values and whatnot using a few different $$anonymous$$athf types, but I would like to avoid having to script elements that shouldn't need scripting... For optimal performance and to keep things as simple/clean as possible, especially purely static elements that are going to be duplicated and moved around quite a bit by other people building the scenes. I need the translation and snapping system to work well for the rest of my $$anonymous$$m so they can easily place everything without me needing to go in and fix all the float values. If it comes down to it, I may need to do that though... But I may try working at a scale that only requires integer values ins$$anonymous$$d, and see how that goes first...
Also, I achieve pixel perfect accuracy by keeping my object dimensions as power of 2 numbers, with power of 2 translations. So a static objects position value never needs to be more than one decimal place and never less than 0.1. Of course... this issue, it's not working 100% and causing jitter on those static elements that now have very long float numbers (when I bring them back to 1 or 2 decimal places, the jitter goes away)
Answer by hamstar · Nov 09, 2013 at 09:55 AM
If the objects don't appear to be overlapping I wouldn't worry about it. It just has to do with the way floats are stored in memory. See here.
Do you mean 1 object per pixel? I definitely wouldn't recommend that as instantiating and keeping that many objects in memory is bound to cause problems. Even if you just mean in terms of scale I don't recommend it. Your scene could become huge making navigating it in the editor slow. Also there could be a chance you become limited by the maximum size of a unity scene (I'm not sure what the max size is).
Well, the problem is that I need this system to be simple to use for the other people on my $$anonymous$$m, I need to know that when they are translating the objects, it's going to be consistent and simple for them to work on the level design. If the position continually worsens for objects, it's going to cause issues for me having to fix things up every time.
And nah, not 1 object per pixel, heh, that would definitely be troublesome. I just mean scaled up so that 1 Unity Unit translates to 1 Pixel on screen. So if my object was 32x64, it would cover that many pixels on screen. This is already how I'm doing it, except a factor of 10 less in unit size, so I have say a 32x64 texture on a 3.2x6.4 scale object, with movement snapping of power of 2 numbers like 1.6 or 3.2, so that my objects can always be translated to pixel perfect positions.
About the float errors you linked to, the problem with this, as "Starwalker" here sort of indirectly mentioned, is that I get a constant jitter with my objects if they have float values which are longer than 2 or so decimal points, which is what this issue is causing.
Hopefully this all makes a little more sense now... Thanks!
I will have to have another read/think when I'm back on my pc. In the mean time hopefully someone will provide a better answer.
"If the position continually worsens for objects" - is this happening or just something you predict? I wouldn't have expected that to happen. As for the pixel per unit, I'm not sure if I properly understand the benefit (but I guess I don't know what you're planning). In my opinion it seems easier to think of 1 unit = 1 meter, rather than thinking in pixels.
@Invertex I missed the jitter issue. So the objects are jittering even though they are static? Or are you changing their position in code?
Indeed, they are jittering even though they are static objects. (it's not happening as I stand still $$anonymous$$d you, but when the camera moves, they start to jitter) If the position values go past 1 decimal point actually (after further testing) is when it happens. (Nearly everything is comprised of single quad objects with a texture on them.)
As for it continually worsening, I guess that's just how it seemed, but after further inspection, it will often go back to single decimal point values, but the issue is still stands. I sometimes even get values that are too long for unity to display, like -2.384186e-07.
edit: Upon further inspection, it doesn't seem to be completely random either. I can snap it back and forth between bad and good positions, with them staying the same, even though they are wrong.
Just in case, can you check that code which affects the player rigidbody is in FixedUpdate rather than Update. Also, if you are changing the camera position in code (e.g. to follow player) put that code in FixedUpdate (read more). I think I'll have to give up on this one and hope someone else has an answer.