Индивидуальная коллизия.

Версия Minecraft
1.7.10
API
Forge
16
1
2
Я хочу сделать свой декоративный мод на 3D блоки. Но, у каждого блока должна быть своя коллизия. (Допустим 3x3, 4x4). И игрок во время игры сам может выбрать положение и размер этой коллизии для объекта, который будет ставиться. Но есть проблема - если изменить у Entity размер коллизии, то он применится ко всем другим. Тоже самое и с блоками.(Ну а так же, стоит подметить инициализацию, задавать коллизию для Entity можно только во время инициализации и нигде более)
Возможно ли задать индивидуальную коллизию для каждого Entity / Block . Если да, то как?
 
Последнее редактирование:
Решение
Решение нашёл. Может кому-то пригодится:
Для того, чтобы одинаковые Entity имели разные aabb, нужно сделать следующее:
В классе блока, при создании нового tileEntity:
Java:
    @Override
    public TileEntity createNewTileEntity(World world, int metadata) {
        tile = new TileEntityObj();
        tile.setBoundingBox(AxisAlignedBB.getBoundingBox(0,0,0, 0.5F, 0.5F, 0.5F)); // Размер вашего AABB, который вам нужен ( Майкнрафт не поддерживает больше 1x2x1)
        System.out.println("Create New TileEntitу");
        return tile;
    }

После чего, создаём метод addCollisionBoxesToList И setAABB:
Java:
public void setAABB(AxisAlignedBB aabb)
    {
        this.setBlockBounds((float)aabb.minX, (float)aabb.minY, (float)aabb.minZ...
1,198
31
184
Делай декор через тайлы, там можно менять какие то параметры у твоего уникального в мире декора
Блок - синглтон, поэтому и меняется у всех блоков в мире твоя коллизия
AABB у ентити уникально, не знаю где ты и что меняешь, я в рантайме подменяю AABB на тик для своих расчетов, меняется только у конкретного ентити
 
16
1
2
Насчёт "AABB у Entity уникально", я почему-то не увидел. Ибо когда я допустим ставлю в мире своего Entity( у него вызывается конструктор в который я передаю параметры при создании Entity )
public EntityBlock(World world, int xx, int xy) {
super(world);
this.items = new ItemStack[54];
this.setSize(xx, xy); // Ставлю блоку размеры.
}

То ему в принципе всё равно. Он не сетает ему коллайдер. Но при этом, при инициализации майнкрафта, если впихнуть данную строчку
public EntityAirDrop(World world) {
super(world);
this.items = new ItemStack[54];
this.setSize(5, 5);
}

То у всех энтити мира будет сетнута данная коллизия.

Насчёт тайлов, есть ли какие-то годные туториалы или моды?
Спасибо за ответ

И тут сам факт того, что один и тот же Entity должен создаваться много раз, и каждый экземпляр должен иметь разные значения коллизии
 
Последнее редактирование:
433
41
110
Возможно ли задать индивидуальную коллизию для каждого Entity / Block . Если да, то как?
У блоков и сущностей есть методы - getBoundingBox (название не точное, не за средой разработки)

Они и возвращают хитбокс (с абсолютными позициями), переопределяй и пиши что хочешь

У сущности этот метод без параметра - самостоятельно рассчитывай какой абсолютный хитбокс вернуть

У блоков есть похожий метод с такими параметрами как мир, позиция, состояние. На основе этих входных данных и рассчитывай хитбокс (возвращает относительный хитбокс, до абсолютного хитбокса в другом месте уже изменяется)
(например получить Тил-Ентити в позиции, считать NBT и вернуть хитбокс)
 
16
1
2
Немного не могу понять.
Допустим, у меня есть Entity, в этом Entity я возвращаю aabb

getBoundingBox:
@Override
    public AxisAlignedBB getBoundingBox() {
        double minX = 0;
        double minY = 0;
        double minZ = 0;
        double maxX = 1;
        double maxY = 1;
        double maxZ = 1;
        return AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
    }

Но он всё равно не работает.. (Точнее, он почему-то телепортирует игрока когда я подхожу к нему по ближе, да и ставится как то не корректно)
Так же пытался вот так:
getBoundingBox:
        @Override
public AxisAlignedBB getBoundingBox() {
double minX = this.posX - 0.5;
double minY = this.posY - 0.5;
double minZ = this.posZ - 0.5;
double maxX = this.posX + 0.5;
double maxY = this.posY + 0.5;
double maxZ = this.posZ + 0.5;

 return AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
}

А насчёт блока, я думаю, что вы имели ввиду :
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {

return AxisAlignedBB.getBoundingBox(0,0,0, 0.7, 0.7, 0.7);
}
Но увы, он так же не работает.
 
433
41
110
Но он всё равно не работает.. (Точнее, он почему-то телепортирует игрока когда я подхожу к нему по ближе, да и ставится как то не корректно)
Естественно будут непредсказуемые ошибки - оно абсолютное (специально сделал акцент на этом)

Так же пытался вот так:
Это примерно то что я имел в виду ... (подсмотри как в оригинале метод реализован, + точно скажу что по z вниз нельзя двигать, иначе оно может сквозь пол провалиться)

А насчёт блока, я думаю, что вы имели ввиду
ХЗ. Используй отладчик. Создай плоский мир вообще без сущностей, наставь брейкпоинтов, чтобы отследить где, откуда и зачем оно вызывается

В качестве примера, откуда можно позаимствовать код изменчивых хитбоксов у блоков - двери, ступеньки и подобное. Сделать так-же, но
например получить Тил-Ентити в позиции, считать NBT и вернуть хитбокс

UPD
Вспомнил что 1 блок может иметь несколько хитбоксов, смотри методы appendBox... addBox и подобные
 
Последнее редактирование:
16
1
2
Делай декор через тайлы, там можно менять какие то параметры у твоего уникального в мире декора
Блок - синглтон, поэтому и меняется у всех блоков в мире твоя коллизия
AABB у ентити уникально, не знаю где ты и что меняешь, я в рантайме подменяю AABB на тик для своих расчетов, меняется только у конкретного ентити
Так если Блок - это синглтон, то как мне через тайлы это делать ? Как я знаю, тайлы же от блок-контейнера создаются.
 
16
1
2
Решение нашёл. Может кому-то пригодится:
Для того, чтобы одинаковые Entity имели разные aabb, нужно сделать следующее:
В классе блока, при создании нового tileEntity:
Java:
    @Override
    public TileEntity createNewTileEntity(World world, int metadata) {
        tile = new TileEntityObj();
        tile.setBoundingBox(AxisAlignedBB.getBoundingBox(0,0,0, 0.5F, 0.5F, 0.5F)); // Размер вашего AABB, который вам нужен ( Майкнрафт не поддерживает больше 1x2x1)
        System.out.println("Create New TileEntitу");
        return tile;
    }

После чего, создаём метод addCollisionBoxesToList И setAABB:
Java:
public void setAABB(AxisAlignedBB aabb)
    {
        this.setBlockBounds((float)aabb.minX, (float)aabb.minY, (float)aabb.minZ, (float)aabb.maxX, (float)aabb.maxY, (float)aabb.maxZ);
    }

    @Override
    public void addCollisionBoxesToList(World w, int x, int y, int z, AxisAlignedBB aabb, List list, Entity e) {
        TileEntityObj ted = (TileEntityObj) w.getTileEntity(x, y, z);


            if(ted.getBoundingBox() != null)
                this.setAABB(ted.getBoundingBox());
            super.addCollisionBoxesToList(w, x, y, z, aabb, list, e);

        this.setBlockBounds(0f, 0, 0f, 1f, 1f, 1f);
    }

TileEntityObj:
public class TileEntityObj extends TileEntity {

    private AxisAlignedBB boundingBox;

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        if (compound.hasKey("boundingBox")) {
            boundingBox = AxisAlignedBB.getBoundingBox(compound.getDouble("minX"), compound.getDouble("minY"), compound.getDouble("minZ"),
                    compound.getDouble("maxX"), compound.getDouble("maxY"), compound.getDouble("maxZ"));
        }
    }
   
    @Override
    public void writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);
        if (boundingBox != null) {
            compound.setDouble("minX", boundingBox.minX);
            compound.setDouble("minY", boundingBox.minY);
            compound.setDouble("minZ", boundingBox.minZ);
            compound.setDouble("maxX", boundingBox.maxX);
            compound.setDouble("maxY", boundingBox.maxY);
            compound.setDouble("maxZ", boundingBox.maxZ);
        }
    }


    public AxisAlignedBB getBoundingBox() {
        return  boundingBox;
    }

    public void setBoundingBox(AxisAlignedBB boundingBox) {
        this.boundingBox = boundingBox;
        markDirty();
    }
   
}
 
433
41
110
Все он поддерживает..
Хоть и поддерживает но как-то криво, по крайне мере на 1.12.2. Когда я делал хитбокс блока в 3х3х3 я столкнулся со странными багами, и решил больше так не делать
 
Сверху