本篇教程参考为的NeoForge1.20.4Mod开发的视频,这篇教程是我边学边总结的,与其说是教程更像我的学习笔记,如有不清楚的地方,大家可以在评论区提问。在我力所能及的范围内,我都会解答的。
首先添加一个物品
创建AroundYItem类
public class AroundYItem extends Item {
public AroundYItem() {
super(new Properties());
}
private static final BlockEntityWithoutLevelRenderer R = new AroundYItemRenderer();
@Override
public void initializeClient(Consumer<IClientItemExtensions> consumer) {//接入自定义渲染
consumer.accept(new IClientItemExtensions() {
@Override
public BlockEntityWithoutLevelRenderer getCustomRenderer() {
return R;//返回此物品专用BlockEntityWithoutLevelRenderer
}
});
}
}
创建AroundYItemRenderer类
public class AroundYItemRenderer extends BlockEntityWithoutLevelRenderer {
private int degree = 0;//初始化旋转角度
public AroundYItemRenderer() {
super(null, null);
}
@Override
public void renderByItem(ItemStack stack, ItemDisplayContext displayContext, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {//渲染物品的方法,根据物品类型的不同,选择不同的渲染方式
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();//获取全局渲染器
BakedModel bakedModel = itemRenderer.getModel(stack,null,null,1);//获取此栈当前模型
BakedModel modelToRender = bakedModel instanceof AroundYItemModel aroundYItemModel//若模型是AroundYItemModel,则getOriginalModel()用原本的模型;否则直接用当前模型
? aroundYItemModel.getOriginalModel()
: bakedModel;
if (degree == 360) {degree = 0;}//旋转角度
degree++;
poseStack.pushPose();
poseStack.translate(0.5f, 0.5f, 0.5f);//把旋转中心移到模型中心
poseStack.mulPose(Axis.YP.rotationDegrees(degree));//绕物体y轴旋转
itemRenderer.render(stack, ItemDisplayContext.NONE, false, poseStack, buffer, packedLight, packedOverlay, modelToRender);//绘制模型
poseStack.popPose();
}
}
创建AroundYItemModel类
public class AroundYItemModel implements BakedModel {
private final BakedModel existingModel;
public AroundYItemModel(BakedModel existingModel) {
this.existingModel = existingModel;
}
public BakedModel getOriginalModel() {
return existingModel;
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction direction, RandomSource random) {
return this.existingModel.getQuads(state, direction, random);
}
@Override
public boolean useAmbientOcclusion() {
return existingModel.useAmbientOcclusion();
}
@Override
public boolean isGui3d() {
return existingModel.isGui3d();
}
@Override
public boolean usesBlockLight() {
return existingModel.usesBlockLight();
}
@Override
public boolean isCustomRenderer() {//返回true,使用自定义渲染
return true;
}
@Override
public TextureAtlasSprite getParticleIcon() {
return existingModel.getParticleIcon();
}
@Override
public ItemOverrides getOverrides() {
return existingModel.getOverrides();
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData data, @Nullable RenderType renderType) {
throw new AssertionError("IBakedModel::getQuads should never be called, only IForgeBakedModel::getQuads");
}
}
这个是前面说过的烘焙模型,不一样的是要使用public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction direction, RandomSource random)而不是另一个同名方法
替换模型
Map<ResourceLocation, BakedModel> models = event.getModels();//获取本次烘焙结果里的“模型表”,键是模型资源位置,值是烘焙后的BakedModel
ModelResourceLocation location = new ModelResourceLocation(BuiltInRegistries.ITEM.getKey(ModItems.AROUNDY_ITEM.get()),"inventory");//构造aroundy物品在物品栏场景对应的模型键
BakedModel existingModel = models.get(location);
if (existingModel == null) {
throw new RuntimeException("Did not find Aroundy ");
} else if (existingModel instanceof AroundYItemModel) {
throw new RuntimeException("Tried to replace Wrench twice");
}else {
AroundYItemModel AroundYItemModel = new AroundYItemModel(existingModel);
event.getModels().put(location,AroundYItemModel);
}
最后不要忘记注册和提供模型、材质,之后你就得到了一个围绕自身y轴旋转的物品
如果你想在特定展示环境才显示动画你可以在在AroundYItemModel类中写重写applyTransform方法
public BakedModel applyTransform(ItemDisplayContext ctx, PoseStack poseStack, boolean applyLeftHandTransform) {
if (ctx == ItemDisplayContext.FIRST_PERSON_LEFT_HAND || ctx == ItemDisplayContext.FIRST_PERSON_RIGHT_HAND) {//只在第一人称主手和副手上时才显示动画
return this;
}
return this.existingModel.applyTransform(ctx, poseStack, applyLeftHandTransform);
}
如果写了此方法需要去掉AroundYItemRenderer类中的
BakedModel modelToRender = bakedModel instanceof AroundYItemModel aroundYItemModel
? aroundYItemModel.getOriginalModel()
: bakedModel;
这个是为了防止无限回调,在不是aroundYItemModel时给出默认的模型。applyTransform
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END









暂无评论内容