Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-258579

Player head does not rotate smoothly (with delay) in third person view while riding a vehicle

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.19.3, 23w07a, 1.19.4 Pre-release 1, 1.19.4, 23w16a, 1.20, 1.20.1, 1.20.2, 1.20.3, 1.20.5, 1.21
    • None
    • Confirmed
    • Networking, Rendering
    • Low
    • Platform

      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

      1. Enter third person view.
      2. Move the camera left and right
        Your head moves smoothly
      3. 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.

        1. Expected Behaviour (fix demonstration).mp4
          2.72 MB
          Ismael Rosillo
        2. Observed Behaviour.mp4
          2.86 MB
          Ismael Rosillo

            Unassigned Unassigned
            ISRosillo14 Ismael Rosillo
            Votes:
            10 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              CHK: