The Bug:
Guardians and elder guardians render outside of their hitboxes when looking up or down.
Steps to Reproduce:
Summon a guardian and elder guardian looking down by using the commands provided below.
/summon minecraft:elder_guardian ~ ~ ~ {NoAI:1b,Silent:1b,Rotation:[0f,75f]}/summon minecraft:guardian ~ ~ ~ {NoAI:1b,Silent:1b,Rotation:[0f,75f]}Enable entity hitboxes by pressing "F3 + B".
Take note as to whether or not guardians and elder guardians render outside of their hitboxes when looking up or down.
Observed Behavior:
Guardians and elder guardians render outside of their hitboxes.
Expected Behavior:
Guardians and elder guardians would not render outside of their hitboxes.
Code Analysis:
The following is based on a decompiled version of Minecraft 26.3 Snapshot 4 using Mojang mappings.
net.minecraft.client.model.monster.guardian.GuardianModel.java
public static LayerDefinition createBodyLayer() {
MeshDefinition mesh = new MeshDefinition();
PartDefinition root = mesh.getRoot();
PartDefinition head = root.addOrReplaceChild(
"head",
CubeListBuilder.create()
.texOffs(0, 0)
.addBox(-6.0F, 10.0F, -8.0F, 12.0F, 12.0F, 16.0F)
...
.texOffs(16, 40)
.addBox(-6.0F, 8.0F, -6.0F, 12.0F, 2.0F, 12.0F)
.texOffs(16, 40)
.addBox(-6.0F, 22.0F, -6.0F, 12.0F, 2.0F, 12.0F),
PartPose.ZERO
);
...
}
public void setupAnim(final GuardianRenderState state) {
...
this.head.xRot = state.xRot * (float) (Math.PI / 180.0);
...
}If we look at the above class, we can see that the guardian's body is a single part, named "head", whose pivot is set to PartPose.ZERO. The pivot is the point a part turns around, and ZERO places it at y 0. Every box that makes up the body sits between y 8 and y 24, so the model is centered on y 16. Since 16 units is one block, the body is a full block away from the point it turns around.
The line in setupAnim then applies the guardian's pitch straight to that part, with nothing else adjusting for the gap. Looking up or down therefore does not turn the guardian in place. It swings the whole model around a point one block above itself, on an arc with a one block radius.
At the 75 degrees used in the steps above, the center of the model moves 1.22 blocks and ends up at a height of 1.24. The hitbox is a 0.85 block cube, so the model does not lean out of its hitbox, it leaves it entirely. The elder guardian uses the same part scaled by 2.35, so it moves 2.86 blocks.
Fixed Code:
net.minecraft.client.model.monster.guardian.GuardianModel.java
PartDefinition head = root.addOrReplaceChild(
"head",
CubeListBuilder.create()
.texOffs(0, 0)
.addBox(-6.0F, -6.0F, -8.0F, 12.0F, 12.0F, 16.0F)
...
.texOffs(16, 40)
.addBox(-6.0F, -8.0F, -6.0F, 12.0F, 2.0F, 12.0F)
.texOffs(16, 40)
.addBox(-6.0F, 6.0F, -6.0F, 12.0F, 2.0F, 12.0F),
PartPose.offset(0.0F, 16.0F, 0.0F)
);The pivot moves to y 16, the center of the body, so the guardian turns around itself rather than around a point above itself. Every y coordinate underneath that part then drops by the same 16, which is what keeps the resting pose exactly where it is today. That covers the body boxes above, the eye, the three tail parts, and the 16.0F currently added in getSpikeY.
No guard on the pitch is needed. The correction is worth nothing at 0 degrees, so a guardian that is not looking up or down renders identically to how it does now.
The elder guardian is covered by the same change. createElderGuardianLayer scales the mesh by 2.35, and that scale is applied above this part rather than to it, so the elder guardian inherits the corrected pivot at its own size.
i think, this is like an animation for an attack, like a iron golem trows up his arms. But when in this animation, the hitbox doesnt change.
They must remove the animation, the change of hitbox because of the animation would be much more difficult i think.