Jump to content

[1.19.2] How to replace PlayerModel with a custom one


duckynatalie

Recommended Posts

Hello,

I am working on a mod in which I would like to add new animations to the player (ex: push a button to rotate the arm up for 1 second). I have spent hours upon hours attempting to get to a point where I am able to control the parts of the character model, but have not had any success.

In my current approach, I have created an ExpressivePlayerModel class which extends PlayerModel. I can manipulate the parts of the player (ModelPart) such as "head," "rightArm," etc. from within this class. Basically what I think I want to do is replace PlayerModel with ExpressivePlayerModel. If I were able to simply change the Minecraft source code, I think this would be solved by changing "PlayerModel" to "ExpressivePlayerModel" in the constructor of PlayerRenderer, but obviously I can not do this.

Based on a few older posts I found on related topics, I think the correct way to go about this is using the RenderPlayerEvent.Pre event. This is where I've been stuck trying different things out for hours with no luck. I tried way too many things to list out here, most recently of which is using an access transformer to make "model" in LivingEntityRenderer public, then in the event do-

event.getRenderer.model = new ExpressivePlayerModel(p_174557_.bakeLayer(p_174558_ ? ModelLayers.PLAYER_SLIM : ModelLayers.PLAYER), p_174558_)

-but I can not even get that to work because I can't figure out how I would get p_174557_ and p_174558_.

One last note, this mod is just for a school project, so I don't care if I have to do anything that would not be compatible with other mods and/or have issues with client/server stuff. This won't be used anywhere else, I just need the character to animate on my screen.

Is anything that I've been doing on the right track? And where should I go from here?

Thanks!

Link to comment
Share on other sites

I'm not immediately sure, as I haven't done anything like that before, but it seems to me that you're potentially answering your own question: 

1 hour ago, duckynatalie said:

If I were able to simply change the Minecraft source code, I think this would be solved by changing "PlayerModel" to "ExpressivePlayerModel" in the constructor of PlayerRenderer, but obviously I can not do this.

Create a new player renderer that extends PlayerRenderer, replace the model for your own and then inside the event, cancel the current one and spawn a new event in it's place. Using your own renderer as the PlayerRenderer perhaps?

The pre event you subscribe to needs the following:

        public Pre(Player player, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) {
            super(player, renderer, partialTick, poseStack, multiBufferSource, packedLight);
        }

send everything through, most of which you can steal from the original event before the cancellation, and fire away... I hope? 

 

Oh yeah, you can fire an event like this: 

net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Pre(player, renderer, partialTick, poseStack, multiBufferSource, packedLight));



Again, I'm not sure if this is recommended, safe or anything, but it's where I'd start

Edited by MistaOmega
added potential way to fire event
Link to comment
Share on other sites

Thanks for the response.

What you are describing is actually one of the ways I was trying it before. For the most part, I was able to create a new player renderer that extends PlayerRenderer (ExpressivePlayerRenderer), replace the model with my own, and cancel the event.

@SubscribeEvent
    public static void testAnimationEvent(final RenderPlayerEvent.Pre event) {
        
        EntityRendererProvider.Context context = What do I put right here?;
        boolean isSlim = What do I put right here?;
        ExpressivePlayerRenderer renderer = new ExpressivePlayerRenderer(context, isSlim);
        renderer.setToExpressiveModel(); // Method to replace PlayerModel with ExpressivePlayerModel

        Player player = event.getEntity();
        float partialTick = event.getPartialTick();
        PoseStack poseStack = event.getPoseStack();
        MultiBufferSource multiBufferSource = event.getMultiBufferSource();
        int packedLight = event.getPackedLight();

        event.setCanceled(true);
        net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Pre(player, renderer, partialTick, poseStack, multiBufferSource, packedLight));

    }

However, I can not for the life of me figure out how to initialize context and isSlim. I looked at the code where the PlayerRenderer constructor is used and tried to replicate it but I am still at a total loss for this part. I need that EntityRendererProvider.Context and the boolean to pass into super() in the constructor of ExpressivePlayerRenderer.

Also - I'm pretty new to using events - wouldn't this just repeat forever since whenever there is a RenderPlayerEvent.Pre it just fires another RenderPlayerEvent.Pre?

Does what I have here look good and how would I go about initializing those?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.