Альтернатива AABB не привязанная к сетке

Версия Minecraft
1.20.1
API
Forge
95
4
6
Я хочу получить мобов находящихся перед игроком, на определённом расстоянии, но AABB привязан к квадратной сетке и поэтому не позволяет учитывать поворот камеры, есть ли альтернатива AABB которая позволяет это учитывать?
 
есть ли альтернатива AABB которая позволяет это учитывать?
Только если самопис.

Я хочу получить мобов находящихся перед игроком, на определённом расстоянии, но AABB привязан к квадратной сетке и поэтому не позволяет учитывать поворот камеры,
Не проще ли кидать луч к сущностям в радиусе (с трешхолдом, конечно же), а затем проверять видимость его перед игроком?
Или просто изменять размеры AABB в зависимости от поворота игрока, кидать лучи к сущностям и проверять на видимость.
Наилучший вариант - воспользоваться математикой для определения сущностей внутри равнобедренного треугольника.
 
Долго думал над разными способами узнать находится ли моб у игрока на виду, решил сделать через скалярное произведение. Я считаю вектор координат моба относительно игрока, потом косинус угла между векторами Player.getLookAngle() и нормализованным вектором позиции моба, далее остаётся только сравнить полученный косинус с косинусом желаемого угла. Единственное что есть небольшая проблема с тем, что при больших углах игрок может не видеть моба если повернёт камеру вниз или вверх, а этот моб всё равно будет выбран, но для меня это не является проблемой

Вот код::
    private LivingEntity getNearestLivingEntity(Level pLevel, Player pPlayer) {
        Vec3 playerVec = pPlayer.getLookAngle();

        LivingEntity nearest = null;
        Vec3 posVector;
        Vec3 posVectorNormalized;
        double cos;
        double dist = Integer.MAX_VALUE;

        List<LivingEntity> li = getEntitiesInRadius(pLevel, range, (int)pPlayer.getX(), (int)pPlayer.getY(), (int)pPlayer.getZ());

        for (LivingEntity livingEntity : li) {
            if(livingEntity == pPlayer) continue;

            posVector = livingEntity.position().subtract(pPlayer.position());
            posVectorNormalized = (livingEntity.position().subtract(pPlayer.position())).normalize();
            cos = RechromaMathHelper.cosFromScalarProduct(posVectorNormalized, playerVec.normalize());


            if(dist > posVector.length() && cos >= 0.5) {
                nearest = livingEntity;
                dist = posVector.length();
            }
        }

        return nearest;
    }

    private List<LivingEntity> getEntitiesInRadius(Level pLevel, int r, int x, int y, int z) {
        return pLevel.getEntitiesOfClass(LivingEntity.class, new AABB(x-r,y-r,z-r,x+r,y+r,z+r));
    }
 
Строки 15-16 выглядят сомнительно.
Окей, рассчитал posVector, но зачем тогда выделять память под нормализованный, если он используется только в вычислении косинуса? Не проще ли передавать в RechromaMathHelper#cosFromScalarProduct posVector.normalize(), как то ты делаешь с playerVec?

LivingEntity nearest = null;
Вот так делать тоже нежелательно. Для этого нужны Optional.

Единственное что есть небольшая проблема с тем, что при больших углах игрок может не видеть моба если повернёт камеру вниз или вверх, а этот моб всё равно будет выбран
Это связано с тем, что разрешение экрана не 1:1. Иначе говоря, для нахождения сущностей по вертикали используется тот же угол, что и при по горизонтали, однако по вертикале игрок видит меньше, чем по горизонтали. Оттого и такой результат.

А так, решение вполне себе рабочее. Замечу только, что условие соответствия косинуса определённого градуса лучше вынести в отдельное поле.
private static final double REFERENCE_COS = Math.cos(Math.to_radians(60));
 
Назад
Сверху