Custom Moduls(zh) - Gamepiaynmo/BallanceModLoader GitHub Wiki

自定义机关

English Version

在开始之前,请先在这里下载解密后的Ballance nmo文件。它们会在接下来的教程中十分有用。

自带的模组也是有价值的参考资料。

自定义玩家球种

要创建自定义球种,首先需要一个球的模型,以及一些球碎片的模型,在变球时使用。你可以使用3ds max来建模,或者直接使用Ballance原有的球模型。

  • 首先给你的新球起个名字。例如其中一个自带模组加入了一个粘球,名为Sticky。那么将球和球碎片物体如下命名:

  • 创建一个3D Frame,名为Ball_StickyPieces_Frame。将它的坐标设为(0,0,0),并将所有的球碎片物体设为它的子物体(在层级管理器中):

  • 创建一个名为Ball_Sticky_Pieces的组,然后将所有球碎片物体都加入其中:

  • 创建一个名为All_Ball_Sticky的组,并将所有其他物体:3D实体,材质,网格,贴图,还有之前创建的另一个组Ball_Sticky_Pieces,加入其中。

  • 在All_Ball_Sticky组下创建两个脚本,名字分别为Ball_Explosion_Sticky和Ball_ResetPieces_Sticky。这两个脚本将在变球时创建球碎片效果,并播放球碎片逐渐消失的动画。总体而言:

    • Ball_Explosion_Sticky脚本首先将Ball_StickyPieces_Frame移动到Ball_Pos_Frame的位置,设置球碎片可见,并物理化所有球碎片。
    • Ball_ResetPieces_Sticky脚本首先修改球碎片材质的透明度来实现碎片渐渐消失的效果,然后取消所有碎片的物理化,并恢复它们为IC初始值。
  • 你可以直接拷贝Balls.nmo中的脚本,但记得修改脚本中引用的物体。或者你也可以自己编写它们。

  • 最后,隐藏所有3D实体和组,设置它们还有所有材质的IC值,除了All_Ball_Sticky组,并设置它们不在一开始激活。

  • 将它导出为nmo文件。注意直接保存nmo文件会导致丢失IC值,正确的方法是首先保存为cmo文件,然后手动修改文件后缀名为nmo。现在自定义球种的nmo部分就完成了,将它放在你的mod文件夹中的3D Entities文件夹下,命名为Ball_Sticky.nmo,并在Load消息函数中加入一行代码:

    m_bml->RegisterBallType("Ball_Sticky.nmo", "sticky", "Sticky", "Ball_Sticky", 10.0f, 0.0f, 1.4f,
    	"Ball", 1.0f, 7.0f, 0.15f, 2.0f);
    
  • 如果你的球不是一个完美的球体(比如纸球),那么将最后一个参数(球的半径)设为-1。

自定义变球器

你仍然需要一个变球器使你的球出现在游戏中。

  • 选择拷贝一个原有的变球器文件:P_Trafo_Wood.nmo,P_Trafo_Stone.nmo,和P_Trafo_Paper.nmo。

  • 将它重命名为你的球名字,并重命名其中的所有物体:3D物体,组,材质和网格。

  • 修改材质P_Trafo_Sticky_Color的漫反射颜色。例如粘球变球器使用了粉色(203,103,204)作为变球器的颜色。记得设置所有3D物体的IC值,然后按相同的方法保存为nmo文件。

  • 将它放在你的mod文件夹中的3D Entities/PH文件夹下,并在Load消息函数中加入一行代码:

    m_bml->RegisterTrafo("P_Trafo_Sticky");
    

自定义道具球种

你也许也希望将你的新球种成为道具球中的一员。

  • 拷贝一份之前的玩家球种的nmo文件,并删除所有多余的物体和脚本。仅需要留下4个物体:一个3D物体,一个材质,一个网格和一个贴图。将球物体重命名为P_Ball_Sticky_MF,并创建一个名为All_P_Ball_Sticky的组,然后将所有的其他4个物体加入其中。最后隐藏球的3D物体,并为其设置IC值,按相同的方法保存为nmo文件。

  • 将这个文件放在你的mod文件夹中的3D Entities/PH文件夹下,并在Load消息函数中加入一行代码:

    m_bml->RegisterModulBall("P_Ball_Sticky", false, 10.0f, 0.0f, 1.4f, "", false, true, false, 0.8f,
    	7.0f, 2.0f);
    
  • 如果你的球不是一个完美的球体,那么使用RegisterModulConvex函数(保证你的球模型为一个3D凸包):

    m_bml->RegisterModulConvex("P_Ball_Sticky", false, 10.0f, 0.0f, 1.4f, "", false, true, false, 0.8f,
    	7.0f);
    

自定义机关

以下将以自带模组加入的P_Rotboard_Wood机关为例来介绍。

  • 与自定义玩家球种类似,首先你需要建立机关的模型,然后创建一个名为P_Rotboard_Wood_MF的3D实体,设置所有其他3D实体为它的子物体。然后创建一个名为All_P_Rotboard_Wood的组,将所有其他物体加入其中。之后隐藏所有的3D物体,并为它们设置IC值:

  • 在All_P_Rotboard_Wood组下创建两个脚本,名字分别为:P_Rotboard_Wood_Init和P_Rotboard_Wood_MF Script。

    • P_Rotboard_Wood_Init脚本将做一些初始化工作,包括获得Ball_Pos_Frame和FixCube的实例。前者指示了当前玩家球的坐标,以便我们在玩家球接近当前机关时激活它。后者会在一些物理化BB中使用。你也可以从其他Ballance机关中拷贝这个脚本。
    • P_Rotboard_Wood_MF Script脚本将根据目前的状态来物理化或者取消物理化当前机关。它将读取CurrentLevel表格的值(行:0,列:4)。这是一个布尔值,含义为当前应进行物理化还是取消物理化工作。
  • 首先物理化木板物体,然后使用Set Physics Hinge让它绕着中轴旋转。使用TT Scalable Proximity模块来检测玩家球是否进入一定的范围,如果是的话使用Physics WakeUp模块来激活当前机关。

  • 当取消物理化时,首先禁用TT Scalable Proximity模块,然后销毁Set Physics Hinge,最后取消木板的物理化并重置P_Rotboard_Wood_MF的IC值。

  • 最终的脚本如下:

  • 保存为P_Rotboard_Wood.nmo并将它放在你的mod文件夹中的3D Entities/PH文件夹下,并在Load消息函数中加入一行代码:

    m_bml->RegisterModul("P_Rotboard_Wood");