Кат Сцены.

Версия Minecraft
1.19.2
API
Forge
37
1
1
Новый вопрос, у меня есть код катсцены который переводит меня в режим наблюдателя и каждый тик пока я не достигнку цели телепортирует на координаты и т.д., НО ЭТО НЕ ИДЕАЛ! (не плавно). Вот код вычисления следующей точки и телепортации и т.д. :
Код класса;:
private double OrigX, OrigY, OrigZ;
    private double CurrX, CurrY, CurrZ;
    private double TargX, TargY, TargZ;
    private double speed;
    private int use;

    @SubscribeEvent
    public static void tick(TickEvent.ServerTickEvent event) {
        if (event.phase == TickEvent.Phase.END) {
            if (camera.use == 1) {
                camera.updateCamera();
                world.excuteCommand("gamemode spectator @a");
            }
        }
    }

    public void setCamera(double startX, double startY, double startZ, double endX, double endY, double endZ,double speed) {
        this.OrigX = startX;
        this.OrigY = startY;
        this.OrigZ = startZ;
        this.TargX = endX;
        this.TargY = endY;
        this.TargZ = endZ;
        this.CurrX = startX;
        this.CurrY = startY;
        this.CurrZ = startZ;
        this.speed = speed;
        this.use = 1;
    }
    public void updateCamera() {
        if (use == 1) {
            CurrX += (TargX - CurrX) * speed;
            CurrY += (TargY - CurrY) * speed;
            CurrZ += (TargZ - CurrZ) * speed;
            all.lookAt(EntityAnchorArgument.Anchor.EYES, new Vec3(TargX, TargY, TargZ));
            all.teleportTo(CurrX, CurrY, CurrZ);
            if (Math.abs(CurrX - TargX) < speed && Math.abs(CurrY - TargY) < speed && Math.abs(CurrZ - TargZ) < speed) {
                use = 0;
            }
        }
    }
 
Решение
1) use сделай в boolean, раз он может принимать значения только 1 и 0.
2) Тройка Orig вообще не нужна.
3)
TickEvent.ServerTickEvent event)
Камеры - штука клиентская, т.е. подобная реализация будет работать только в одиночке.
Для адекватной настройки нужно настроить пакетную систему под твои задачи.

4) Камеры следуют за сущностью, т.е. двигать нужно не камеру, а игрока:
(Вариант lerp - @HomaPlus его и предложил)
Java:
        public static void updateCamera(Player player, float partialTicks) {
            if(use) {
                //lerp(тек. поз., конеч. поз, дельта (на сколько меняем));
                double x = Mth.lerp(curPos.x, targetPos.x, partialTicks);
                double y = Mth.lerp(curPos.y, targetPos.y...
Делал подобное как и на базе Forge так и на Spigot

В идеале это делать в cameraSetupEvent установить кастомную позицию камеры, и перед этим выключить интерфейс, управление и прочее если нужно.

Чтобы это было плавно - рассчитывай позиции на ключевых кадрах (прошлый тик и текущий тик) и интерполируй значения между ними в зависимости от partial tick
 
1) use сделай в boolean, раз он может принимать значения только 1 и 0.
2) Тройка Orig вообще не нужна.
3)
TickEvent.ServerTickEvent event)
Камеры - штука клиентская, т.е. подобная реализация будет работать только в одиночке.
Для адекватной настройки нужно настроить пакетную систему под твои задачи.

4) Камеры следуют за сущностью, т.е. двигать нужно не камеру, а игрока:
(Вариант lerp - @HomaPlus его и предложил)
Java:
        public static void updateCamera(Player player, float partialTicks) {
            if(use) {
                //lerp(тек. поз., конеч. поз, дельта (на сколько меняем));
                double x = Mth.lerp(curPos.x, targetPos.x, partialTicks);
                double y = Mth.lerp(curPos.y, targetPos.y, partialTicks);
                double z = Mth.lerp(curPos.z, targetPos.z, partialTicks);

                //Вращение можем задавать также

                curPos = new Vec3(x, y, z);

                player.setPos(curPos);

                if(curPos.closerThan(targetPos, 0.1f))
                    use = false;
            }
        }

(Вариант deltaMovement - ввиду внутр. реализации setPosRaw - с Math.floor, - этот будет предпочтительней)
Java:
        private static final Vec3 SPEED = new Vec3(1, 1, 1);
       
        public static void updateCamera(Player player, float partialTicks) {
            if(use) {
                //Получаем направление "куда двигать"
                Vec3 dir = player.getPosition(0.5f).vectorTo(targetPos).normalize();
               
                player.setDeltaMovement(dir.multiply(SPEED));

                if(player.getPosition(0.5f).closerThan(targetPos, 0.1f))
                    use = false;
            }
        }
 
Назад
Сверху