- Home /
Objects moving relative to the player appear to be stuttering/jittering
In this project, I clip all the positions of my sprites so that the sprites are aligned perfectly by the pixels. I do the clipping by taking the rigidbody position of an object and using that Vector3 to create a transform.position which is a multiple of 1/sprite's PPU and applying that position to just the sprite and the colider of the object. After updating the camera's position with the position of the clipped components, I achieve this crisp effect: https://gyazo.com/efe2b4aca6ff0450e326bc256b51718c However, the problems begin when I introduce another moving object into the mix. The objects' fixedUpdates' aren't syncing with each other which means that they're moving in 2 cycles, creating jitter. I've been trying to sort this out all day, but there was no success. Here are some more gifs to visualize the problem:
Other object moving at a lower speed, same direction:
https://gyazo.com/490b44d6011c1150e55d5907865b2307
Object with camera stationary, other object moving (everything working nicely in this situation):
https://gyazo.com/2da9ff9440ad4a3000c7ea9ffbb57af2
Camera stationary while both objects moving:
https://gyazo.com/6392966a0a5fe070da99bfe3e3bea5c9
Slowed time scale showing that the updates are not in sync:
https://gyazo.com/ab2fabe857a7fb8a3d2930ddd3b6391c
The code making the objects go into motion:
private void Awake()
{
physicsPosition = transform.position;
}
private void FixedUpdate()
{
Vector2 force = ComputeForce();
Vector2 acceleration = new Vector2(force.x / mass, force.y / mass);
velocity += acceleration*Time.fixedDeltaTime;
physicsPosition = new Vector3(physicsPosition.x + 0.0625f*velocity.x * Time.fixedDeltaTime, physicsPosition.y + 0.0625f * velocity.y * Time.fixedDeltaTime, physicsPosition.z);
transform.position = RoundToPixel(physicsPosition);
}
Vector2 ComputeForce()
{
return new Vector2(0, mass * (-9.81f * gravityScale));
}
float RoundToPixel(float value)
{
if (PPU != 0)
{
float pixel = 1.0f / PPU;
float rem = value % pixel;
float result = value - rem;
return result;
}
else
{
Debug.LogError("Error: Your Pixel per unit ratio is 0.");
return 0;
}
}
If you're playing with transform.position, did you want to consider moving your changes to Update rather than FixedUpdate?
FixedUpdate doesn't always run every frame and is ideally used as part of the built-in Unity physics system. If you're overriding position on your object, you should probably set the RigidBody to 'kinematic' (controlled by code rather than the physics engine) and take care of the physics yourself, the way you're doing with ComputeForce. In a 2D game, it's unlikely that you need a fully-fledged RigidBody for anything but collision detection anyway.
Answer by Sadzony · Jul 02, 2019 at 01:11 PM
@Optrix I've tried both moving just the updating of the position of the sprite, and the updating of the rb.position with the sprite update to Update rather than FixedUpdate, however that did not work. I've found that the root of the problem lays somewhere else. Although everything updates at the same rate, since one physics body moves faster than the other, the rates on which just the sprites are updated changes. I've tried to snap the physics position to the sprite position whenever the sprite position changes, but that made my gravity not work and also made the objects stop whenever their position reaches positive values, probably due to how my rounding is handled.
Here's a gif of the physics positions represented by colliders (physics positions are not snapped here):
Your answer
Follow this Question
Related Questions
copy camera view to 2d panel and pixelate it 0 Answers
Issue with PixelPerfectCamera script and sprite masks (see images)... How to fix? 1 Answer
Questions about Unity 2D camera setup 1 Answer
Any idea for smooth camera in pixel art sprite? 1 Answer
How to letterbox the screen and have pixel perfection in a 2d game 0 Answers