Mod creation memo – setting of hit detection – 1.12.2

This is a reminder about hit detection in creating mods in Minecraft 1.12.2.

The purpose of this series is to record information. I had a hard time because of the lack of information when I was making mods, so I am publishing this in the hope that I can share some of the information I have. I am not an expert in programming, so I cannot accept questions or advice about mod creation. I try to provide correct information, but I ask that you deliberate the information and ask questions by yourself. Also, technical terms are difficult to understand, so I may explain them in my own words. Please forgive me if there may be nuances that differ.

Judgment on selection” and “Judgment on touch

There are two types of hit judgments: one is the “hit judgment when selecting” and the other is the “hit judgment when touching.

The hit judgment when selecting an item is a frame that appears when the item is within the area that can be destroyed with the pointer. The hit points for touching are invisible hit points that you can see when you actually climb on or pass through an object.

For example, a fence is one block high when you select it, but you cannot jump over it. This is because the judgment when touching it is 1.5 blocks high. In this way, the hit judgment for selection and the hit judgment for touch can be set separately.

The hit judgment for selection can be set with getBoundingBox, and the hit judgment for touching can be set with getCollisionBoundingBox.

// 選択する際の当たり判定
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
  ~
}
// 触れる際の当たり判定
@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
  ~
}

If you do not need to set both of them, you can set only getBoundingBox if you want to keep the same judgment when selecting and touching. If you want to change the collision judgments when selecting and touching, set getCollisionBoundingBox only.

How to Set the Bounce Judgment Value

To set the hit judgment, write the following.

public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
  return new AxisAlignedBB(0.0D, 1.0D, 0.0D, 1.0D, 0.0D, 1.0D);
}

This numerical value allows you to set the hit judgment in detail.

0.0D, 1.0D, 0.0D, 1.0D, 0.0D, 1.0D

The meaning of this number is as follows.

[X subtract], [Y add], [Z subtract], [X add], [Y subtract], [Z add], [X add], [Y subtract], [Z add], [X subtract], [Y subtract], [Z subtract].

XYZ means the X axis from left to right, the Y axis from bottom to top, and the Z axis from back to front when facing north. Trying to figure this out in my head is difficult, so I think of it in terms of the following diagram.

It is easier to understand if you look at North and remember [shave from left], [add from bottom], [shave from back], [add from left], [shave from bottom], [add from back]!

By adding or subtracting by these 6 values, you can make any shape you want.

For example, the following is the case of a half block.

//上付きハーフブロック
0.0D, 1.0D, 0.0D, 1.0D, 0.5D, 1.0D
//下付きハーフブロック
0.0D, 0.5D, 0.0D, 1.0D, 0.0D, 1.0D

Since the width of both the superscript and subscript halves is one block, both X (left and right) and Z (back and front) are given 1.0 each. The superscript half is floating, so 1.0 is given from the bottom and 0.5 is removed. The bottom half is given 0.5 and is not shaved off. If it is difficult to understand, I am thinking in terms of the previous diagram.

Allow the block to slip through.

If you want to eliminate the hit decision, simply return NULL_AABB to getCollisionBoundingBox. This is a convenient value that contains the AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D)!

Conversely, a hit decision for a whole block is stored in FULL_BLOCK_AABB.

@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos) {
  return NULL_AABB;
}

With the above description, the hit judgment when touching is eliminated and the block can be slipped through. Easy and simple!

Even if you eliminate the judgment of getCollisionBoundingBox, be careful not to set getBoundingBox to NULL_AABB, because if you eliminate the judgment of getBoundingBox, the block cannot be selected and cannot be broken.

Change the judging of hits depending on the direction

There are cases in which you may want to change the hit judgment depending on the direction in which the block is placed. This can be used only if the direction of the block is set to change according to the direction. It cannot be used for blocks for which no setting has been made.

On the other hand, if a state is set, you can set the judging for each value other than the direction. For example, in the case of a half block, the state of the half block is set to a superscript state and the state of the half block is set to a subscript state, so the judging can be different for the superscript state and the subscript state.

Let’s think in terms of direction this time!

This is for north, this is for west, and so on, one for each direction. This time, we will use a switch statement! Please search and find out how to use the switch statement.

The following is a description of the case where a vertical half is added. The vertical half is set up with a state called FACING that contains the values of east, west, north, south, and west.

public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
    AxisAlignedBB axisalignedbb;
    switch ((EnumFacing)state.getValue(FACING))
    {
        case NORTH:
        default:
            axisalignedbb = new AxisAlignedBB(0.0D, 1.0D, 0.0D, 1.0D, 0.0D, 0.5D);
            break;
        case SOUTH:
            axisalignedbb = new AxisAlignedBB(0.0D, 1.0D, 0.5D, 1.0D, 0.0D, 1.0D);
            break;
        case WEST:
            axisalignedbb = new AxisAlignedBB(0.0D, 1.0D, 0.0D, 0.5D, 0.0D, 1.0D);
            break;
        case EAST:
            axisalignedbb = new AxisAlignedBB(0.5D, 1.0D, 0.0D, 1.0D, 0.0D, 1.0D);
    }
    return axisalignedbb;
}

Combined with the previous illustration, the decision is as follows.

The point here is that the direction of the XYZ axis does not change regardless of which way you are facing. Be sure to look to the north and consider the judgment.

Hollowing out the inside of a cauldron

How is a judgment made by hollowing out the inside of a cauldron like a cauldron?

Here is an excerpt from the cauldron class that is relevant.

protected static final AxisAlignedBB AABB_LEGS = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.3125D, 1.0D);
protected static final AxisAlignedBB AABB_WALL_NORTH = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D);
protected static final AxisAlignedBB AABB_WALL_SOUTH = new AxisAlignedBB(0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_WALL_EAST = new AxisAlignedBB(0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
protected static final AxisAlignedBB AABB_WALL_WEST = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D);
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean isActualState)
  {
      addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB_LEGS);
      addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB_WALL_WEST);
      addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB_WALL_NORTH);
      addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB_WALL_EAST);
      addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB_WALL_SOUTH);
  }

  public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
  {
      return FULL_BLOCK_AABB;
  }

It seems that the judgments are made by dividing them into parts and combining them. The stair block is also made by combining judgments in this way.

Also, the judgment when touching the stair block is set in detail, but the getBoundingBox uses FULL_BLOCK_AABB to judge a perfect square.

Complex hit judgments can be added by combining in this format.

(This article was automatically translated by a translation tool.)