怎样让实体可以被攻击

USS.Shenzhou


版本信息
你使用的系统:win10 2004 x64
你是用的JDK: 8u251
你使用的IDE:IntelliJ IDEA
你使用的IDE版本:2020.2
Forge版本: 31.2.36
Minecraft版本: 1.15.2

简述
我创建了一个实体是ProjectileItemEntity的子类。我想让它能够被攻击(近战/远程)然后remove掉。(有一点像画和展示框的效果)。翻了翻HangingEntityPaintingEntity,只找到了下面两个在被攻击时调用的方法,但是不知道是怎么让它被攻击的。。。

来自HangingEntity.java

   /**
    * Called when a player attacks an entity. If this returns true the attack will not happen.
    */
   public boolean hitByEntity(Entity entityIn) {
      if (entityIn instanceof PlayerEntity) {
         PlayerEntity playerentity = (PlayerEntity)entityIn;
         return !this.world.isBlockModifiable(playerentity, this.hangingPosition) ? true : this.attackEntityFrom(DamageSource.causePlayerDamage(playerentity), 0.0F);
      } else {
         return false;
      }
   }

   /**
    * Called when the entity is attacked.
    */
   public boolean attackEntityFrom(DamageSource source, float amount) {
      if (this.isInvulnerableTo(source)) {
         return false;
      } else {
         if (!this.removed && !this.world.isRemote) {
            this.remove();
            this.markVelocityChanged();
            this.onBroken(source.getTrueSource());
         }

         return true;
      }
   }

FledgeXu


attackEntityFrom不是写了吗?


USS.Shenzhou


我仿造着写了

    @Override
    public boolean hitByEntity(Entity entityIn) {
        if (entityIn instanceof PlayerEntity) {
            PlayerEntity playerentity = (PlayerEntity)entityIn;
            return this.attackEntityFrom(DamageSource.causePlayerDamage(playerentity), 1.0F);
        } else {
            return false;
        }
    }

    @Override
    public boolean attackEntityFrom(DamageSource source, float amount) {
            if (!this.world.isRemote) {
                this.remove();
                this.markVelocityChanged();
            }
            else {
                this.world.addParticle(ParticleTypes.CLOUD,this.getPosX(),this.getPosY(),this.getPosZ(),0,0,0);
            }
            return true;
    }

但是没有什么用。。。。下断点发现这两个方法没有被调用过。。。。(尝试了近战、爆炸和弓箭)
应该有什么方法是关于能不能被攻击的?但是我一直没有找到。


FledgeXu


是不是因为你没攻击到。


USS.Shenzhou


测试的时候箭都是直接从碰撞框里面穿过去的。。。。。应该是程序以为它不可以被攻击?


USS.Shenzhou


更正:爆炸可以摧毁它 但是不知道近战和远程为什么都没用。。



挂画、物品展示框等「被攻击」的效果是在 attackEntityFrom 里实现的。
如果你正确实现了这个方法但毫无效果的话,考虑攻击来源本身认为你的实体不可被攻击,或者没有识别到,比如 AbstractArrowEntity 的逻辑是在 tick 的时候通过 World.rayTraceBlocks 来判断它是不是碰到了某个实体(AbstractArrowEntity.onHitAbstractArrowEntity.onEntityHit 等)。再比如玩家实体的话,是先在客户端上 Minecraft.clickMouse 里进行一次 ray tracing,若结果是命中一个实体,则调用 PlayerController.attackEntity 在客户端进行一次模拟攻击,并发数据包 CUseEntityPacket 请求服务器处理攻击逻辑。


USS.Shenzhou


谢谢!我找到了方法canBeCollidedWith,它在父类Entity中返回的是假,重写为真就好啦 :smile:


system


该主题在最后一个回复创建后7天后自动关闭。不再允许新的回复。