I’m doing a 2D game on Android and i have a little problem with my graphics.
When my player is moving, all pixel seem to move…
it’s not like shaking or jerk, i don’t know how to explain this effect . i was thinking about my physic, but when i created a new scene with no physic and just a animation to move my player, the effect of “move” stay …
remove the smooth effect of my camera change nothing
so i don’t understand what happen…
i don’t know if on my video you can see it, but if someone can help me i’ll really appreciate ^^’
It’s because your camera position isn’t a pixel coordinate. If your camera is at a random floating point position, you’re going to have partial-pixels on screen getting rounded, and that rounding is what causes that visual crawling.
Try rounding your camera’s position to the nearest pixel, or getting an asset that supports pixel-perfect cameras. You’ll also need your sprites to be at pixel-perfect positions when they move if that’s also desired.
For example, here’s the asset PixelPerfect with a demo of your visual artifact.
Oh thanks for you’re help! i’m on the right way now !
I found a free script for pixel perfect wich work perfectly for this! but … when i’m using it , my sprite seem to change their Z valu or order in layer
My perspective in my game is down
Do you know how can i fix that ?
here the script of this free asset :
using UnityEngine;
using UnityEngine.Rendering;
namespace GGEZ
{
[
ExecuteInEditMode, // Run this script in edit mode so the preview window looks good
RequireComponent (typeof(Camera)), // Only add this component if there is a camera
HelpURL ("http://ggez.org/posts/perfect-pixel-camera/"), // Website opened by clicking the book icon on the component
DisallowMultipleComponent, // Only one of these per GameObject
AddComponentMenu ("GGEZ/Camera/Perfect Pixel Camera") // Insert into the "Add Component..." menu
]
public class PerfectPixelCamera : MonoBehaviour
{
// Set this value to the same value as Pixels Per Unit when importing sprites
[
Tooltip ("The number of texture pixels that fit in 1.0 world units. Common values are 8, 16, 32 and 64. If you're making a tile-based game, this is your tile size."),
Range (1, 64)
]
public int TexturePixelsPerWorldUnit = 16;
// Reference to the camera on this same GameObject. Found
// by the OnEnable function.
private Camera cameraComponent;
// Set to a value that compensates for the half-pixel offset when
// rendering with Direct3D
private float halfPixelOffsetIfNeededForD3D;
//---------------------------------------------------------------------------
// OnEnable - Called by Unity when the component is created or enabled
//---------------------------------------------------------------------------
void OnEnable ()
{
// Grab a reference to the camera
this.cameraComponent = (Camera)this.GetComponent (typeof(Camera));
// Detect whether we are using Direct3D, because D3D rendering has a
// half-pixel offset from OpenGL rendering.
bool isD3D =
SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D9
|| SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11
|| SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12;
// 0.4975f and not 0.5f is used because 0.5f can be represented
// as a perfect IEEE float. This means that when added to other
// floats that are imperfect, the results can sometimes be rounded
// the wrong way. It can be tricky to reproduce so this isn't part
// of the main demo.
this.halfPixelOffsetIfNeededForD3D = isD3D ? 0.4975f : 0f;
// Run the LateUpdate immediately so that the projection gets set up
this.LateUpdate ();
}
//---------------------------------------------------------------------------
// OnDisable - Called by Unity when the component is disabled or destroyed
// This function cleans up after the PerfectPixelCamera so that the
// projection matrix isn't left in an altered state by this component.
//---------------------------------------------------------------------------
void OnDisable ()
{
if (this.cameraComponent == null)
{
return;
}
this.cameraComponent.ResetProjectionMatrix ();
this.cameraComponent = null;
}
//---------------------------------------------------------------------------
// LateUpdate - Called by Unity after all other functions have run Update.
// If you have other scripts that use LateUpdate, you might want to use
// the Script Execution Order project setting to make this script run last.
//---------------------------------------------------------------------------
void LateUpdate ()
{
// Get a local reference
Camera camera = this.cameraComponent;
// Make sure the camera is in 2D mode
camera.transparencySortMode = TransparencySortMode.Orthographic;
camera.orthographic = true;
camera.transform.rotation = Quaternion.identity;
camera.orthographicSize = Mathf.Max (camera.orthographicSize, 0.00001f);
// This is the code that computes the parameters needed to perfectly map
// world-space pixels to screen-space pixels.
var pixelRect = camera.pixelRect;
float texturePixelsPerWorldUnit = this.TexturePixelsPerWorldUnit;
float zoomFactor = Mathf.Max (1f, Mathf.Ceil ((1f * pixelRect.height) / (camera.orthographicSize * 2f * texturePixelsPerWorldUnit)));
float halfWidth = (1f * pixelRect.width) / (zoomFactor * 2f * texturePixelsPerWorldUnit);
float halfHeight = (1f * pixelRect.height) / (zoomFactor * 2f * texturePixelsPerWorldUnit);
float snapSizeWorldUnits = 1f / (zoomFactor * texturePixelsPerWorldUnit);
float halfPixelOffsetInWorldUnits = this.halfPixelOffsetIfNeededForD3D * snapSizeWorldUnits;
float pixelPerfectXOffset = halfPixelOffsetInWorldUnits - Mathf.Repeat (snapSizeWorldUnits + Mathf.Repeat (camera.transform.position.x, snapSizeWorldUnits), snapSizeWorldUnits);
float pixelPerfectYOffset = halfPixelOffsetInWorldUnits - Mathf.Repeat (snapSizeWorldUnits + Mathf.Repeat (camera.transform.position.y, snapSizeWorldUnits), snapSizeWorldUnits);
// Build a manual projection matrix that fixes the camera!
camera.projectionMatrix = Matrix4x4.Ortho (
-halfWidth + pixelPerfectXOffset,
halfWidth + pixelPerfectXOffset,
-halfHeight + pixelPerfectYOffset,
halfHeight + pixelPerfectYOffset,
camera.nearClipPlane,
camera.farClipPlane
);
}
}
}