Boat jitters when you turn
when you use the a and d key to turn the boat the boat jitters|
Linked Issues
Created Issue:
boat jitters when you turn
when you use the a and d key to turn the boat the boat jitters
when you use the a and d key to turn the boat the boat jitters|
boat jitters when you turnBoat jitters when you turn
is duplicated by
is duplicated by
Can confirm still in the 17w47b.
is duplicated by
is duplicated by
is duplicated by
relates to
This issue duplicates MC-122211.
Duplicate of MC-122211
This issue duplicates MC-122211.
It isn't actually a duplicate of MC-122211. That was issue in 17w47b and it was fixed in 17w48a. The camera and the Boats are not jittering or having any issues when controlling in 17w48a.
This is another issue / bug related to crosshair / mouse movement while in a Boat (standing still or moving).
The Bug
Normally, when the player moves the cursor in third person view, it's model head rotates smoothly (with a slight delay from the camera). However, this doesn't happen while the player is on a vehicle.
This bug is caused by two different mistakes in the code of the game. The first one affects all vehicles and it's just from client-side and the second only affects boats.
How to reproduce
- Enter third person view.
- Move the camera left and right
→
Your head moves smoothly - Place a minecart or any other rideable entity and enter it
→
Your head doesn't move smoothly
Code analysis (using the official mappings and code from 1.19.2, with my own variable names)
In "net.minecraft.client.player.LocalPlayer", the method "getViewYRot(float)" that overrides LivingEntity's, it returns the player's current Y rotation (not the head Y rotation) only when the player is not a passenger. This causes that when "net.minecraft.client.Camera" calls this method when the player is a passenger, the camera uses the head rotation, always rendering the head directly and being unable to see the it's sides.
@Override public float getViewYRot(float partialTick) { return this.isPassenger() ? super.getViewYRot(partialTick) : this.getYRot(); }
This can be easily fixed by changing LocalPlayer's "getViewYRot" method to always return the Y rotation "getYRot()", regardless of if the player is a passenger or not. (just like "getViewXRot(float)"):
@Override public float getViewYRot(float partialTick) { return this.getYRot(); }
By fixing what's described above, the head will now move smoothly (with the "delay") when the player is riding any vehicle without (most likely) any side effects on gameplay. But this will not fix this issue for boats.
This bug also happens when riding a boat (if just this is fixed and not the above, this will not work):
In "net.minecraft.world.entity.vehicle.Boat", at the method "clampRotation(Entity)" which prevents the player from moving his head too away from it's front, when setting the player's Head Y rotation using "setYHeadRot(float)", it just copies the Main Y rotation of the player that was adjusted, removing the delay (or smoothness) of the head movement at third person view.
protected void clampRotation(Entity psngr) { psngr.setYBodyRot(this.getYRot()); float wrappedYrot = Mth.wrapDegrees(psngr.getYRot() - this.getYRot()); float clampedYrot = Mth.clamp(wrappedYrot, -105.0F, 105.0F); psngr.yRotO += clampedYrot - wrappedYrot; psngr.setYRot(psngr.getYRot() + clampedYrot - wrappedYrot); psngr.setYHeadRot(psngr.getYRot); }
This can be fixed by using it's own clamp calculation rather than using the main Y rotation's, as shown in this example:
protected void clampRotation(Entity psngr) { psngr.setYBodyRot(this.getYRot()); float wrappedYrot = Mth.wrapDegrees(psngr.getYRot() - this.getYRot()); float clampedYrot = Mth.clamp(wrappedYrot, -105.0F, 105.0F); psngr.yRotO += clampedYrot - wrappedYrot; psngr.setYRot(psngr.getYRot() + clampedYrot - wrappedYrot); float wrappedYheadrot = Mth.wrapDegrees(psngr.getYHeadRot() - this.getYRot()); float clampedYheadrot = Mth.clamp(wrappedYheadrot, -105.0F, 105.0F); psngr.setYHeadRot(psngr.getYHeadRot() + clampedYheadrot - wrappedYheadrot); }
Deeper investigation (what caused this bug, very important)
This bug happens since snapshot 17w48a, when MC-122211 (the camera jitters when turning a boat while riding it) was fixed by changing the LocalPlayer's "getViewYRot" method to return the Head rotation instead of the Main rotation if the player is a passenger. However, this was a lazy fix (or may be because the summary of that bug report was wrong and Mojang misunderstood it) because that bug actually caused the boat to stutter, not the camera, and resulted in this new bug.
MC-122211 should've been fixed by modifying the "yRotO" value of the boat to be consistent with the "yRot" when "deltaRotatation" field value changes it in the "controlBoat()" method, as you can see in this example:
(at net.minecraft.world.entity.vehicle.Boat) private void controlBoat() { if (this.isVehicle()) { float f = 0.0F; if (this.inputLeft) { --this.deltaRotation; } if (this.inputRight) { ++this.deltaRotation; } if (this.inputRight != this.inputLeft && !this.inputUp && !this.inputDown) { f += 0.005F; } this.yRotO += this.deltaRotation;//ADD THIS this.setYRot(this.getYRot() + this.deltaRotation); if (this.inputUp) { f += 0.04F; } if (this.inputDown) { f -= 0.005F; } this.setDeltaMovement(this.getDeltaMovement().add((double)(Mth.sin(-this.getYRot() * ((float)Math.PI / 180F)) * f), 0.0D, (double)(Mth.cos(this.getYRot() * ((float)Math.PI / 180F)) * f))); this.setPaddleState(this.inputRight && !this.inputLeft || this.inputUp, this.inputLeft && !this.inputRight || this.inputUp); } }
This is very important to do because if you just do the two fixes from the code analysis and ignore this, the boat will stutter when it turns, reviving MC-122211.
confirmed in 17w47b as well