tutorial:model_predicate_providers

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
tutorial:model_predicate_providers [2021/03/05 18:49] – created oroarmortutorial:model_predicate_providers [2025/04/02 04:20] (current) – [Model Predicate Providers (before 1.21.5)] solidblock
Line 1: Line 1:
-====== Model Predicate Providers =======+====== Model Predicate Providers (before 1.21.4) =======
  
-==== Introduction ====+:!: Model predicate providers are removed since 1.21.4. Since 1.21.4, please use items model definition instead. See [[https://minecraft.wiki/w/Items_model_definition|Minecraft Wiki]] for details. 
 + 
 +===== Introduction =====
  
 Model providers are used to dynamically change the model of items based on data from ''ItemStack''s. A common example is the bow, which has different textures based on how long the bow has been pulled. All providers are then used in the model file for the item, in the ''overrides'' section. Model providers are used to dynamically change the model of items based on data from ''ItemStack''s. A common example is the bow, which has different textures based on how long the bow has been pulled. All providers are then used in the model file for the item, in the ''overrides'' section.
  
-==== Practical Example ====+===== Practical Example =====
  
-For this example, let's say we have we have a custom bow item called ''EXAMPLE_BOW''.+For this example, assume we have we have a custom bow item called ''TutorialItems.EXAMPLE_BOW''
 + 
 +Inside a method, we register a ''ModelPredicateProvider'' with our item and an ''Identifier''. For the ''Identifier''s use, you do not need to provide a namespace, as none of these should conflict with Minecraft's providers. This must be done in the ''onInitializeClient'' method of your ''ClientModInitializer''. If you do not have a ''ClientModInitializer'', look at the [[documentation:entrypoint|entrypoints]] tutorial on how to add one.
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
 +@Environment(EnvType.CLIENT)
 +public class ExampleModClient implements ClientModInitializer {
 +  public static void registerModelPredicateProviders() {
 +    // For versions before 1.21, replace 'Identifier.ofVanilla' with 'new Identifier'.
 +    ModelPredicateProviderRegistry.register(EXAMPLE_BOW, Identifer.ofVanilla("pull"), (itemStack, clientWorld, livingEntity, seed) -> {
 +      if (livingEntity == null) {
 +        return 0.0F;
 +      }
 +      return livingEntity.getActiveItem() != itemStack ? 0.0F : (itemStack.getMaxUseTime(livingEntity) - livingEntity.getItemUseTimeLeft()) / 20.0F;
 +    });
 +
 +    ModelPredicateProviderRegistry.register(EXAMPLE_BOW, Identifier.ofVanilla("pulling"), (itemStack, clientWorld, livingEntity, seed) -> {
 +      if (livingEntity == null) {
 +        return 0.0F;
 +      }
 +      return livingEntity.isUsingItem() && livingEntity.getActiveItem() == itemStack ? 1.0F : 0.0F;
 +    });
 +  }
 +  
 +  @Override
 +  public void onInitializeClient() {
 +    // ...
 +    registerModelPredicateProviders();
 +  }
 +}
 +</code>
 +
 +If the ''ModelPredicateProviderRegistry'' does not exist in some versions, you may use ''FabricModelPredicateProviderRegistry''.
 +
 +The ''ModelPredicateProvider'' is a Functional Interface that takes in an ''ItemStack'' for the current stack that is being rendered, a ''ClientWorld'' for the current world that the client is in, and a ''LivingEntity'' as the user of the item (In 1.17+, it also takes in an ''int'').
 +
 +All ''ModelPredicateProvider'' returns a float, which can be used to represent different states for the model, or a true/false value by returning ''1.0f'' and ''0f'' respectively. The float value will be clamped between 0.0f and 1.0f.
 +
 +Taking a closer look at the ''pull'' predicate, we see that we first check if the entity is null, as items can be rendered outside of a context where they are being used (i.e. dropped on the ground). We then make sure that the entity is using our item, otherwise the item could have the model predicate apply when not being used. Finally, we subtract the ''livingEntity.getItemUseTimeLeft()'' from the ''itemStack.getMaxUseTime(livingEntity)'' which tells us how many ticks the item has been held for. Because it takes 20 ticks or one second to fully charge a bow, we then divide this number by ''20.0f'' to normalize it to between ''0f'' and ''1.0f'' for the normal pull progress.
  
-FabricModelPredicateProviderRegistry.register(EXAMPLE_BOWnew Identifier("pull"), (itemStack, clientWorld, livingEntity) -> { +All of this is usefulbut is only half of the features we need to implement in order to have our item change its model.
- if (livingEntity == null) { +
- return 0.0F; +
-+
- return livingEntity.getActiveItem() != itemStack ? 0.0F : (itemStack.getMaxUseTime() - livingEntity.getItemUseTimeLeft()) / 20.0F; +
-});+
  
-FabricModelPredicateProviderRegistry.register(EXAMPLE_BOW, new Identifier("pulling")(itemStackclientWorld, livingEntity) -> +<code javascript resources/data/tutorial/models/item/example_bow.json> 
- if (livingEntity == null) +
- return 0.0F; +    // [...] 
-+    "overrides":
- return livingEntity.isUsingItem() && livingEntity.getActiveItem() == itemStack ? 1.0F : 0.0F; +        { 
-});+            "predicate":
 +                "pulling": 1 
 +            }, 
 +            "model": "tutorial:item/example_bow_pulling_0" 
 +        }, 
 +        
 +            "predicate": 
 +                "pulling": 1, 
 +                "pull": 0.65 
 +            }, 
 +            "model": "tutorial:item/example_bow_pulling_1" 
 +        }, 
 +        { 
 +            "predicate":
 +                "pulling": 1
 +                "pull": 0.
 +            }, 
 +            "model": "tutorial:item/example_bow_pulling_2" 
 +        } 
 +    ] 
 +}
 </code> </code>
  
 +The way that Minecraft works is that it checks to see which model is last in the list that either matches or has values greater than specified. so with a pull value of ''0.8'', we would use model ''tutorial:item/example_bow_pulling_1''. ''0.5'' would be ''tutorial:item/example_bow_pulling_0''.
tutorial/model_predicate_providers.1614970189.txt.gz · Last modified: 2021/03/05 18:49 by oroarmor