Dao_Za
本帖最后由 Dao_Za 于 2021-9-24 17:27 编辑

如题,在开发1.16.5的模组,发现投掷物/生物/掉落物(自定义EntityItem)无法渲染,参考其他模组的办法也不行,
不知道是哪里出了问题。

已知成功生成投掷物entity、可以成功攻击敌人。(可击中对象/掉落物品)
问题:投出后为隐形,即无法渲染。


或者大佬们不用看我的代码也可以,举个渲染成功的例子也可以,谢过了。
不过论坛添加太多代码会吞,所以贴文本。
======
投掷物源码:
public class Entity_dirt extends ProjectileItemEntity
{
//设置投掷伤害,撞击后是否掉落,掉落什么。
    public float damage = 3.0F;
    public boolean     dropitem = false;
    public Item     iconitem = Regitem.throw_dirt;
//基础属性设置
    public Entity_dirt(EntityType<? extends Entity_dirt> type, World w)
    {
        super(type, w);
    }  
    public Entity_dirt( World w, LivingEntity ee)
    {
        super(RegTEBALL.TR_DIRT.get() , ee, w);
    }
    public Entity_dirt( World w, double x, double y, double z)
    {
        super(RegTEBALL.TR_DIRT.get() , x, y, z, w);
    }
    public Entity_dirt(FMLPlayMessages.SpawnEntity entity, World world)
    {
        this( RegTEBALL.TR_DIRT.get() , world);
        setDeltaMovement(entity.getVelX(), entity.getVelY(), entity.getVelZ());
        lerpHeadTo(entity.getYaw(), entity.getPitch());
        setPos(entity.getPosX(), entity.getPosY(), entity.getPosZ());
    }
    protected Item getDefaultItem()
    {
        return iconitem;
    }

//撞击粒子效果

    @OnlyIn(Dist.CLIENT)
    public void handleEntityEvent(byte p_70103_1_)
    {
        if (p_70103_1_ == 3)
        {
            for(int i = 0; i < 8; ++i)
                this.level.addParticle(new ItemParticleData(ParticleTypes.ITEM, this.getItem()),
                        this.getX(), this.getY(), this.getZ(), ((double)this.random.nextFloat() - 0.5D) * 0.08D,
                        ((double)this.random.nextFloat() - 0.5D) * 0.08D, ((double)this.random.nextFloat() - 0.5D) * 0.08D);
        }
    }

//重力系数,影响投掷曲线

    protected float getGravity() {
        return 0.01F;
    }
//当击中生物

    protected void onHitEntity(EntityRayTraceResult mop)
    {
        super.onHitEntity(mop);
        if(mop.getEntity() instanceof LivingEntity && !(mop.getEntity() instanceof PlayerEntity))
        {
            LivingEntity hitted = (LivingEntity)mop.getEntity();  
            hitted.hurt(DamageSource.thrown(this, this.getOwner()), this.damage);
            hitted.addEffect(new EffectInstance(Effects.MOVEMENT_SLOWDOWN , 140, 0));
            hitted.knockback(0.5F, this.getX() -hitted.getX() , this.getZ() -hitted.getZ());  
        }
    }
//当击中任何对象(这里写方块。实际上包括了击中生物)

    protected void onHit(RayTraceResult mop)
    {
        super.onHit(mop);
        if (!this.level.isClientSide)
        {
            if(this.dropitem && mop.getType().equals(RayTraceResult.Type.BLOCK))//need not hit entity
                level.addFreshEntity(new ItemEntity(this.level, this.getX(), this.getY() + 1, this.getZ(), new ItemStack(    iconitem) ));
            this.level.broadcastEntityEvent(this, (byte)3);//>> BYTE is for client render break particle upside
            this.remove();
        }
    }  
}

======
1.另起文件注册Entity们,入一下户口:下记注册setCustomClientFactory()报错,不知如何解。于是注释掉。
会不会就是它引起无法渲染??*

public class RegTEBALL {
//实体类型

   public static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Main.MODID);
//注册方法
   private static <T extends net.minecraft.entity.Entity> RegistryObject<EntityType<T>> registerBasic(String name,
    BiFunction<    EntityType<T>,    World, T    > function)
   {
   EntityType<T> type = EntityType.Builder.of(function::apply, EntityClassification.MISC).sized(0.25F, 0.25F)
   .setTrackingRange(100).setUpdateInterval(1).noSummon().fireImmune().setShouldReceiveVelocityUpdates(true).build(name);
   //.setCustomClientFactory( () -> type )
        return ENTITIES.register(name, () -> type);
   }
//添加具体实体:投掷泥巴
   public static final RegistryObject<        EntityType<  Entity_dirt >>   TR_DIRT    = registerBasic("entity_dirt", Entity_dirt::new);
}

======
2.在主类main:登记(成功)
public Main() {
//注册上方实体

    RegTEBALL.ENTITIES.register(     FMLJavaModLoadingContext.get().getModEventBus()     );
//注册main内所有event   

MinecraftForge.EVENT_BUS.register(this);
}
======
3.在主类的FMLClientSetupEvent 注册渲染。(渲染失败)
试了2种方法都不行。
①问题点不知道是不是在SpriteRenderer: net.minecraft.client.renderer.entity.SpriteRenderer;
②另外又试了自定义渲染RenderBall,貌似也不行,投出去还是【隐形】的,但是确信有成功投出物品了。

//玩家端渲染
public void clientSetup(FMLClientSetupEvent event) {
//METHOD 1:自定义渲染方法:RenderBall
  RenderingRegistry.registerEntityRenderingHandler(    RegTEBALL.TR_DIRT.get() ,
  renderManager ->  new RenderBall<Entity_dirt>(renderManager, Minecraft.getInstance().getItemRenderer()));

//或者使用METHOD 2.MC默认渲染方法:SpriteRenderer
  RenderingRegistry.registerEntityRenderingHandler(    RegTEBALL.TR_STONE.get() ,
  renderManager ->  new SpriteRenderer<Entity_stone>(renderManager, Minecraft.getInstance().getItemRenderer()));
}

======
4.上边使用的自定义渲染RenderBall方法,感觉是public void render(T entity...)不对?

//参考了其它MOD
@OnlyIn(Dist.CLIENT)
public class RenderBall<    T extends ProjectileItemEntity    > extends SpriteRenderer<    T >
{
    private final net.minecraft.client.renderer.ItemRenderer itemRenderer;
    private final float scale;
    public RenderBall(EntityRendererManager rm, ItemRenderer ir)
    {
        this(rm, ir, 1.0F, true);
    }  
    public RenderBall(EntityRendererManager rm, ItemRenderer ir, float scale, boolean p_i226035_4_)
    {
        super(rm, ir, scale, p_i226035_4_);
        this.itemRenderer = ir;
        this.scale = scale;
    }   
//关键渲染方法,可能问题出在这里??但是原版EGG,SNOWBALL都没有写有参考意义的代码...
public void render(T entity, float entityYaw, float partialTicks, MatrixStack matrices, IRenderTypeBuffer buffer, int light)
    {
        if (entity.tickCount > 2 || !(this.entityRenderDispatcher.camera.getEntity().distanceToSqr(entity) < 12.25D))//!entity.isInvisible() ||
        {
            matrices.pushPose();
            //matrices.mulPose(Vector3f.YP.rotationDegrees(180.0F));
            //matrices.mulPose(Vector3f.YP.rotationDegrees(entityYaw));
            //matrices.mulPose(Vector3f.XP.rotationDegrees(entity.xRot));
            //this.itemRenderer.renderStatic(entity.getItem(), ItemCameraTransforms.TransformType.NONE,
            //        light, OverlayTexture.NO_OVERLAY, matrices, buffer);

            matrices.scale(this.scale, this.scale, this.scale);
            matrices.mulPose(this.entityRenderDispatcher.cameraOrientation());
            matrices.mulPose(Vector3f.YP.rotationDegrees(180.0F));
            this.itemRenderer.renderStatic(entity.getItem(), ItemCameraTransforms.TransformType.GROUND,
                    light, OverlayTexture.NO_OVERLAY, matrices, buffer);

            matrices.popPose();
            super.render(entity, entityYaw, partialTicks, matrices, buffer, light);
        }
    }
}

======



2021.12 数据,可能有更多内容如题,在开发1.16.5的模组,发现投掷物/生物/掉落物(自定义EntityItem)无法渲染,参考其他模组的办法也不行,
不知道是哪里出了问题。


已知成功生成投掷物entity、可以成功攻击敌人。(可击中对象/掉落物品)
问题:投出后为隐形,即无法渲染。



或者大佬们不用看我的代码也可以,举个渲染成功的例子也可以,谢过了。
不过论坛添加太多代码会吞,所以贴文本。
======
投掷物源码:
public class Entity_dirt extends ProjectileItemEntity
{
//设置投掷伤害,撞击后是否掉落,掉落什么。
    public float damage = 3.0F;
    public boolean  dropitem = false;
    public Item  iconitem = Regitem.throw_dirt;
//基础属性设置
    public Entity_dirt(EntityType&lt;? extends Entity_dirt&gt; type, World w)
    {
  super(type, w);
    }
    public Entity_dirt( World w, LivingEntity ee)
    {
  super(RegTEBALL.TR_DIRT.get() , ee, w);
    }
    public Entity_dirt( World w, double x, double y, double z)
    {
  super(RegTEBALL.TR_DIRT.get() , x, y, z, w);
    }
    public Entity_dirt(FMLPlayMessages.SpawnEntity entity, World world)
    {
  this( RegTEBALL.TR_DIRT.get() , world);
  setDeltaMovement(entity.getVelX(), entity.getVelY(), entity.getVelZ());
  lerpHeadTo(entity.getYaw(), entity.getPitch());
  setPos(entity.getPosX(), entity.getPosY(), entity.getPosZ());
    }
    protected Item getDefaultItem()
    {
  return iconitem;
    }


//撞击粒子效果


    @OnlyIn(Dist.CLIENT)
    public void handleEntityEvent(byte p_70103_1_)
    {
  if (p_70103_1_ == 3)
  {
   for(int i = 0; i &lt; 8; ++i)
    this.level.addParticle(new ItemParticleData(ParticleTypes.ITEM, this.getItem()),
   this.getX(), this.getY(), this.getZ(), ((double)this.random.nextFloat() - 0.5D) * 0.08D,
   ((double)this.random.nextFloat() - 0.5D) * 0.08D, ((double)this.random.nextFloat() - 0.5D) * 0.08D);
  }
    }


//重力系数,影响投掷曲线


    protected float getGravity() {
  return 0.01F;
    }
//当击中生物


    protected void onHitEntity(EntityRayTraceResult mop)
    {
  super.onHitEntity(mop);
  if(mop.getEntity() instanceof LivingEntity &amp;&amp; !(mop.getEntity() instanceof PlayerEntity))
  {
   LivingEntity hitted = (LivingEntity)mop.getEntity();
   hitted.hurt(DamageSource.thrown(this, this.getOwner()), this.damage);
   hitted.addEffect(new EffectInstance(Effects.MOVEMENT_SLOWDOWN , 140, 0));
   hitted.knockback(0.5F, this.getX() -hitted.getX() , this.getZ() -hitted.getZ());
  }
    }
//当击中任何对象(这里写方块。实际上包括了击中生物)


    protected void onHit(RayTraceResult mop)
    {
  super.onHit(mop);
  if (!this.level.isClientSide)
  {
   if(this.dropitem &amp;&amp; mop.getType().equals(RayTraceResult.Type.BLOCK))//need not hit entity
    level.addFreshEntity(new ItemEntity(this.level, this.getX(), this.getY() + 1, this.getZ(), new ItemStack(    iconitem) ));
   this.level.broadcastEntityEvent(this, (byte)3);//&gt;&gt; BYTE is for client render break particle upside
   this.remove();
  }
    }
}


======
1.另起文件注册Entity们,入一下户口:下记注册setCustomClientFactory()报错,不知如何解。于是注释掉。
会不会就是它引起无法渲染??*


public class RegTEBALL {
//实体类型


   public static final DeferredRegister&lt;EntityType&lt;?&gt;&gt; ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Main.MODID);
//注册方法
   private static &lt;T extends net.minecraft.entity.Entity&gt; RegistryObject&lt;EntityType&lt;T&gt;&gt; registerBasic(String name,
    BiFunction&lt;    EntityType&lt;T&gt;,    World, T    &gt; function)
   {
   EntityType&lt;T&gt; type = EntityType.Builder.of(function::apply, EntityClassification.MISC).sized(0.25F, 0.25F)
   .setTrackingRange(100).setUpdateInterval(1).noSummon().fireImmune().setShouldReceiveVelocityUpdates(true).build(name);
   //.setCustomClientFactory( () -&gt; type )
  return ENTITIES.register(name, () -&gt; type);
   }
//添加具体实体:投掷泥巴
   public static final RegistryObject&lt;  EntityType&lt;Entity_dirt &gt;&gt;   TR_DIRT    = registerBasic(&quot;entity_dirt&quot;, Entity_dirt::new);
}


======
2.在主类main:登记(成功)
public Main() {
//注册上方实体


    RegTEBALL.ENTITIES.register(  FMLJavaModLoadingContext.get().getModEventBus()  );
//注册main内所有event   


MinecraftForge.EVENT_BUS.register(this);
}
======
3.在主类的FMLClientSetupEvent 注册渲染。(渲染失败)
试了2种方法都不行。
①问题点不知道是不是在SpriteRenderer: net.minecraft.client.renderer.entity.SpriteRenderer;
②另外又试了自定义渲染RenderBall,貌似也不行,投出去还是【隐形】的,但是确信有成功投出物品了。


//玩家端渲染
public void clientSetup(FMLClientSetupEvent event) {
//METHOD 1:自定义渲染方法:RenderBall
RenderingRegistry.registerEntityRenderingHandler(    RegTEBALL.TR_DIRT.get() ,
renderManager -&gt;new RenderBall&lt;Entity_dirt&gt;(renderManager, Minecraft.getInstance().getItemRenderer()));


//或者使用METHOD 2.MC默认渲染方法:SpriteRenderer
RenderingRegistry.registerEntityRenderingHandler(    RegTEBALL.TR_STONE.get() ,
renderManager -&gt;new SpriteRenderer&lt;Entity_stone&gt;(renderManager, Minecraft.getInstance().getItemRenderer()));
}


======
4.上边使用的自定义渲染RenderBall方法,感觉是public void render(T entity...)不对?
//参考了其它MOD
@OnlyIn(Dist.CLIENT)
public class RenderBall&lt;    T extends ProjectileItemEntity    &gt; extends SpriteRenderer&lt;    T &gt;
{
    private final net.minecraft.client.renderer.ItemRenderer itemRenderer;
    private final float scale;
    public RenderBall(EntityRendererManager rm, ItemRenderer ir)
    {
  this(rm, ir, 1.0F, true);
    }
    public RenderBall(EntityRendererManager rm, ItemRenderer ir, float scale, boolean p_i226035_4_)
    {
  super(rm, ir, scale, p_i226035_4_);
  this.itemRenderer = ir;
  this.scale = scale;
    }   
//关键渲染方法,可能问题出在这里??但是原版EGG,SNOWBALL都没有写有参考意义的代码...
public void render(T entity, float entityYaw, float partialTicks, MatrixStack matrices, IRenderTypeBuffer buffer, int light)
    {
  if (entity.tickCount &gt; 2 || !(this.entityRenderDispatcher.camera.getEntity().distanceToSqr(entity) &lt; 12.25D))//!entity.isInvisible() ||
  {
   matrices.pushPose();
   //matrices.mulPose(Vector3f.YP.rotationDegrees(180.0F));
   //matrices.mulPose(Vector3f.YP.rotationDegrees(entityYaw));
   //matrices.mulPose(Vector3f.XP.rotationDegrees(entity.xRot));
   //this.itemRenderer.renderStatic(entity.getItem(), ItemCameraTransforms.TransformType.NONE,
   //  light, OverlayTexture.NO_OVERLAY, matrices, buffer);


   matrices.scale(this.scale, this.scale, this.scale);
   matrices.mulPose(this.entityRenderDispatcher.cameraOrientation());
   matrices.mulPose(Vector3f.YP.rotationDegrees(180.0F));
   this.itemRenderer.renderStatic(entity.getItem(), ItemCameraTransforms.TransformType.GROUND,
  light, OverlayTexture.NO_OVERLAY, matrices, buffer);


   matrices.popPose();
   super.render(entity, entityYaw, partialTicks, matrices, buffer, light);
  }
    }
}


======



第一页 上一页 下一页 最后一页