Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preventing Animation Model Rotation #101

Open
TunYuntuwuQWQ opened this issue Aug 13, 2024 · 1 comment
Open

Preventing Animation Model Rotation #101

TunYuntuwuQWQ opened this issue Aug 13, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@TunYuntuwuQWQ
Copy link

TunYuntuwuQWQ commented Aug 13, 2024

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.)

@TunYuntuwuQWQ TunYuntuwuQWQ added the enhancement New feature or request label Aug 13, 2024
@TunYuntuwuQWQ
Copy link
Author

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);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant