Jump to content

[1.15.2] Rotate player arms and edit/remove animation when holding an item


xanderindalzone

Recommended Posts

Hi, I was trying to make my player look like it was holding a Gun type Item, I saw a couple of topics, wrote a bit of code in the Player render Pre event, but it doesn't do anything, the only thing it changes is when i make the arm not visible, this my GunEvents code:
 

Quote

@Mod.EventBusSubscriber(modid = CustomGunsMod.MOD_ID, bus = Bus.FORGE)
public class GunEvents 
{
    
    @SubscribeEvent    //DISPARAR SIN ANIMACION
    public static void cancelRightClickAnimation(PlayerInteractEvent.RightClickItem event)
    {
        PlayerEntity player = event.getPlayer();
        if(player != null){
            Item item = player.getHeldItemMainhand().getItem();
            if(item instanceof GunBase){
                event.setCanceled(true);
                ((GunBase) item).onItemRightClickPrivateEvent(player.world, player);
            }
        }
    }
    
    @SubscribeEvent        //THIS EVENT NOT WORKING <-----------------------
    public static void holdGun(RenderPlayerEvent.Pre event)
    {
        PlayerEntity player = event.getPlayer();
        
        if(player != null&&player.getHeldItemMainhand().getItem() instanceof GunBase){
            event.getRenderer().getEntityModel().bipedRightArm.rotateAngleX=90;
            event.getRenderer().getEntityModel().swimAnimation=0;
            event.getRenderer().getEntityModel().bipedRightArm.showModel=true;
            //event.getRenderer().getEntityModel().bipedRightArm.showModel=false;
        }
    }

    
    
    
    
}
 


any help would be grateful :), thx
 

Link to comment
Share on other sites

I haven't find the best solution yet, but any changes (e.g. rotation) made in the pre event will not work because in render method which gets call after pre event resets model's rotation angle and stuff. What I do is hard coded the rotation and position of the custom player model and render it in post event, and set the bodyparts.showModel to false for the parts that you want to render in post event.

Edited by poopoodice
Link to comment
Share on other sites

2 hours ago, poopoodice said:

I haven't find the best solution yet, but any changes (e.g. rotation) made in the pre event will not work because in render method which gets call after pre event resets model's rotation angle and stuff. What I do is hard coded the rotation and position of the custom player model and render it in post event, and set the bodyparts.showModel to false for the parts that you want to render in post event.

could I see your classes to see how you did it? the custom model render thing to override the vanilla player model

the custom model class and how did you register that custom model....

i'm not very good understanding render stuff XD

Link to comment
Share on other sites

Models does not need to be registered, only renderers

And what I mean by a custom player model is basically the copy and paste of the player model with some rotations and translations... anyways here's the code

https://bitbucket.org/poopoodice/ava/src/master/src/main/java/poopoodice/ava/misc/AVATPRenderer.java

Just want you to know the code is extremely terrible and should not be an example of doing anything.

To explain a bit more: I did not replace anything in vanilla rendering (except the layers, you can't "hide" them). Instead, I hide them and render my own model. I hope there's an easier way to do this but I haven't find anything yet.

You may find this more helpful

 

Edited by poopoodice
Link to comment
Share on other sites

5 hours ago, poopoodice said:

Models does not need to be registered, only renderers

And what I mean by a custom player model is basically the copy and paste of the player model with some rotations and translations... anyways here's the code

https://bitbucket.org/poopoodice/ava/src/master/src/main/java/poopoodice/ava/misc/AVATPRenderer.java

Just want you to know the code is extremely terrible and should not be an example of doing anything.

To explain a bit more: I did not replace anything in vanilla rendering (except the layers, you can't "hide" them). Instead, I hide them and render my own model. I hope there's an easier way to do this but I haven't find anything yet.

You may find this more helpful

 

thx for the help, at least i'm doing some progress now XD

 

 

 


(actual event method), this is the first attempt XD:

Quote

@SubscribeEvent        
    public static void holdGunPost(RenderPlayerEvent.Post event)
    {
        PlayerEntity player = event.getPlayer();
        PlayerRenderer render = event.getRenderer();
        PlayerModel<AbstractClientPlayerEntity> model = render.getEntityModel();
        
        if(player != null&&player.getHeldItemMainhand().getItem() instanceof GunBase){
            ModelRenderer arm = model.bipedRightArm;
            arm.rotateAngleX=90;
            //model.swimAnimation=0;
            
            MatrixStack matrix = event.getMatrixStack();
            IVertexBuilder buffer = event.getBuffers().getBuffer(model.getRenderType(((AbstractClientPlayerEntity) player).getLocationSkin()));
            int light = event.getLight();
            int texture = OverlayTexture.NO_OVERLAY;
            
            model.bipedRightArm.copyModelAngles(arm);
            model.bipedRightArm.showModel=true;    
            arm.render(matrix, buffer, light, texture);;
        }
    }

 

2020-06-23_10.56.52.png

Link to comment
Share on other sites

39 minutes ago, poopoodice said:

It took me really long to adjust the rotations angles and points, btw you can run it in debug mode so you dont have to relaunch the game everytime you make any changes

 

thx for the debug tip, the rotation and pose are pretty much done, but how do I make the gun Item follow the new rendered arm position/rotation?

 

2020-06-23_14.35.44.png

Link to comment
Share on other sites

6 hours ago, sciwhiz12 said:

If the gun model will not need to move dynamically and the gun model is defined using model JSONs, use item display transforms through the "display" option (see MC wiki article on Item Models). I recommend using a program like Blockbench to edit the model's display transforms.

you can but the problem is if he want the hand to keep the rotation angle (no swinging), he will need to access the layers and replace then with his own layers, like I did.

Link to comment
Share on other sites

13 hours ago, poopoodice said:

you can but the problem is if he want the hand to keep the rotation angle (no swinging), he will need to access the layers and replace then with his own layers, like I did.

Exactly, I want the gun to follow the body's YAW and the head's PITCH(removing the walking bobbing animation) to match the Arms Pos./Rot.

How could I do that exactly? Is there a wiki or example code somewhere?

2020-06-24_12.04.43.png

2020-06-24_12.06.06.png

Link to comment
Share on other sites

14 hours ago, poopoodice said:

The link I sent already include that except the rotation pitch

Sorry, I'm trying to understand the layer code stuff, but a bit lost, it's the first time I "try" to work with layers.

 

Could you kindly show me the classes and highlight the code that makes posible to modify position and rotation of the item in the player's hand in third person view? (just the item rendering, I got the player model rendering fine for now).... that way I could study how does the layer code work etc etc.... 

 

I'm looking everywhere to find a solution but i'm not getting any progress :c

 

 

This is my actual rendering code, just in case someone wants to see it:

Quote

    @SubscribeEvent        
    public static void renderHeldGun(RenderPlayerEvent.Pre event)
    {
        
        
        PlayerEntity player = event.getPlayer();
        PlayerRenderer render = event.getRenderer();
        PlayerModel<AbstractClientPlayerEntity> model = render.getEntityModel();

        
        
        if(player != null&&player.getHeldItemMainhand().getItem() instanceof GunBase){
            GunBase gun = (GunBase) player.getHeldItemMainhand().getItem();
            
            
            if(gun.isAiming())
            {
                model.bipedLeftArm.showModel=false;    
            }
            else
            {
                model.bipedLeftArm.showModel=true;    
            }

            model.bipedRightArm.showModel=false;
            
        }
    }
    
    @SubscribeEvent        
    public static void holdGunPost(RenderPlayerEvent.Post event)
    {
        PlayerEntity player = event.getPlayer();
        PlayerModel<AbstractClientPlayerEntity> model = event.getRenderer().getEntityModel();
        
        if(player != null&&player.getHeldItemMainhand().getItem() instanceof GunBase){
            GunBase gun = (GunBase) player.getHeldItemMainhand().getItem();
            if(gun.isAiming())
            {
                renderArmModelIdleHoldingPistolAiming(model, player, event);
            }
            else
            {
                renderArmModelIdleHoldingPistol(model, player, event);
            }
            
        }
    }
    
    
    
    
    
    
    private static void renderArmModelIdleHoldingPistol(PlayerModel<AbstractClientPlayerEntity> model, PlayerEntity player, RenderPlayerEvent event)
    {
        MatrixStack matrix = event.getMatrixStack();
        IVertexBuilder buffer = event.getBuffers().getBuffer(model.getRenderType(((AbstractClientPlayerEntity) player).getLocationSkin()));
        int light = event.getLight();
        int texture = OverlayTexture.NO_OVERLAY;
        
        model.bipedRightArm.rotationPointX = -MathHelper.cos((float) Math.toRadians(player.renderYawOffset)) * 5.5F;
        model.bipedRightArm.rotationPointY = player.isCrouching() ? 17.5F : 20.5F;
        model.bipedRightArm.rotationPointZ = -MathHelper.sin((float) Math.toRadians(player.renderYawOffset)) * 5.5F;
        model.bipedRightArm.rotateAngleX = -1.6F - (player.rotationPitch/90)*1.2F; //-3.0F > -1.65F > -0.0F;    
        model.bipedRightArm.rotateAngleY =  (float) -Math.toRadians(player.renderYawOffset) + 3.2F + -Math.abs((player.rotationPitch/90))*-0.05F;
        model.bipedRightArm.rotateAngleZ = 0.0F;
        
        
        model.bipedRightArm.showModel=true;    
        model.bipedRightArm.render(matrix, buffer, light, texture);
    }
    
    private static void renderArmModelIdleHoldingPistolAiming(PlayerModel<AbstractClientPlayerEntity> model, PlayerEntity player, RenderPlayerEvent event)
    {
        MatrixStack matrix = event.getMatrixStack();
        IVertexBuilder buffer = event.getBuffers().getBuffer(model.getRenderType(((AbstractClientPlayerEntity) player).getLocationSkin()));
        int light = event.getLight();
        int texture = OverlayTexture.NO_OVERLAY;
        
        model.bipedRightArm.rotationPointX = -MathHelper.cos((float) Math.toRadians(player.renderYawOffset)) * 5.5F;
        model.bipedRightArm.rotationPointY = player.isCrouching() ? 17.5F : 20.5F;
        model.bipedRightArm.rotationPointZ = -MathHelper.sin((float) Math.toRadians(player.renderYawOffset)) * 5.5F;
        model.bipedRightArm.rotateAngleX = -1.6F - (player.rotationPitch/90)*1.2F; //-3.0F > -1.65F > -0.0F;    
        model.bipedRightArm.rotateAngleY =  (float) -Math.toRadians(player.renderYawOffset) + 3.5F + -Math.abs((player.rotationPitch/90))*-0.6F;
        model.bipedRightArm.rotateAngleZ = 0.0F;
        
        model.bipedLeftArm.rotationPointX = -MathHelper.cos((float) Math.toRadians(player.renderYawOffset)) * -5.5F;
        model.bipedLeftArm.rotationPointY = player.isCrouching() ? 17.5F : 20.5F;
        model.bipedLeftArm.rotationPointZ = -MathHelper.sin((float) Math.toRadians(player.renderYawOffset)) * -5.5F;
        model.bipedLeftArm.rotateAngleX = -1.7F - (player.rotationPitch/90)*1.2F; //-3.0F > -1.65F > -0.0F;    
        model.bipedLeftArm.rotateAngleY =  (float) -Math.toRadians(player.renderYawOffset) - 3.5F + -Math.abs((player.rotationPitch/90))*0.6F;
        model.bipedLeftArm.rotateAngleZ = 0.0F;

        
        model.bipedRightArm.showModel=true;    
        model.bipedLeftArm.showModel=true;    
        model.bipedRightArm.render(matrix, buffer, light, texture);
        model.bipedLeftArm.render(matrix, buffer, light, texture);
    }

 

Link to comment
Share on other sites

11 hours ago, poopoodice said:

I used reflection to replace the player model's layers and do the rotations and translations in the replaced render method

I found this website with a bunch of PlayerRenderEvent examples and.... LMAO..... it only took 1 CODE LINE to make the player render as I wanted when it was holding the gun. WEBSITE: https://www.programcreek.com/java-api-examples/?api=net.minecraftforge.client.event.RenderPlayerEvent

 

Literally, just this line of code:

Quote

event.getRenderer().getEntityModel().rightArmPose=ArmPose.BOW_AND_ARROW;

 

making the arm and the item copy the render when the player aims with an arrow, the result is just perfect :D

 

tomorrow i'll try to render the left arm as normal, which will be easy I guess.

But now I can finally progress with this thing done XD

 

Footage of the Gun with proper rendering:

https://gyazo.com/de87cfcb79dea7b565013077cb77bb04

 

thx for the help, I guess this topic is now solved :P

Edited by xanderindalzone
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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I have created a mod which applies x shader to the player after consuming x item for a certain time, but if the player presses f5 to change the camera the shader stops working. The only way I have found to prevent the shader from being deactivated is to load it on all ticks until it is disabled but this greatly reduces the performance of the game. I have also tried to cancel the event of changing the camera but this is not cancelable. Any advice, I've been trying to solve this for several days 😵‍💫  
    • Minecraft 1.20.1 Forge 47.2.0 log and crash report: https://pastebin.com/P7tQymQS ; (crash report) I launch the game and i got this error: Someone could help me please?  
    • EDIT: NVM, the enchantment ID was wrong and that was causing the issue. Not sure why it doesn't let me delete this post Hi, I'm trying to make a "smelting" enchantment Global Loot Modifier, but for some reason the game could not decode its related JSON file, altough is applying the Loot Modifier to every single loot When I join a world I get this error in the console   [01:08:01] [Render thread/WARN] [ne.mi.co.lo.LootModifierManager/]: Could not decode GlobalLootModifier with json id mineworld:enchantments/fiery_touch - error: Not a json array: {"condition":"minecraft:match_tool","predicate":{"enchantments":[{"enchantment":"mineworld:smelting","levels":{"min":1}}]}} The GLM Json file is the following { "type": "mineworld:fiery_touch", "conditions": [ { "condition": "minecraft:match_tool", "predicate": { "enchantments": [ { "enchantment": "mineworld:smelting", "levels": { "min": 1 } } ] } } ] } And this is the LootModifier class   package org.mineworld.loot; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.core.RegistryAccess; import net.minecraft.world.Container; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.LootModifier; import net.minecraftforge.items.ItemHandlerHelper; import org.jetbrains.annotations.NotNull; import org.mineworld.MineWorld; import java.util.List; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.IntStream; /** * {@link MineWorld MineWorld} loot modifier for smelting a drop from a block */ public final class FieryTouchModifier extends LootModifier { /** * {@link Supplier<Codec> The loot codec supplier} */ public static final Supplier<Codec<FieryTouchModifier>> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst).apply(inst, FieryTouchModifier::new))); /** * Constructor. Set the {@link LootItemCondition loot id conditions} * * @param lootConditions {@index ILootCondition The conditions that need to be matched before the loot is modified} */ public FieryTouchModifier(final LootItemCondition[] lootConditions) { super(lootConditions); } /** * Add the {@link MWLootItem items} to the loot * * @param loot {@link ObjectArrayList<ItemStack> The current loot} * @param context {@link LootContext The loot context} * @return {@link ObjectArrayList<ItemStack> The modified loot} */ @Override protected @NotNull ObjectArrayList<ItemStack> doApply(final ObjectArrayList<ItemStack> loot, final LootContext context) { if(context.hasParam(LootContextParams.BLOCK_STATE)) { final Level level = context.getLevel(); final RecipeManager recipeManager = level.getRecipeManager(); final RegistryAccess registryAccess = level.registryAccess(); IntStream.range(0, loot.size()).forEach(index -> { final ItemStack drop = loot.get(index); final ItemStack smeltedDrop = tryGetSmeltedDrop(recipeManager, RecipeType.SMELTING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.SMITHING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.BLASTING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.SMOKING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.CAMPFIRE_COOKING, level, registryAccess, drop) .orElse(ItemStack.EMPTY))))); if(!smeltedDrop.isEmpty()) { loot.set(index, smeltedDrop); } }); } return loot; } /** * Get the {@link Codec loot modifier codec} * * @return {@link #CODEC The loot modifier codec} */ @Override public Codec<? extends IGlobalLootModifier> codec() { return CODEC.get(); } /** * Try to set the smelted drop to the {@link List<ItemStack> block drop list} * * @param recipeManager {@link RecipeManager The recipe manager} * @param recipeType {@link RecipeType The recipe type} * @param level {@link Level The level reference} * @param registryAccess {@link RegistryAccess The registry access} * @param drop {@link ItemStack The dropped item} * @return {@link ItemStack The smelted ItemStack} */ private static <C extends Container, T extends Recipe<C>> Optional<ItemStack> tryGetSmeltedDrop(final RecipeManager recipeManager, final RecipeType<T> recipeType, final Level level, final RegistryAccess registryAccess, final ItemStack drop) { return recipeManager.getRecipeFor(recipeType, (C) new SimpleContainer(drop), level) .map(recipe -> recipe.value().getResultItem(registryAccess)) .filter(itemStack -> !itemStack.isEmpty()) .map(itemStack -> ItemHandlerHelper.copyStackWithSize(itemStack, drop.getCount() * itemStack.getCount())); } } I have another GLM that has some entries as well and doesn't have any issues
  • Topics

×
×
  • Create New...

Important Information

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