Armure avec rendu 3D


  • Correcteurs

    Salut les gens,

    Tout est dans le titre, je viens à la pêche aux infos car je ne trouve pas grand chose sur le forum à ce sujet en 1.7.x
    Le seul tuto que j'ai pu trouver sur le net était en anglais et illisible pour un novice.

    Bon, j'imagine qu'il faut le modèle, la classe du rendu, la classe de l'armure ainsi que l'enregistrement dans le ClientProxy. J'ai tenté 2 fois de bricoler selon mes connaissances à 2 mois d'intervalle et je n'arrive toujours à rien.

    Sûrement des méthodes qui me dépassent, je ne mets même pas mes classes tellement elles doivent être loin du résultat, je pars des classes typiques pour un rendu d'item 3D.

    Mais c'est surtout cette méthode qui cache le mystère:
    :::

    @SideOnly(Side.CLIENT)
        public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot)
        {
            return null;
        }
    

    :::

    Est ce bien cette méthode qui est la clef? Si oui comment l'utiliser? Sinon des pistes, svp?



  • Tu dois sûrement créer ton model qui va extends ModelBiped. Puis dans la fonction que tu as donné, tu remplaces le return null par return new MonModel


  • Correcteurs

    Je ne comprends pas trop comment ça fonctionne pour le coup.

    J'ai fais ça:

    :::

    @SideOnly(Side.CLIENT)
        public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
        {
    // ItemStack boots = entityLiving.getEquipmentInSlot(1);
    // ItemStack leggings = entityLiving.getEquipmentInSlot(2);
    ItemStack chestPlate = entityLiving.getEquipmentInSlot(3);
    // ItemStack helmet = entityLiving.getEquipmentInSlot(4);
    if(chestPlate != null && chestPlate.getItem() == ModPg2.bodyArmor3D)
    {
    return new RenderArmor3D();
    }
    return null;
        }
    

    :::

    Seulement le rendu est fait quand j'ai l'item du plastron en main (premier slot et ça change si je change le InSlot(3) par 1 par exemple)
    Il n'est pas fait quand j'ai l'item dans le slot du plastron.

    :::

    public class ItemArmor3D extends ItemArmor
    {
    public ItemArmor3D(ArmorMaterial material, int type)
    {
    super(material, 0, type);
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
        public Multimap getAttributeModifiers(ItemStack stack)
        {
            Multimap map = super.getAttributeModifiers(stack);
            map.put(SharedMonsterAttributes.knockbackResistance.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "KnockbackResist", 0.55, 0));
            map.put(SharedMonsterAttributes.movementSpeed.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "MovementSpeed", 0.04, 1));
    
            return map;
        }
    
    @SideOnly(Side.CLIENT)
        public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
        {
    // ItemStack boots = entityLiving.getEquipmentInSlot(1);
    // ItemStack leggings = entityLiving.getEquipmentInSlot(2);
    ItemStack chestPlate = entityLiving.getEquipmentInSlot(3);
    // ItemStack helmet = entityLiving.getEquipmentInSlot(4);
    if(chestPlate != null && chestPlate.getItem() == ModPg2.bodyArmor3D)
    {
    return new RenderArmor3D();
    }
    return null;
        }
    
    public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type)
    {
    if(stack.getItem() == ModPg2.headArmor3D|| stack.getItem() == ModPg2.bootsArmor3D|| stack.getItem() == ModPg2.legsArmor3D)
    {
    return ModPg2.MODID + ":textures/models/armors/trooper_layer_1.png";
    }
    return null;
    }
    }
    

    :::


  • Administrateurs

    @SideOnly(Side.CLIENT)
       public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
       {
            if(armorSlot == 1)
            {
                 return new RenderArmor3D();
            }
            return null;
       }
    

  • Correcteurs

    J'avais déjà testé ça Robin, mais ça ne fonctionne pas.
    Quand je fais ça, le soucis est le même, je dois avoir l'item en main et non pas équipé pour avoir le rendu du modèle

    Edit: Rectification, ça ne change rien en fait. Même histoire


  • Administrateurs

    Comme ça ?

    @SideOnly(Side.CLIENT)
    public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
    {
    return new RenderArmor3D();
    }
    

  • Correcteurs

    J'avais fais ça au tout début.

    En fait ça applique le modèle au personnage tout le temps. (ce qui peut être sympa si on veut rajouter un troisième bras mais pas là)

    Edit: Rectification, ça ne fait pas ce que j'ai dis plus haut, le soucis reste le même, slot en main et pas quand équipé.


  • Administrateurs

    What vraiment pas normal.
    C'est sensé s'appliquer dans tu as l'armure sur toi.
    Change de version de Forge.


  • Correcteurs

    Bon du coup je mets plutôt l'ensemble des classes. Le modèle actuel est une baignoire, je me suis pas foulé, je voulais tester le code déjà.

    :::

    public class ItemArmor3D extends ItemArmor
    {
    public ItemArmor3D(ArmorMaterial material, int type)
    {
    super(material, 0, type);
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
        public Multimap getAttributeModifiers(ItemStack stack)
        {
            Multimap map = super.getAttributeModifiers(stack);
            map.put(SharedMonsterAttributes.knockbackResistance.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "KnockbackResist", 0.55, 0));
            map.put(SharedMonsterAttributes.movementSpeed.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "MovementSpeed", 0.04, 1));
    
            return map;
        }
    
    @SideOnly(Side.CLIENT)
        public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
        {
    //// ItemStack boots = entityLiving.getEquipmentInSlot(1);
    //// ItemStack leggings = entityLiving.getEquipmentInSlot(2);
    // ItemStack chestPlate = entityLiving.getEquipmentInSlot(3);
    //// ItemStack helmet = entityLiving.getEquipmentInSlot(4);
    // if(chestPlate != null && chestPlate.getItem() == ModPg2.bodyArmor3D)
    // {
    return new RenderArmor3D();
    // }
    // return null;
        }
    
    public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type)
    {
    if(stack.getItem() == ModPg2.headArmor3D|| stack.getItem() == ModPg2.bootsArmor3D|| stack.getItem() == ModPg2.legsArmor3D)
    {
    return ModPg2.MODID + ":textures/models/armors/trooper_layer_1.png";
    }
    return null;
    }
    }
    

    :::

    :::

    public class RenderArmor3D extends ModelBiped implements IItemRenderer
    {
    public RenderArmor3D()
    {
    super();
    }
    
    protected static final ResourceLocation texture = new ResourceLocation("ModPg2:textures/entity/Baignoire.png");
    private ModelArmor3D modelArmor3D = new ModelArmor3D();    
    
    public void renderArmor3D(EntityPlayer player, double x, double y, double z, float f, float prt)
    {
    GL11.glPushMatrix();
    GL11.glTranslated(x, y, z);
    this.getEntityTexture(player);
    modelArmor3D.render(player, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
    GL11.glPopMatrix();
    }
    
    protected ResourceLocation getEntityTexture(Entity entity)
    {
    return this.getEntityTexture((EntityPlayer)entity);
    }
    
    public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9)
    {
    this.renderArmor3D((EntityPlayer)entity, par2, par4, par6, par8, par9);
    }
    
    @Override
    public boolean handleRenderType(ItemStack item, ItemRenderType type)
    {
    switch(type)
    {
           case EQUIPPED:
            return true;
           default:
            return false;
    }
    }
    
    @Override
    public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper)
    {
    return false;
    }
    
    @Override
    public void renderItem(ItemRenderType type, ItemStack item, Object… data) 
    {
    switch(type)
    {
    case EQUIPPED:
    {
               GL11.glPushMatrix();
               Minecraft.getMinecraft().renderEngine.bindTexture(texture);
               modelArmor3D.render((Entity)data[1], 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
               GL11.glPopMatrix();
               break;
           }
           default:
               break;
           }
    }
    }
    
    

    :::

    :::

    public class ModelArmor3D extends ModelBiped
    //Je ne mets pas le contenu, le modèle fonctionne de toute façon
    {
    public ModelArmor3D()
    
      {
    public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
      {
        super.render(entity, f, f1, f2, f3, f4, f5);
        setRotationAngles(f, f1, f2, f3, f4, f5, entity);
     }
    
      private void setRotation(ModelRenderer model, float x, float y, float z)
      {
        model.rotateAngleX = x;
        model.rotateAngleY = y;
        model.rotateAngleZ = z;
      }
    
      public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
      {
        super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
      }
    }
    

    :::

    :::

     MinecraftForgeClient.registerItemRenderer(ModPg2.bodyArmor3D, (IItemRenderer)new RenderArmor3D());
    
    Et dans la classe principale
    
       headArmor3D = new ItemArmor3D(armorR6, 0).setUnlocalizedName("headArmor3D").setTextureName(MODID + ":headArmor3D").setCreativeTab(ModPg2.tabPg);
       bodyArmor3D = new ItemArmor3D(armorR6, 1).setUnlocalizedName("bodyArmor3D").setTextureName(MODID + ":bodyArmor3D").setCreativeTab(ModPg2.tabPg);
       legsArmor3D = new ItemArmor3D(armorR6, 2).setUnlocalizedName("legsArmor3D").setTextureName(MODID + ":legsArmor3D").setCreativeTab(ModPg2.tabPg);
       bootsArmor3D = new ItemArmor3D(armorR6, 3).setUnlocalizedName("bootsArmor3D").setTextureName(MODID + ":bootsArmor3D").setCreativeTab(ModPg2.tabPg);
       GameRegistry.registerItem(headArmor3D, "head_armor3D");
       GameRegistry.registerItem(bodyArmor3D, "body_armor3D");
       GameRegistry.registerItem(legsArmor3D, "legs_armor3D");
       GameRegistry.registerItem(bootsArmor3D, "boots_armor3D");
    

    :::

    Changer de version de Forge… ça me fait un peu peur. J'aime pas toucher à Eclipse.
    Je suis en version 1.7.10-10.13.4.1448-1.7.10


  • Administrateurs

    What ? Pourquoi tu utilises une classe implements IItemRenderer.
    Il faut un modèle extends ModelBiped.


  • Correcteurs

    Eh bien je ne savais pas du tout comment faire la déclaration dans le ClientProxy.

    Car je veux appliquer le modèle à une pièce d'armure et pas toute la classe de l'armure (car l'armure ne suivra pas la mouvements de bras et jambes j'ai supposé)
    Du coup chui parti sur un rendu d'item donc IItemRenderer =/


  • Administrateurs

    Il n'y a rien à faire dans le client proxy.


  • Correcteurs

    Ah bah bonne nouvelle.

    Du coup dans la classe du render, quelles sont les méthodes?

    Est ce que ça suit une façon de procéder qui est déjà détaillée dans un tuto par exemple?

    :::

    public class RenderArmor3D extends ModelBiped
    {
    public RenderArmor3D() 
    {
    super();
    }
    
    protected static final ResourceLocation texture = new ResourceLocation("ModPg2:textures/entity/Baignoire.png");
    private ModelArmor3D modelArmor3D = new ModelArmor3D();    
    
    public void renderArmor3D(EntityPlayer player, double x, double y, double z, float f, float prt)
    {
    GL11.glPushMatrix();
    GL11.glTranslated(x, y, z);
    this.getEntityTexture(player);
    modelArmor3D.render(player, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
    GL11.glPopMatrix();
    }
    
    protected ResourceLocation getEntityTexture(Entity entity)
    {
    return this.getEntityTexture((EntityPlayer)entity);
    }
    
    public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9)
    {
    this.renderArmor3D((EntityPlayer)entity, par2, par4, par6, par8, par9);
    }
    }
    

    :::

    Cette classe est en chantier du coup, comme je ne comprends pas comme ça doit fonctionner de base.


  • Administrateurs

    Il ne faut pas de rendu. Il faut mettre directement le modèle.


  • Correcteurs

    Wuuuut! xD

    Ok, je suis choqué de la simplicité du truc en fait.
    Merci Robin.

    :::
    (http://img11.hostingpics.net/pics/387406Armor3D.png)
    :::

    Edit: Et du coup ça recoupe avec Faire suivre le modèle


  • Administrateurs

    Bha oui c'est super simple.
    Pas mal l'armure qui te transformes en douche roulante x)



  • Je dois admettre que c'est stylé ^^


  • Correcteurs

    Ok je comprends rien à ce que fait Cuty-Stark quand il arrive à faire suivre les mouvements du joueur à la pièce d'armure.

    Je ne me suis pas encore attaqué à l'animation mais en cherchant sur le sujet j'ai vu qu'on pouvait faire ".isChild" des éléments du modèle.
    Est ce que la solution à mon problème serait de faire en sorte que l'ensemble des éléments de mon plastron soit assimilé à une armure normale?

    Il faut mettre tous les offsets au même endroit et définir ça? Si oui, comment svp? (Ou alors la partie du tuto qui ne m'a pas interpellé et qui répond à ma question Xd)

    Edit:

    Ouki c'est ça, j'ai simplement testé son code:::

    casquelampe1.addChild(casquelampe2);
         casquehaut2.addChild(casquelampe1);
         casquehaut1.addChild(casquehaut2);
         casquebas.addChild(casquehaut1);
         this.bipedHead.addChild(casquebas);
    
         body.addChild(vestebase);
         this.bipedBody.addChild(body);
    
         vestebrasgauche.addChild(braceletgauche);
         leftarm.addChild(vestebrasgauche);
         this.bipedLeftArm.addChild(leftarm);
    
         vestebrasdroit.addChild(braceletdroit);
         rightarm.addChild(vestebrasdroit);
         this.bipedRightArm.addChild(rightarm);
    

    :::

    Et effectivement ça permet de les "assembler"
    Par contre le coup du sneak etc. Moi pas comprendre.

    Lui il fait d'une façon qui me fait perdre mes repères.

    :::

    
    1.  armorModel.isSneak = entityLiving.isSneaking();
    2.      armorModel.isRiding = entityLiving.isRiding();
    3.      armorModel.isChild = entityLiving.isChild();
    4.      
    5.      //Ajout –---------------------------------------------
    6.      armorModel.swingProgress = entityLiving.swingProgress;
    7.      //Ajout –---------------------------------------------
    
    

    :::

    C'est cette partie qui semble être la solution, mais je ne comprends pas à quoi devrait correspondre "armorModel" dans mon cas (Lui ça part dans le ClientProxy etc)

    Edit:

    Bon je tente plein plein de trucs, rien ne marche actuellement je tourne autour du pot avec:
    :::

    @SideOnly(Side.CLIENT)
        public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot)
        {
    ModelArmor3D modelArmor3D = new ModelArmor3D();
    if(armorSlot == 1)
    {
    if (entityLiving.isSneaking())
    {
    modelArmor3D.bipedBody.rotateAngleX = 0.5F;
    modelArmor3D.bipedRightArm.rotateAngleX += 0.4F;
    modelArmor3D.bipedLeftArm.rotateAngleX += 0.4F;
    modelArmor3D.bipedRightLeg.rotationPointZ = 4.0F;
    modelArmor3D.bipedLeftLeg.rotationPointZ = 4.0F;
    modelArmor3D.bipedRightLeg.rotationPointY = 9.0F;
    modelArmor3D.bipedLeftLeg.rotationPointY = 9.0F;
    modelArmor3D.bipedHead.rotationPointY = 1.0F;
    modelArmor3D.bipedHeadwear.rotationPointY = 1.0F;
    }
    return new ModelArmor3D();
    }
    return null;
        }
    

    :::

    Je ne comprends pas pourquoi le sneak n'est pas pris en compte alors que c'est extends ModelBiped et que le setRotationAngles me semble bon…