在这章中,我们讲学习如何制作一个简单的物品mod,各个文件[夹]的意义,下面有请我们的主角——威尔逊的胡子。让我们看一下它都能干嘛。
所以现在我们先把前5个功能实现了。
打开饥荒联机版的mods路径(如:F:\Steam\steamapps\common\Don’t Starve Together\mods)
新建空文件夹,随便起个名字,这里我的是mybeard。然后去其他mod里面把 modicon.tex、modicon.xml 复制过来。
用TEXTool.exe打开modicon.tex(没工具的或对工具不熟的看第一期)。观察下面的一行的参数
Size是 128x128像素,有多个Mipmaps。modicon的Size记号。
接着我们点左上角的保存,把它导出为png格式
这里直接导出到刚才我们建的文件夹就好,方便管理,如果有Steam的饥荒开发工具(见第一期),也会自动打包。
命名为 modicon.png 。然后打开你的图片编辑软件(PS、SAI等),这里我用就简单用画图了,编辑你的mod图标并保存。
下一步把modicon.png转为modicon.tex。
打开texcreator.exe,选择modicon.png,输出路径选桌面(或者刚才那个文件夹,免去复制)
由于我们是从其他mod那拿来的modicon,Size不用担心。再把其他参数,对应上即可。Mipmaps是复数的,所以要把Generate Mipmaps勾上,否则导出的tex的Mipmaps为1。
然后替换我们文件夹的tex即可。这样我们的mod图标就搞定了。
没用VS Code配置代码环境的,看第二期。打开之前第二期配好的VS Code工作区,看我们的beard文件夹是否出现在mods里了。
点击beard,然后右键创建文件或者点+号
起名为 modinfo.lua,复制粘贴进去。各项的意思基本上可以通过英文名判断出来。
name = "我的mod名字" ---mod名字
description = "你好,世界" --mod描述
author = "我" --作者
version = "1.0" -- mod版本 上传mod需要两次的版本不一样
forumthread = "" --和官方论坛相关,一般不填
api_version = 10 --api版本,现在版本写10就行
dst_compatible = true --是否兼容联机
dont_starve_compatible = false --是否兼容原版
reign_of_giants_compatible = false --是否兼容巨人DLC
all_clients_require_mod = true --所有人都需要mod,true就是
icon_atlas = "modicon.xml" --mod图标
icon = "modicon.tex"
server_filter_tags = { --服务器标签
}
--[[ 取消注释,在这行前面加个-就行。可选的mod设置,在modmain里面用 GetModConfigData("test_name") 来获取值,data只能是boolean/string/number
configuration_options = {
{
name = "test_name",
label = "一直显示的选项标题",
hover = "选中时最上面显示的提示",
options =
{
{description = "选项1", data = true, hover = "提示1"},
{description = "选项2", data = false, hover = "提示2"},
},
default = true,
},
}
--]]
现在进游戏,看看效果。
如果到这步都没什么问题,那mod贴图和mod介绍部分就完成了。下面将开始编写代码,让它跑起来。
在mybeard文件夹下,建个 modmain.lua
在这里我们简单声明下我们的预设物(Prefab)文件就好。这样在生成prefab时就会去运行对应的lua文件
PrefabFiles = { --scripts/prefabs文件夹下面我们自己的文件名,没有后缀
"mybeard"
}
在mybeard文件夹下建立scripts文件夹,在scripts文件夹下建立prefabs文件夹,在prefabs文件夹下建立 mybeard.lua(对应我们在modmain里写的名字)
我们可以通过各种途径知道胡须的预设物名字叫 beardhair (你也可以在第一章中资料中的饥荒代码大全里找到)
官方scripts文件夹安排是这样的,而我们写的mod的文件夹名应该和官方的保持一致。
下一步我们要找的预设物胡须,其文件就在prefabs/beardhair.lua 里。你当然可以直接点开文件夹慢慢找,不过这里推荐,按 Ctrl+P ,输入beardhear来直接跳转到对应文件。
先复制代码到我们自己的mybeard.lua里面。
把最后一行的beardhair,改为我们自己的预设物名字 mybeard
因为我们现在用的是官方的动画,所以现在也可以进游戏,用控制台代码 c_spawn(“mybeard”) 来生成。
如果没认真学lua,先回去学lua吧!资料在第一期。
local assets =
{
--添加这个预设物所用到的资源,这里只有个物品在地上时的动画
Asset("ANIM", "anim/beardhair.zip"),
}
对应的文件在饥荒目录/data/anim里面,我们先把它复制到桌面,等下我们再创建我们自己的动画。
接下来我们看看构建函数fn,当生成预设物时,它就会调用构建函数并返回一个实体(entity),一般我们叫它 inst ,全称可能是 instance 。而这个实体一般会添加一堆组件,每个组件各有用处,提供对应的功能,如:
这些组件都在官方代码的 scritps/components 文件夹下,当lua学到一定程度,去看相应代码,而不是去随便copy。
local assets =
{
--添加这个预设物所用到的资源,这里只有个物品在地上时的动画
Asset("ANIM", "anim/beardhair.zip"),
}
local function fn()
local inst = CreateEntity() --创建一个实体,官方代码在 scripts/mainfunctions.lua
--C层的组件,类似的还有Phiysics、Light、Network、SoundEmitter等
--这些组件我们看不见源代码,对应API可以看第一期提供的资源里的 笔记:物品制作常用组件.lua
inst.entity:AddTransform() --添加位移组件,坐标位置
inst.entity:AddAnimState() --添加动画组件,用于播放动画(这里就一个地上的动画)
MakeInventoryPhysics(inst) --对于放在物品栏里的物理Phiysics,让其可以放地上,具体代码在 standardcomponents.lua
--设置动画,这三个函数的参数意义在第一章提到过
inst.AnimState:SetBank("beardhair") --Sprite里面右下角第一层的entity name
inst.AnimState:SetBuild("beardhair") --scml name,同时也是zip的名字
inst.AnimState:PlayAnimation("idle") --Sprite里面右下角第二层的animation name
inst.entity:AddNetwork() --添加网络,因为要在服务器和客户端都显示
MakeInventoryFloatable(inst, "med", nil, 0.75) --让物品浮起来,后面三参数可省,具体代码在 standardcomponents.lua
inst.entity:SetPristine() --推断是OnLoad等初始化相关的
--一般与entity有关的代码,以及服务器和客户端都运行的代码都写在这行上面
if not TheWorld.ismastersim then --如果是客户端,返回inst,结束
return inst
end
--下面是服务器代码,我们添加若干组件,让实体有各种各样的功能
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --可放物品栏
inst:AddComponent("stackable") --可堆叠
inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM --设置堆叠最大值
inst:AddComponent("fuel") --可当燃料
inst.components.fuel.fuelvalue = TUNING.MED_FUEL --设置燃料值
MakeSmallBurnable(inst, TUNING.MED_BURNTIME) --可自然
MakeSmallPropagator(inst) --可传递火焰,即自身燃烧时也点燃周围的物体,具体代码在 standardcomponents.lua
MakeHauntableLaunchAndIgnite(inst) --可作祟(Hauntable)和(火把)点燃(Ignite),具体代码在 standardcomponents.lua
return inst
end
return Prefab("mybeard", fn, assets) --组成成预设物,具体代码在prefabs.lua
以上代码解释完毕。下一期教你如何看懂component和调试代码
现在可以进游戏看下效果,控制台 c_spawn(“mybeard”) 生成我们的预设物来看看。发现,对应本文开头的5种功能都在,只是名字显示,检查时并不是我们想要的效果,以及放在物品栏里没贴图。所以接下来,我们先制作动画和贴图。
在mybeard文件夹下建个exported文件夹,在里面建个mybeard文件夹,在里面建个mybeard文件夹,随便找张图。(这一步除了exported文件夹名字不能变,其他文件夹和图片名随意,不过推荐和预设物一个名字,图片是xxx-序号,方便管理)
打开Sprite,点击左上角 File->New Project,有提示直接Ok
选择exported文件夹下的mybeard文件夹
双击右边的图片设置锚点(对应物品的落地点)
把图片拖出来,设置x,y为0。这样掉落物体时就正好从人物正中间位置开始掉落。
设置第一层的entity name为 mybeard(对应inst.AnimState:SetBank(“mybeard”))
设置第二层的anim name为 idle (对应inst.AnimState:PlayAnimation(“idle”))
保存为mybeard.scml (对应等下生成的zip文件名,对应代码里面inst.AnimState:SetBuild(“mybeard”) )
如果下有Steam上的饥荒开发工具,运行游戏时会自动打包,可以跳过这一步。没有的就需要我们手动打包了。
把exported文件夹下的mybeard文件夹复制
粘贴到打包工具下的相关目录(没软件的看第一章)
运行打包软件
把anim文件夹下的zip拷贝到我们自己mod下的anim文件夹。
回到我们的mybeard.lua中,把对应动画代码的名字改为我们自己的文件,其他部分不变。
local assets =
{
--添加这个预设物所用到的资源,这里只有个物品在地上时的动画
Asset("ANIM", "anim/mybeard.zip"),
}
--设置动画,这三个函数的参数意义在第一章提到过
inst.AnimState:SetBank("mybeard") --Sprite里面右下角第一层的entity name
inst.AnimState:SetBuild("mybeard") --scml name,同时也是zip的名字
inst.AnimState:PlayAnimation("idle") --Sprite里面右下角第二层的animation name
运行游戏看是否正常显示我们的动画。
(这里我直接那modicon的图来用了,白底没删……)
在mybeard文件夹下,建个images文件夹,在里面建个inventoryimages。
官方没用单独的物品栏贴图,这里看看其他mod的物品栏贴图参数。Size64x64像素,多个Mipmaps。
打开的图像编辑软件(PS、SAI等)创建个64x64的png图片,并保存到inventoryimages文件夹下。名字就叫 mybeard(和我们预设物的名字对应)
如果下有Steam上的饥荒开发工具,运行游戏时会自动打包,可以跳过这一步。没有的就需要我们手动打包了。
用texcreator.exe把这张png,转为tex,记得勾选生成Mipmaps
(这里我先生成在桌面,等下剪切过去就行)
把modicon.xml复制粘贴过来,文件夹改为mybeard.xml
打开mybeard.xml(推荐用XML Tool,记事本也行)
把modicon替换成mybeard
回到 mybeardlua,在assets里注册我们的贴图文件。
local assets =
{
--添加这个预设物所用到的资源,这里只有个物品在地上时的动画
Asset("ANIM", "anim/mybeard.zip"),
--物品栏贴图
Asset("IMAGE", "images/inventoryimages/nohat.tex"),
Asset("ATLAS", "images/inventoryimages/nohat.xml"),
}
并在inst:AddComponent(“inventoryitem”) 下指出我们的贴图。(参数名的意义去看官方代码 inventoryitem.lua)
inst:AddComponent("inventoryitem") --可放物品栏
inst.components.inventoryitem.imagename = "mybeard"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mybeard.xml"
至此动画和贴图部分都搞定了。mybeard.lua 完整代码如下
local assets =
{
--添加这个预设物所用到的资源,这里只有个物品在地上时的动画
Asset("ANIM", "anim/mybeard.zip"),
--物品栏贴图
Asset("IMAGE", "images/inventoryimages/mybeard.tex"),
Asset("ATLAS", "images/inventoryimages/mybeard.xml"),
}
local function fn()
local inst = CreateEntity() --创建一个实体,官方代码在 scripts/mainfunctions.lua
--C层的组件,类似的还有Phiysics、Light、Network、SoundEmitter等
--这些组件我们看不见源代码,对应API可以看第一期提供的资源里的 笔记:物品制作常用组件.lua
inst.entity:AddTransform() --添加位移组件,坐标位置
inst.entity:AddAnimState() --添加动画组件,用于播放动画(这里就一个地上的动画)
MakeInventoryPhysics(inst) --对于放在物品栏里的物理Phiysics,让其可以放地上,具体代码在 standardcomponents.lua
--设置动画,这三个函数的参数意义在第一章提到过
inst.AnimState:SetBank("mybeard") --Sprite里面右下角第一层的entity name
inst.AnimState:SetBuild("mybeard") --scml name,同时也是zip的名字
inst.AnimState:PlayAnimation("idle") --Sprite里面右下角第二层的animation name
inst.entity:AddNetwork() --添加网络,因为要在服务器和客户端都显示
MakeInventoryFloatable(inst, "med", nil, 0.75) --让物品浮起来,后面三参数可省,具体代码在 standardcomponents.lua
inst.entity:SetPristine() --推断是OnLoad等初始化相关的
--一般与entity有关的代码,以及服务器和客户端都运行的代码都写在这行上面
if not TheWorld.ismastersim then --如果是客户端,返回inst,结束
return inst
end
--下面是服务器代码,我们添加若干组件,让实体有各种各样的功能
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --可放物品栏
inst.components.inventoryitem.imagename = "mybeard"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mybeard.xml"
inst:AddComponent("stackable") --可堆叠
inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM --设置堆叠最大值
inst:AddComponent("fuel") --可当燃料
inst.components.fuel.fuelvalue = TUNING.MED_FUEL --设置燃料值
MakeSmallBurnable(inst, TUNING.MED_BURNTIME) --可自然
MakeSmallPropagator(inst) --可传递火焰,即自身燃烧时也点燃周围的物体,具体代码在 standardcomponents.lua
MakeHauntableLaunchAndIgnite(inst) --可作祟(Hauntable)和(火把)点燃(Ignite),具体代码在 standardcomponents.lua
return inst
end
return Prefab("mybeard", fn, assets) --组成成预设物,具体代码在prefabs.lua
回到modmain.lua,声明具体名称和描述。完整modmain.lua代码如下
PrefabFiles = { --scripts/prefabs文件夹下面我们自己的文件名,没有后缀
"mybeard"
}
--一键GLOBAL,免去了local STRINGS = GLOBAL.STRINGS等繁琐操作
GLOBAL.setmetatable(env,{__index=function(t,k) return GLOBAL.rawget(GLOBAL,k) end})
--全部大写,最后面对应我们的预设物名
STRINGS.NAMES.MYBEARD = "一个简单的物品" --显示的名字
STRINGS.CHARACTERS.GENERIC.DESCRIBE.MYBEARD = "你好" --人物检查时说的话
现在进入游戏看看效果。(每次修改mod要么重回世界,要么控制台命令 c_reset() 进行回滚,不过换贴图和动画时必须要重回世界)(建议不开洞穴,并把把资源调为无,世界调小)
完整的文件夹图。发布mod时.png文件和exported文件夹可以不上传。
→饥荒联机版Mod开发——Class, Prefab, component,debug(四)
←饥荒联机版Mod开发——配置代码环境(二)