方块朝向 1.21 Fabric
本篇教程的视频
本篇教程的源代码
Github地址:TutorialMod-Facing-1.21
介绍
这里我们将用两篇教程来讲解方块状态
,这一篇讲解方块朝向
,下一篇讲解可连接方块
的方块状态
简单介绍一下,方块状态
是方块独有的一种属性,它可以用来表示方块的不同状态,方块状态的种类相当多,有穷举变种型(variants
,名字是我自己定义的),比如以下的acacia_button
1 | { |
这里的face
、facing
、powered
都是方块的属性
显然易见,variants
类型的方块状态是根据方块的属性来穷举出所有状态的方块模型,当然它的缺点也很明显,就是当属性过多时,会导致方块状态文件过于庞大,不利于维护
另外,也有组合型(multipart
),比如acacia_fence
1 | { |
这里的multipart
类型的方块状态是根据方块的属性来选择应用哪个方块模型,比如这里的栅栏,根据四个面是否可连接来决定应用哪个方块模型(如果说要用穷举法,那得写多长的文件啊)
不过,其实很多方块的方块状态还是用variants
类型的,而里面的属性也是相当多的,这里我们就不展开讲解了,有兴趣的可以去看看原版的方块状态文件
我们这里要讲解的参数是facing
,上面的acacia_button
的其中一个属性就是facing
,它表示按钮的朝向,不同的朝向对应不同的模型
原版的门
、楼梯
等都有facing
属性,我们可以去看看它们的源代码,看看它们的这个属性是怎么定义,如何使用的
查看源代码
这里我们以楼梯
为例,看看它的facing
属性是怎么定义的
StairsBlock类
1 | public static final DirectionProperty FACING = HorizontalFacingBlock.FACING; |
在StairsBlock
这个类中,我们可以看到它定义了一个DirectionProperty
类型的属性FACING
,这个属性是HorizontalFacingBlock.FACING
,我们再看看HorizontalFacingBlock
这个类
HorizontalFacingBlock类
1 | public abstract class HorizontalFacingBlock extends Block { |
在HorizontalFacingBlock
这个类中,我们可以看到它定义了一个DirectionProperty
类型的属性FACING
,这个属性是原版定义好的,我们可以直接使用
Properties类
1 | public static final DirectionProperty HORIZONTAL_FACING = DirectionProperty.of("facing", Direction.Type.HORIZONTAL); |
我们还可以在追溯至Properties
这个类,我们可以看到它定义了一个DirectionProperty.of("facing", Direction.Type.HORIZONTAL)
这个字段注册的id
就是facing
,也就是对应我们方块状态文件中的facing
属性
而在Properties
类中还有很多其他的属性,你可以根据需要去查看
实现方块朝向
这里我们就开始来实现方块朝向,我们以前一篇教程的SimpleBlock
为例,我们来实现一个朝向的方块
方块类
1 | public class SimpleBlock extends Block { |
我们先不管其中的碰撞箱,我们先来实现方块朝向
引入FACING属性
1 | public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING; |
我们在SimpleBlock
这个类中定义一个DirectionProperty
类型的属性FACING
,直接引用原版的Properties.HORIZONTAL_FACING
即可
当然,我们可以让我们的方块类继承HorizontalFacingBlock
,这样就不用自己定义FACING
属性了,同时也不用再重写那些方法了,但是得写个编解码器
重写rotate
、mirror
、getPlacementState
方法
1 |
|
这里我们重写了rotate
、mirror
、getPlacementState
方法,这三个方法是用来处理方块朝向的
这里的写法和原版的HorizontalFacingBlock
类中的不太一样,我们多写了getPlacementState
方法,你可以自己来测试一下有什么不同
重写appendProperties
方法
1 |
|
以后写方块状态的属性时候记得写这个,这是非常重要的点!!!
不然后面会报错、崩溃
这里我们添加了FACING
属性,后面我们在游戏中按F3
查看方块状态时就会看到facing
属性了
碰撞箱
接下来我们结合方块的朝向,利用BlockBench
来生成碰撞箱
1 | public static final VoxelShape SHAPE_N = Stream.of( |
东西南北,一共四个方向,我们分别定义了四个碰撞箱,然后根据方块的朝向来返回对应的碰撞箱
在使用BlockBench
生成碰撞箱时,前面说过,我们要将所有的体块放在一个叫VoxelShapes
的组下才能导出,名字不能错,大小写也是
然后不同方向的碰撞箱,可以先选中所有体块,然后将枢轴点设置到xz
平面的中心,高度轴y
可以任意,然后我们选中所有体块,一次旋转90
度(建议逆时针
,这样就是按照上面的顺序来的),再导出
最后就可以得到我们上面那一堆了
修改构造函数
1 | public SimpleBlock(Settings settings) { |
这里我们在构造函数中设置了默认的方块朝向为NORTH
注册方块
前面我们已经注册过了,这里就不再赘述了(当然如果你自己又写了一个的话,记得注册,还有物品栏)
数据文件
语言文件我们就不写了,和前面一样的
模型文件
我们方块的模型文件还是之前的,但是方块状态文件得改
1 | blockStateModelGenerator.registerNorthDefaultHorizontalRotation(ModBlocks.SIMPLE_BLOCK); |
这里我们用registerNorthDefaultHorizontalRotation
方法注册我们的方块,默认面向是NORTH
,这样和我们在方块构造函数中设置的默认朝向一致,并且这里会生成带有facing
属性的方块状态文件
而后,我们就可以在游戏中测试我们的方块了