Bukkit / Spigot-命中检测中的弹丸位置完全错误

问题描述 投票:0回答:1

我正在为Minecraft服务器制作自定义的“枪支”插件。我的问题是,当尝试检测弹丸降落的位置时,弹丸与被击中的玩家之间的位置差异太大,无法用我的爆头方法检测到。我对'isHeadshot'使用射弹跟踪的唯一原因是由于调试试验。

这是我的拍摄方法

public void shootGun(Player p) {
        if (getFirearmAction().isDelayed(p))
            return;

        double shiftYaw = (p.getLocation().getYaw() + 180) * (Math.PI/180);
        Vector shiftVec = new Vector(Math.cos(shiftYaw), 0.0D, Math.sin(shiftYaw)); //TODO: add bullet_spread


        for (int i = 0; i < projectileInfo.getAmount(); i++) {
            Projectile proj = (Projectile)p.getWorld().spawn(p.getEyeLocation().toVector().add(shiftVec.multiply(0.2D)).toLocation(p.getWorld()), getProjectileInfo().getProjectileClass());
            proj.setVelocity(UtilMethods.getBulletVelocity(p).multiply(projectileInfo.getSpeed()));
            proj.setShooter(p);
        }
        projectileInfo.playShootGunSound(p);
        getFirearmAction().performAction(p);
    }

这是'hit'的侦听器

@EventHandler
    public void onEntDamage(EntityDamageByEntityEvent event) {
        if (event.getDamager() instanceof Projectile) {
            Projectile p = (Projectile)event.getDamager();
            if (p.getShooter() instanceof Player) {
                Player player = (Player)p.getShooter();
                Gun gun = UtilMethods.getGun(player);
                if (gun != null) {
                    int damage = gun.getProjectileInfo().getDamage();
                    if (event.getEntity() instanceof Player) {
                        Player ent = (Player)event.getEntity();

                        if (UtilMethods.isHeadShot(ent, p))
                            damage *= 2;
                    }
                    event.setDamage(damage);
                }
            }
        }
    }

最后,这是[isHeadshot,isInCuboid和bulletVelocity]方法。前两种是尝试找出失败的爆头检测的替代方法... getBulletVelocity方法设置正确的射弹速度和方向。 (在这种情况下,我正在使用Snowball.class)

public static boolean isHeadShot(Player victim, Projectile projectile) {

        Location locA = new Location(victim.getWorld(), victim.getEyeLocation().getX() -0.5, victim.getEyeLocation().getY() - 0.5, victim.getEyeLocation().getZ() - 0.5);
        Location locB = new Location(victim.getWorld(), victim.getEyeLocation().getX() +0.5, victim.getEyeLocation().getY() + 0.5, victim.getEyeLocation().getZ() + 0.5);

        for (double i = 0; i < 256; i+=0.8D) {
            System.out.println(projectile.getLocation() + " | " + victim.getLocation());
            projectile.getLocation().add(projectile.getVelocity().normalize().multiply(i));
            if (isInCuboid(locA, locB, projectile.getLocation())) {
                System.out.println(i);
                return true;
            }
        }
        return false;
    }

    public static boolean isInCuboid(Location min, Location max, Location varying) {
        double[] locs = new double[2];
        locs[0] = min.getX();
        locs[1] = max.getX();
        Arrays.sort(locs);
        if (varying.getX() > locs[1] || varying.getX() < locs[0])
            return false;
        locs[0] = min.getY();
        locs[1] = max.getY();
        Arrays.sort(locs);
        if (varying.getY() > locs[1] || varying.getY() < locs[0])
            return false;
        locs[0] = min.getZ();
        locs[1] = max.getZ();
        Arrays.sort(locs);
        if (varying.getZ() > locs[1] || varying.getZ() < locs[0])
            return false;
        return true;
    }

    public static Vector getBulletVelocity(Player shooter) {
        double yaw = Math.toRadians((-shooter.getLocation().getYaw() - 90.0f));
        double pitch = Math.toRadians(-shooter.getLocation().getPitch());

        double x = Math.cos(pitch) * Math.cos(yaw);
        double y = Math.sin(pitch);
        double z = -Math.sin(yaw) * Math.cos(pitch);

        Vector dirVec = new Vector(x, y, z).normalize();
        return dirVec;
    }

我希望获得帮助,因为似乎当子弹造成损坏时,子弹已经通过了玩家的打击盒,因此不再被视为爆头。有什么建议吗?

这是位置差异。第一位置是弹丸,第二位置是受害者。但是,要想被击中,子弹必须在某一时刻通过玩家。.

[[08:53:22] [服务器线程/信息]:位置{world = CraftWorld {name = San_Andreas},x = 2501.8249706725665,y = 73.62000000476837,z = 1681.0750064188326,pitch = 0.0,yaw = 0.0} |位置{world = CraftWorld {name = San_Andreas},x = 2508.7144181513295,y = 72.0,z = 1671.9424013003206,pitch = 0.3,yaw = -8.100003}

vector collision-detection bukkit projectile aabb
1个回答
0
投票

ProjectileHitEvent并检查射弹的y坐标是否位于击中玩家眼睛位置的y坐标的一定距离内(x和z坐标与确定玩家的爆头无关。) >

© www.soinside.com 2019 - 2024. All rights reserved.