Багованное передвижение

Версия Minecraft
1.19.2
API
Forge
37
1
1
Доброго времени суток, у меня есть нпс и я его заставляю идти на нужные координаты, но он не доходит 1 блок и останавливается а иногда и больше, из за чего это происходит? Вот часть кода:
NpcEntity:
public class NpcEntity extends Monster implements IAnimatable {
    private AnimationFactory factory = GeckoLibUtil.createFactory(this);
    private UUID uniqueId;
    private String name;
    private double moveTargetX = 0;
    private double moveTargetY = 0;
    private double moveTargetZ = 0;
    private boolean shouldMove = false;
    public static boolean play;
    public static String animation;
    public static boolean loop;

    public NpcEntity(EntityType<? extends Monster> entity, Level world) {
        super(entity, world);
    }

    public void setUniqueId(UUID uniqueId) {
        this.uniqueId = uniqueId;
    }

    public UUID getUniqueId() {
        return uniqueId;
    }

    public void setName(String name) {
        this.name = name;
        this.setCustomName(Component.literal(name));
    }

    public String getNpcName() {
        return name;
    }

    public void setMoveTarget(double x, double y, double z) {
        this.moveTargetX = x;
        this.moveTargetY = y;
        this.moveTargetZ = z;
        this.shouldMove = true;
    }


    @Override
    public void baseTick() {
        super.baseTick();
        if (shouldMove) {
            this.getNavigation().moveTo(this.moveTargetX, this.moveTargetY, this.moveTargetZ, 1.0);
            Double x = this.getX();
            Double y = this.getY();
            Double z = this.getZ();
            Double distance = Math.sqrt((moveTargetX - x) * (moveTargetX - x) + (moveTargetY - y) * (moveTargetY - y) + (moveTargetZ - z) * (moveTargetZ - z));
            System.out.println("Distance to target: " + distance);
            System.out.println(shouldMove);
            if (distance <= 1) {
                this.shouldMove = false;
                System.out.println("Npc has reached the target position.");
                Interpreter(EngineInterpreter.Player, World, line);
            }
        }
        this.refreshDimensions();
    }
}
 
Решение
Java:
    @Override
    public void baseTick() {
        super.baseTick();
        if (shouldMove) {
            // Последний параметр отвечает за скорость.
            // Вызывать здесь - не лучшее решение. Читай ниже.
            getNavigation().moveTo(moveTargetX, moveTargetY, moveTargetZ, 1);
           
            //1. Располагаем даблы не в куче, а на стеке. Т.е. вместо Double пишем double
            //2. Нам это не всё нужно. Можем использовать уже готовую реализацию. Первый параметр позиция, второй - точность достижения.
            if (position.closerThan(new Vec3(moveTargetX, moveTargetY, moveTargetZ), 1.0)) {
                shouldMove = false;
                Interpreter(EngineInterpreter.Player, World, line);
            }...
Java:
    @Override
    public void baseTick() {
        super.baseTick();
        if (shouldMove) {
            // Последний параметр отвечает за скорость.
            // Вызывать здесь - не лучшее решение. Читай ниже.
            getNavigation().moveTo(moveTargetX, moveTargetY, moveTargetZ, 1);
           
            //1. Располагаем даблы не в куче, а на стеке. Т.е. вместо Double пишем double
            //2. Нам это не всё нужно. Можем использовать уже готовую реализацию. Первый параметр позиция, второй - точность достижения.
            if (position.closerThan(new Vec3(moveTargetX, moveTargetY, moveTargetZ), 1.0)) {
                shouldMove = false;
                Interpreter(EngineInterpreter.Player, World, line);
            }
        }
        refreshDimensions();
    }

Как тебе уже говорили, лучше используй AI таски для всего этого дела, а не считай всё в тиках моба.
И да, moveTo достаточно вызвать один раз. Он вернёт возможность достижения точки, установит путь и сам заставит моба двигаться по нему. В т.ч. и пересчитает путь, в случае если он стал недостижим.
 
Назад
Сверху