Create a new class that extends GeoModel, then implement all the required methods:
publicclassExampleItemModelextendsGeoModel<ExampleItem> {// Models must be stored in assets/<modid>/geo with subfolders supported inside the geo folderprivatestaticfinalResourceLocation model =newResourceLocation("yournamespace","geo/yourmodel.geo.json");// Textures must be stored in assets/<modid>/textures with subfolders supported inside the textures folderprivatestaticfinalResourceLocation texture =newResourceLocation("yournamespace","textures/<modeltype>/yourtexture.png");// Animations must be stored in assets/<modid>/animations with subfolders supported inside the animations folderprivatestaticfinalResourceLocation animation =newResourceLocation("yournamespace","animations/youranimation.animation.json"); @OverridepublicResourceLocationgetModelResource(ExampleItem object) {returnthis.model; } @OverridepublicResourceLocationgetTextureResource(ExampleItem object) {returnthis.texture; } @OverridepublicResourceLocationgetAnimationResource(ExampleItem object) {returnthis.animation; }}
Creating the renderer class
Create a class that extends GeoItemRenderer, then just set it like so:
publicclassExampleItemRendererextendsGeoItemRenderer<ExampleItem > {publicExampleItemRenderer() {// Register the Model class to this render super(newExampleItemModel()); }}
Registering the renderer
Fabric/NeoForge/Forge 1.20.1+
In your Item class, add:
// For versions 1.21+, Object has been replaced with RenderProvider, and getRenderProvider() is no longer necessary.privatefinalSupplier<RenderProvider> renderProvider =GeoItem.makeRenderer(this);// Creates the renderer@OverridepublicvoidcreateRenderer(Consumer<RenderProvider> consumer) {// Accepts a consumer to create a new rendererconsumer.accept(newRenderProvider() {// Your custom renderer instanceprivateExampleItemRenderer renderer =null; /** * Returns a custom renderer for the block entity, creating a new instance if necessary. * This renderer is used for rendering the block entity in a custom way. * * @return The {@link BlockEntityWithoutLevelRenderer} used for custom rendering of the block entity. */ @OverridepublicBlockEntityWithoutLevelRenderergetCustomRenderer() {// Check if renderer is null; create a new instance if soif (renderer ==null) { renderer =newExampleItemRenderer(); }// Return the existing renderer if it's not nullreturnthis.renderer; } });}/** * Returns the render provider, but this method is no longer necessary for Minecraft 1.21+. * In versions 1.21 and later, you no longer need to call getRenderProvider() or store the renderProvider. * * @return The render provider (not needed in 1.21+). */@OverridepublicSupplier<RenderProvider>getRenderProvider() {return renderProvider;}
Forge 1.19.4 and older
In your Item class, add:
/** * Initializes client-side extensions for the item, including a custom renderer. * This method sets up how the item should be rendered in the game. * * @param consumer A {@link Consumer} that accepts an {@link IClientItemExtensions} object to handle client-side item extensions. */@OverridepublicvoidinitializeClient(Consumer<IClientItemExtensions> consumer) {// Accepts a consumer to create a new rendererconsumer.accept(newIClientItemExtensions() {// Your custom item rendererprivateExampleItemRenderer renderer =null; /** * Provides a custom renderer for the block entity, creating a new instance if it does not already exist. * This method determines how the block entity should be rendered when placed in the world. * * @return The {@link BlockEntityWithoutLevelRenderer} used for custom rendering of the block entity. */ @OverridepublicBlockEntityWithoutLevelRenderergetCustomRenderer() {// Check if renderer is null; create a new instance if soif (renderer ==null) { renderer =newExampleItemRenderer(); }// Return the existing renderer if it's not nullreturnthis.renderer; } });}