一.创建三个类分别继承 Entity , EntityRenderer , EntityModel<>

public class FlyingSwordEntity extends Entity {
    public FlyingSwordEntity(EntityType<?> entityType, Level level){
        super(entityType, level);
    }
}
public class FlyingSwordEntityRenderer extends EntityRenderer {
    public FlyingSwordEntityRenderer(EntityRendererProvider.Context context) {
        super(context);
        flyingSwordModel = new FlyingSwordModel(context.bakeLayer(FlyingSwordModel.LAYER_LOCATION));
    }
}
public class FlyingSwordModel extends EntityModel<FlyingSwordEntity> {
    private final ModelPart body;
    public static final ModelLayerLocation LAYER_LOCATION = 
        new ModelLayerLocation(new ResourceLocation(TestMod.MODID, "flying_sword_entity"), "main");

    public FlyingSwordModel(ModelPart modelPart) {
        this.body = modelPart.getChild("body");
    }
}

二.完善FlyingSwordEntity

 private static final EntityDataAccessor<Integer> COUNTER =
    SynchedEntityData.defineId(FlyingSwordEntity.class, EntityDataSerializers.INT);

@Override
public void tick() {
    Integer i=this.entityData.get(COUNTER); //获取实体数据
    if(!this.level().isClientSide()){   //服务端执行逻辑
        this.entityData.set(COUNTER,i+1);   //设置实体数据
    }
    super.tick();
}
@Override
protected void defineSynchedData() {
    this.entityData.define(COUNTER,0);
}
@Override
protected void readAdditionalSaveData(CompoundTag compoundTag) {
    this.entityData.set(COUNTER,compoundTag.getInt("counter"));
}
@Override
protected void addAdditionalSaveData(CompoundTag compoundTag) {
    compoundTag.putInt("counter",this.entityData.get(COUNTER));
}

三. 完善FlyingSwordEntityRenderer

private EntityModel<FlyingSwordEntity> flyingSwordModel;
@Override
public ResourceLocation getTextureLocation(Entity entity) {
    return new ResourceLocation(TestMod.MODID, "textures/entity/flying_sword_entity.png");
}
@Override
public void render(Entity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
    super.render(entity, entityYaw, partialTick, poseStack, buffer, packedLight);
    poseStack.pushPose();
    poseStack.mulPose(Axis.YN.rotationDegrees(45));
    poseStack.translate(0, -1, 0);
    VertexConsumer vertexConsumer = 
        buffer.getBuffer(flyingSwordModel.renderType(getTextureLocation(entity)));
    this.flyingSwordModel.renderToBuffer(
        poseStack,vertexConsumer,packedLight, 
        OverlayTexture.NO_OVERLAY,1f,1f,1f,1f
    );
    poseStack.popPose();
}

四.把这三个东西注册到游戏中

先注册Entity,另外两个有点特殊

public static final DeferredRegister<EntityType<?>> ENTITY_TYPES =
            DeferredRegister.create(Registries.ENTITY_TYPE, TestMod.MODID);
public static final Supplier<EntityType<FlyingSwordEntity>> FLYING_SWORD_ENTITY =
            ENTITY_TYPES.register("flying_sword_entity",
                    () -> EntityType.Builder.of(FlyingSwordEntity::new, MobCategory.MISC).sized(2, 0.5F).build("flying_sword_entity"));

记得放进线程
ENTITY_TYPES.register(bus);
然后再注册另外两个

@SubscribeEvent
public static void registerEntityLayers(EntityRenderersEvent.RegisterLayerDefinitions evt) {
    evt.registerLayerDefinition(FlyingSwordModel.LAYER_LOCATION, FlyingSwordModel::createBodyLayer);
}
@SubscribeEvent
public static void onClientEvent(FMLClientSetupEvent event){
    event.enqueueWork(()->{
        EntityRenderers.register(Registry.FLYING_SWORD_ENTITY.get(), FlyingSwordEntityRenderer::new);
    });
}

最后导入材质,进入游戏就可以用summon指令生成我们的实体啦

附完整代码

FlyingSwordEntity

import com.mojang.logging.LogUtils;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import org.slf4j.Logger;
import net. minecraft. world. level. Level;

public class FlyingSwordEntity extends Entity {
    private static final Logger LOGGER = LogUtils.getLogger();  //创建日志
    //实体数据同步器(INT类型)
    private static final EntityDataAccessor<Integer> COUNTER =
            SynchedEntityData.defineId(FlyingSwordEntity.class, EntityDataSerializers.INT);
    @Override
    public void tick() {
        Integer i=this.entityData.get(COUNTER); //获取实体数据
        LOGGER.info(i.toString());  //打印日志
        if(!this.level().isClientSide()){   //服务端执行逻辑
            this.entityData.set(COUNTER,i+1);   //设置实体数据
        }
        super.tick();
    }
    //构造方法
    public FlyingSwordEntity(EntityType<?> entityType, Level level){
        super(entityType, level);
    }
    //实体数据同步器初始化
    @Override
    protected void defineSynchedData() {
        this.entityData.define(COUNTER,0);
    }
    @Override
    protected void readAdditionalSaveData(CompoundTag compoundTag) {
        this.entityData.set(COUNTER,compoundTag.getInt("counter"));
    }
    @Override
    protected void addAdditionalSaveData(CompoundTag compoundTag) {
        compoundTag.putInt("counter",this.entityData.get(COUNTER));
    }

}

FlyingSwordEntityRenderer

import com.XXXYJade17.TestMod.TestMod;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;

public class FlyingSwordEntityRenderer extends EntityRenderer {
    private EntityModel<FlyingSwordEntity> flyingSwordModel;
    public FlyingSwordEntityRenderer(EntityRendererProvider.Context context) {
        super(context);
        flyingSwordModel = new FlyingSwordModel(context.bakeLayer(FlyingSwordModel.LAYER_LOCATION));
    }
    @Override
    public ResourceLocation getTextureLocation(Entity entity) {
        return new ResourceLocation(TestMod.MODID, "textures/entity/flying_sword_entity.png");
    }
    @Override
    public void render(Entity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
        super.render(entity, entityYaw, partialTick, poseStack, buffer, packedLight);
        poseStack.pushPose();
        poseStack.mulPose(Axis.YN.rotationDegrees(45));
        poseStack.translate(0, -1, 0);
        VertexConsumer vertexConsumer = buffer.getBuffer(flyingSwordModel.renderType(getTextureLocation(entity)));
        this.flyingSwordModel.renderToBuffer(poseStack,vertexConsumer,packedLight, OverlayTexture.NO_OVERLAY,1f,1f,1f,1f);
        poseStack.popPose();
    }
}

FlyingSwordModel

import com.XXXYJade17.TestMod.TestMod;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.*;
import net.minecraft.resources.ResourceLocation;

public class FlyingSwordModel extends EntityModel<FlyingSwordEntity> {
    public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(TestMod.MODID, "flying_sword_entity"), "main");
    private final ModelPart body;

    public FlyingSwordModel(ModelPart modelPart) {
        this.body = modelPart.getChild("body");
    }
    public static LayerDefinition createBodyLayer() {
        MeshDefinition meshDefinition = new MeshDefinition();   // 创建网格定义
        PartDefinition partDefinition = meshDefinition.getRoot();
        PartDefinition body= partDefinition.addOrReplaceChild("body",
                CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -1.0F, -18.0F, 3.0F, 1.0F, 19.0F, new CubeDeformation(0.0F))
                .texOffs(0, 20).addBox(-3.0F, -2.0F, -1.0F, 7.0F, 3.0F, 3.0F, new CubeDeformation(0.0F))
                .texOffs(0, 0).addBox(-1.0F, -1.0F, 1.0F, 3.0F, 1.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 23.0F, 0.0F));
        return LayerDefinition.create(meshDefinition, 64, 64);
    }

    @Override
    public void setupAnim(FlyingSwordEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
        //置剑身体body的三维旋转角度,分别对应于X轴(pLimbSwing)、Y轴(pNetHeadYaw)和Z轴(pHeadPitch)的旋转。
        body.xRot = limbSwing;
        body.yRot = netHeadYaw;
        body.zRot = headPitch;
    }

    @Override
    public void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
        body.render(poseStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
    }
}

ClientEventHandler

import com.XXXYJade17.TestMod.Registry;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD,value = Dist.CLIENT)
public class ClientEventHandler {
    @SubscribeEvent
    public static void registerEntityLayers(EntityRenderersEvent.RegisterLayerDefinitions evt) {
        evt.registerLayerDefinition(FlyingSwordModel.LAYER_LOCATION, FlyingSwordModel::createBodyLayer);
    }
    @SubscribeEvent
    public static void onClientEvent(FMLClientSetupEvent event){
        event.enqueueWork(()->{
            EntityRenderers.register(Registry.FLYING_SWORD_ENTITY.get(), FlyingSwordEntityRenderer::new);
        });
    }
}