Preventing Animation Model Rotation
TunYuntuwuQWQ opened this issue ยท 1 comments
When using Player Animator to play animations, I want to ensure that the animated model does not rotate with the player's view.
How can I achieve this? (in 1.21 neoforge)
Does Player Animator support this feature? If not, would it be possible to consider adding it?
I have tried subscribing to the 'RendererPlayerEvent.Pre' event and making some adjustments, but the results were not satisfactory. Although the animation plays, the body position animation no longer functions correctly.
I look forward to your response. (I am using translation software.)
What I did was like this
@EventBusSubscriber(modid = HugMe.MODID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME)
public class RenderPlayerEventHandler {
private static final Minecraft client = Minecraft.getInstance();
private static final Map<UUID, UUID> playerLockMap = new HashMap<>();
private static final Map<UUID, Boolean> playerLockState = new HashMap<>();
@SubscribeEvent
public static void onRenderPlayer(RenderPlayerEvent.Pre event) {
Player player = event.getEntity();
PlayerRenderer renderer = event.getRenderer();
float partialTicks = event.getPartialTick();
PoseStack poseStack = event.getPoseStack();
MultiBufferSource buffer = event.getMultiBufferSource();
int packedLight = event.getPackedLight();
if (player instanceof AbstractClientPlayer clientPlayer) {
UUID playerId = player.getUUID();
if (playerLockMap.containsKey(playerId)) {
UUID targetPlayerUUID = playerLockMap.get(playerId);
if (targetPlayerUUID == null) return;
if (client.level == null) return;
AbstractClientPlayer targetPlayer = (AbstractClientPlayer) client.level.getPlayerByUUID(targetPlayerUUID);
if (targetPlayer == null) return;
float targetYaw = calculateYawToTarget(clientPlayer, targetPlayer);
poseStack.pushPose();
poseStack.mulPose(Axis.XP.rotationDegrees(180.0F));
poseStack.translate(0, -1.5, 0);
poseStack.mulPose(new org.joml.Quaternionf().rotationY((float) Math.toRadians(targetYaw)));
renderPlayerModel(renderer, clientPlayer, partialTicks, poseStack, buffer, packedLight);
poseStack.popPose();
event.setCanceled(true);
}
}
}
private static void renderPlayerModel(PlayerRenderer renderer, AbstractClientPlayer entity, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
PlayerModel<AbstractClientPlayer> model = renderer.getModel();
model.young = entity.isBaby();
if (entity == client.player && client.options.getCameraType() == CameraType.FIRST_PERSON) {
model.head.visible = false;
}
model.setupAnim(entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F);
RenderType renderType = RenderType.entityCutoutNoCull(renderer.getTextureLocation(entity));
model.renderToBuffer(poseStack, buffer.getBuffer(renderType), packedLight, OverlayTexture.NO_OVERLAY, -1);
}
private static float calculateYawToTarget(AbstractClientPlayer fromPlayer, AbstractClientPlayer toPlayer) {
double deltaX = toPlayer.getX() - fromPlayer.getX();
double deltaZ = toPlayer.getZ() - fromPlayer.getZ();
return (float) Math.toDegrees(Math.atan2(deltaZ, deltaX)) - 90.0F;
}
public static void lockPlayers(AbstractClientPlayer player1, AbstractClientPlayer player2) {
playerLockMap.put(player1.getUUID(), player2.getUUID());
playerLockMap.put(player2.getUUID(), player1.getUUID());
playerLockState.put(player1.getUUID(), true);
playerLockState.put(player2.getUUID(), true);
HugMe.LOGGER.debug("Locked " + player1.getName().getString() + " and " + player2.getName().getString());
}
public static void unlockPlayers(AbstractClientPlayer player1, AbstractClientPlayer player2) {
playerLockMap.remove(player1.getUUID());
playerLockMap.remove(player2.getUUID());
playerLockState.remove(player1.getUUID());
playerLockState.remove(player2.getUUID());
HugMe.LOGGER.debug("Unlocked " + player1.getName().getString() + " and " + player2.getName().getString());
}
public static boolean isPlayerLocked(AbstractClientPlayer player) {
return playerLockState.getOrDefault(player.getUUID(), false);
}
}