Вопрос Как развернуть тело сущности в сторону локации?

Версия Minecraft
1.20.X

Wayfarer

Пользователь
Сообщения
45
Решения
1
К сути, есть алгоритм поиска путей, который задаёт маршрут мобу. Вложенный метод moveTo() не подходит, так как он всё равно сам путь перерасчитывает + не пытается идти сквозь препятствия, не прыгает в ямы, в общем, не подходит по всем пунктам. Я написал свой метод движения сущности:
Java:
private final Mob mob;

public Navigation(Mob mob) {
this.mob = mob;
}

double checkDistance = 0.85 * 0.85;
 Calculator calculator = new Calculator();
    public boolean moveTo(Location next, double speed) {
        //if(mob.isOnGround()) {
        Location mobLocation = mob.getLocation();
        Location target = next.clone().add(0.5,0,0.5);
        if (mobLocation.getX() == target.getX()
                && mobLocation.getY() == target.getY()
                && mobLocation.getZ() == target.getZ()) { //check finite
            return true;
        }
        boolean needJump = false;
        if(mobLocation.getY() < target.getY() && mob.isOnGround()) {
            needJump = true;
        }
        double motX = target.getX() - mob.getX();
        double motY = 0;
        double motZ = target.getZ() - mob.getZ();
        Vector velocity = new Vector(motX, motY, motZ).normalize();
        velocity.multiply(speed);
        motX = velocity.getX();
        motY = velocity.getY();
        motZ = velocity.getZ();

        if(needJump && getXZDistanceSquared(mobLocation, target) < checkDistance
                && mob.getY() + 1 <= target.getY()) {
            motY += 0.5;
            motX /= 32.0;
            motZ /= 32.0;
        }
        setDeltaMovement(new Vector(motX, motY, motZ));
        mob.setBodyYaw(calculator.calculateYaw(mob.getLocation(), target));
        if (mob.getLocation().distanceSquared(next) < 0.95) {
            return true;
        }
        //}
        return false;
    }

    public static double getXZDistanceSquared(Location first, Location second) {
        double x1 = first.getX();
        double x2 = second.getX();

        double z1 = first.getZ();
        double z2 = second.getZ();
        return Math.pow(x1-x2, 2) + Math.pow(z1-z2, 2);
    }

    private void setDeltaMovement(Vector v) {
        Vector initVel = mob.getVelocity();
        double motX = v.getX();
        double motY = v.getY();
        double motZ = v.getZ();

        motX += initVel.getX();
        motY += initVel.getY();
        motZ += initVel.getZ();
        Vector computedVelocity = new Vector(motX, motY, motZ);
        mob.setVelocity(computedVelocity);
    }

    public static float calculateYaw(Location objectPosition, Location targetPosition) {
        double dx = targetPosition.getX() - objectPosition.getX();
        double dz = targetPosition.getZ() - objectPosition.getZ();
        return (float) (-Math.atan2(dx, dz) * 180 / Math.PI);
    }

Java:
private final List<Location> locationList = new ArrayList<>();
private Location pathTo;

    @Override
    public void start() {
        navigation = new Navigation(mob);
    }

@Override
    public void tick() {
        if(mob.getPathfinder().hasPath()) {
            mob.getPathfinder().stopPathfinding();
        }
        if(!locationList.isEmpty()) {
            if (navigation.moveTo(locationList.getFirst(), 0.08)) {
                locationList.removeFirst();
                if (locationList.isEmpty()) {
                    pathTo = null;
                }
            }
        } else {
            stop();
        }
    }
Метод setBodyYaw() либо не работает, либо работает не так, как задумано, в общем сущность всё равно не поворачивается в нужную сторону и идёт как повезёт, стрейфом, спиной, но не лицом. Телепортация к локации не подходит. lookAt() тоже криво работает, сущность всё время дёргается
 

Вложения

  • 2024-11-14 16-17-51.gif
    2024-11-14 16-17-51.gif
    137.3 MB · Просмотры: 25
Решение
В общем в текущем версии ядра проблема не решаема, только костыли: телепортировать её (меняя положение, куда сущность смотрит), если разница большая между углами. Также после телепортации восстановить предыдущую скорость сущности
Вам необходимо зарегистрироваться для просмотра изображений-вложений
Оно не разворачивает тело, оно задаёт скорость сущности в направлении, куда смотрит
 
Location#setYaw и Location#setPitch попробуй
А назначить сущности локацию можно через телепорт, а телепорт сбрасывает velocity сущности, в общем такой ступор получается. Я думаю мб через пакеты как-то можно, не работал с протоколлибом
 
Я думаю мб через пакеты как-то можно, не работал с протоколлибом
Интересно как сработает, учитывая, что пакеты должны заставить отображать желаемое только на клиенте, состояние сущности на сервере при таком раскладе изменяться не будет.
 
Интересно как сработает, учитывая, что пакеты должны заставить отображать желаемое только на клиенте, состояние сущности на сервере при таком раскладе изменяться не будет.
А собственно есть разница, в какую сторону смотрит сущность, если можно часть алгоритмов переписать не под то, куда смотрит сущность, а от определённых вещей, позиции игрока, например. Скелет на сервере стоит спиной, но на клиенте смотрит на игрока и также стреляет в игрока, вектор идёт от скелета до игрока. А не туда, куда скелет смотрит. Хотя... я написал и чую, что фигня какая-то выходит и слишком много лишней работы
 
А собственно есть разница, в какую сторону смотрит сущность, если можно часть алгоритмов переписать не под то, куда смотрит сущность, а от определённых вещей, позиции игрока, например. Скелет на сервере стоит спиной, но на клиенте смотрит на игрока и также стреляет в игрока, вектор идёт от скелета до игрока. А не туда, куда скелет смотрит. Хотя... я написал и чую, что фигня какая-то выходит и слишком много лишней работы
Сервер на клиент и собственные пакеты для обновления состояния сущности отправляет, их тоже придется ловить и менять там данные. Для поворота башки сущности, кстати говоря, существует отдельный пакет, кажется.
 
Сервер на клиент и собственные пакеты для обновления состояния сущности отправляет, их тоже придется ловить и менять там данные. Для поворота башки сущности, кстати говоря, существует отдельный пакет, кажется.
Да там хотя бы тело повернуть, метод setBodyYaw() работает, но как-то не знаю, с затупами и медленно. Либо вообще не работает. teleport() - идеально сущность разворачивает, но теряется скорость. Повернуть голову - тоже такое себе. Да вроде всё испробовал. moveTo() разворачивает сущность к локации, куда идёт, но мне этот метод не нравится, очень не гибкий, назову его так
 
mob.setBodyYaw(calculator.calculateYaw(mob.getLocation(), target));
Может стоит вызвать перед этой строкой:
Java:
Bukkit.getServer().getMobGoals().removeAllGoals(mob);
Я ничем подобным раньше не занимался, так что это совет из разряда try and see.
 
Может стоит вызвать перед этой строкой:
Java:
Bukkit.getServer().getMobGoals().removeAllGoals(mob);
Я ничем подобным раньше не занимался, так что это совет из разряда try and see.
А, это уберёт весь ИИ у моба, нужно будет заново его прописывать. Ну кстати тоже может быть (сработать), что моб выполняет другие goals'ы и поэтому вертит башкой туда-сюда в каком-нибудь random_look_at_player
 
Может стоит вызвать перед этой строкой:
Java:
Bukkit.getServer().getMobGoals().removeAllGoals(mob);
Я ничем подобным раньше не занимался, так что это совет из разряда try and see.
В общем кому интересно, setBodyYaw() не работает, если сущности задана любая скорость (странно почему это взаимоисключающие параметры). В документации об этом не сказано, продолжаю тыкать пальцем в небо, держу в курсе.
 
В общем в текущем версии ядра проблема не решаема, только костыли: телепортировать её (меняя положение, куда сущность смотрит), если разница большая между углами. Также после телепортации восстановить предыдущую скорость сущности
 
Последнее редактирование:
Назад
Сверху Снизу