饥荒代码学习文档
饥荒mod制作学习笔记
饥荒模组制作笔记
本文章内容为本人在B站看UP主菜鸟老李的教学学习饥荒mod制作时做的笔记。B站地址为[
https://www.bilibili.com/video/BV1nv411T7Dy](https://www.bilibili.com/video/BV1nv411T7Dy)
文章目录
一、采集功能模组
-
全局变量储存在tuning.lua中,变量名称字母全部大写。引用变量时用:
TUNING.STACK_SIZE_SMALLITEM
。TUNING
是一个table(表格)类型的变量,例如:table1 = {变量1,变量2}
引用变量1,则采用 table1.变量1
TUNING
变量在tuning.lua文件中声明的变量,在 tuning.lua文件中TUNING
表格变量中储存了大量要使用的全局变量。其中, SATCK_SIZE_SMALLITEM 是小尺寸物品堆叠上限数量。
-
全局变量无关键字,直接定义,局部变量关键字 local。
-
Pickable:SetUp(product,regen,number)
为设置采集数量的函数。 -
configuration_option = { --模组变量配置 { name = “name1”, --modmain脚本里调用的变量,可以理解为变量名 label = “label1”, --游戏配置选项中显示的标签名 options = { {description = “40倍”, data = 40}, --description为选项框中显示的字符,data为饥荒内置函数要获取的--饥荒游戏代码要使用的值 {description = “50倍”, data = 50}, {description = “60倍”, data = 60} }, default = 40 }, { name = “name2”, --modmain脚本里调用的变量,可以理解为变量名 label = “label2”, --游戏配置选项中显示的标签名 options = { {description = “40%”, data = 0.4}, {description = “60%”, data = 0.5}, {description = “80%”, data = 0.6} }, default = 0.4 } }
模组配置代码写成这种表格形式,是由饥荒内置函数 GetModConfigData() 决定的。
要使模组配置代码起作用,需要在 modmain.lua 文件里写代码:
TUNING.SACK__SIZE_SMALLITEM=GetModConfigData(“name1”)
这里
GetModConfigData(“name1”)
函数会返回参数name = “name1”的表格中的option表格中玩家在设置里选择的 description 对用的data的值。 -
ecs框架,Entity(实体), Component(组件), System(系统)。组件组合起来形成实体。
-
所有的实体都可以在prefabs文件夹里找到。
-
实体代码结构(以摘取的花瓣为例,文件为 petals.lua):
local assets = --素材,决定在游戏里看到的样子
{ }
local prefabs = --实体的分类,比如花瓣普通花瓣和恶魔花瓣
{ }
local function OnHaunt(inst, haunter)
--方法,定义某些组件里没有的特性,比--如在一定条件下,有几率普通花瓣变成恶魔花瓣。
local function fn()
--方法,初始化用的函数,决定功能改变功能一般在这个函数里改
Return Prefab(“petals”, fn, assert, prefabs) --返回
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j3cCFVIX-1646965611396)(file:///C:\Users\YG\AppData\Local\Temp\ksohtml12196\wps1.jpg)]
-
Component组件修改方法
1.源文件修改方法。
2.通过模组:覆盖原始文件。
3.通过AddComponentPostInit函数修改,方法高级但是难度大。这个函数的作用:游戏启动–mod文件覆盖原始文件–AddComponentPostInit修改就不用脚本文件覆盖,这就是高级的好处。AddComponentPostInit函数只修改整个组件文件里的一小部分, 而mod文件会覆盖掉整个文件。AddComponentPostInit函数写在modmain.lua文件
AddComponentPostInit函数格式:AddComponentPostInit(参数1, 参数2)
参数1 为要修改的组件,字符串为组件名称,” ”。
参数2 为函数代码,要修改的组件内容,方法。参数2 可以是一段函数代码,也 可以先将函数创建写好,参数2 为函数名称。
例如,
local function newPickableSetUp(self) end AddComponentPostInit(“pickable”, newPickableSetUp)
对pickable源文件中的函数进行修改
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-32M3tMSa-1646965611397)(file:///C:\Users\YG\AppData\Local\Temp\ksohtml12196\wps2.jpg)]
-
lua语法:每个组件里都有一个类。关于类的使用,在代码pickable注解版.lua中有解释。
-
Pickable:Pick(picker) 控制采集产出物品的函数
修改采集所得物品时,主要修改的地方
picker.component.inventory:GiveItem(SpawnPrefab(“log”), nil,self.inst:Getpostion())
采集者.组件.库存:GiveItem(道具, nil, 坐标)
道具:实体(由SpawnPrefab(“log”)产生),nil, 坐标self.inst.Getposition()
坐标指的是背包里的坐标,不是地图里的坐标。
二、给人物添加采集组件
-
人物修改相关,人物组成:
-
组件—构成—预制件—人物模板—人物(各种人物不同)—tuning.lua。
人物大量的属性都在tuning.lua文件的TUNING这个表里,这个表里的变量赋值可以直 接在modmain文件 里改。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hyusaUS1-1646965611397)(file:///C:\Users\YG\AppData\Local\Temp\ksohtml12196\wps3.jpg)]
-
给人物添加变量,等级和经验值的思路:全部人物都添加,添加组件。
-
2.1新建一个level组件
-
创建一个组件文件,在模组文件夹,scripts\components\level.lua
-
打开文件编写代码,组件由Class函数创建,必须符合Class函数结构对3个参数的要求
-
Class函数有三个参数
base 定义类的基础,可以是table,可以是函数
_ctor, nil空值
props 默认初始化的数据
- 最后把这个class函数返回,这也是组件必须的格式
ocal Level = Class(function(self, inst) --初始化
self.inst = inst
self.level = 1
self.exp = 0
end,
nil,
{})
return Level
2.3 给人物添加level组件
- 在modmain.lua里通过api函数给所有玩家都添加上这个组件,
AddPlayerPostInit(function(inst))--修改人物函数api
if not inst.components.level then --检查人物有没有这个组件
inst:AddComponent("level") --给人物添加这个组件level
end
end)
-
人物修改函数
AddPlayerPostInit(fn)
,第一个参数为fn函数,fn函数需满足一定的格式。其中一种格式为,其参数为要添加组件的人物实例,其内容为按一定条件筛选要添加组件的人物实例,并为其添加组件,添加组件是使用函数AddComponent("level")
-
组件命名开头大学。
2.4 采集经验值设计
- 采集组件里,采集触发位置,添加经验值累加
picker.components.level.exp = pick.components.level.exp + 1
2.5 采集组件升级
- 升级设置,升级经验设置为 等级x等价x10
2.6 添加显示采集等级
-
UI用户界面User Interface, 游戏里面显示等级和经验
-
窗口,游戏里所有窗口部件都在widgets文件夹里
-
窗口组件,窗口组件都以widgets文件夹里的widget.lua文件中的类Widget为基类,创建新的窗口部件。
Class(Widget, function(self, owner) Widget._ctor(self, "PickableLevelText") end)
继承父类,定义构造函数。
--首先在文件的头部加载Widget类 local Widget = require "widgets/widget" --Widget,基class local PickableLevelText = Class(Widget, function(self, owner) --这里用Class来创建一个子类,第一个参数是父类, --第二个参数是构造函数 --这里让PickableLevelText继承基类Widgets, --这样PickableLevelText就成了一个符合饥荒要求的窗口部件类 Widget._ctor(self,"PickableLevelText") --这一句必须写在构造函数的第一句,否则会报错。这里调用了父类的构造函数 end) return PickableLevelText
Widget是一个空窗口,子类继承父类后需要在子类里添加text部件。
-
添加text部件(指由Text类创建的部件),添加一个自己建立的text部件,部件名称为newText,作为属性添加到PickableLevelText里,newText是由Text类创建的实例。添加text部件采用函数
self:AddChild(Text(BODYEXTFONT, 30, "LV"))
--首先在文件的头部加载Widget类 local Widget = require "widgets/widget" --Widget,基class local Text = require "widgets/text" --Text类,文本处理 local PickableLevelText = Class(Widget, function(self, owner) --这里用Class来创建一个子类,第一个参数是父类, --第二个参数是构造函数 --这里让PickableLevelText继承基类Widgets, --这样PickableLevelText就成了一个符合饥荒要求的窗口部件类 Widget._ctor(self,"PickableLevelText") --这一句必须写在构造函数的第一句,否则会报错。这里调用了父类的构造函数 self.newText = self:AddChild(Text(BODYEXTFONT, 30, "LV")) --添加一个文本变量,接收Text实例 --Text是一个类,不是一个实例,Text(BODYEXTFONT, 30, "LV") --才是一个实例,这就是为什么需要定义构造函数。 --猜测,Text()就是类Text的构造函数 --Text()与text文件里的 --Text = Class(Widget, function(self, font, size, text, colour)...)中 --的function(self, font, size, text, colour)相对应 end) return PickableLevelText
-
将PickableLevelText部件添加到游戏主窗口,widgets文件中的controls.lua文件决定游戏主窗口显示,需要对在modmain文件中其进行修改
AddPlayerPostInit(function(inst)--修改人物函数api,其参数是一个函数。 --这个函数格式为以人物实例为参数,内容为筛选人物实例并添加组件 if not inst.components.level then --检查人物有没有这个组件 inst:AddComponent("level") --给人物添加这个组件level end end) local PickableLevelText = GLOBAL.require("widgets/PickableLevelText") --加载经验文本部件类 local function addPickableLevelWidget(self, owner) self.PickableLevelText = self:AddChild(PickableLevelText(self.owner)) --为controls添加PickableLevelText窗口部件实例 --猜测PickableLevelText(self.owner)是由 --PickableLevelText类的构造函数构造出来的实例 --与PickableLevelText = Class(Widget, function(self, owner)...) --的function(self, owner)相对应 self.PickableLevelText:SetHAnchor(0) --设置原点x坐标位置,0、1、2分别对应屏幕中、左、右 self.PickableLevelText:SetVAnchor(1) --设置原点y坐标位置,0、1、2分别对应屏幕中、上、下 self.PickableLevelText:SetPosition(70, -50, 0) -- 设置PickableLevelText窗口相对于原点的偏移量,70表示相右,-50表示向下 end --这个函数是官方的MOD API,用于修改游戏中的类的构造函数。第一个参数是类的文件路径,根目录为------scripts。第二个为自定义函数 --自定义函数的结构需要满足AddClassPostConstruct函数对参数的要求。 AddClassPostConstruct("widgets/controls", addPickableLevelWidget)
2.7 UI更新
接下来的方法只能用于离线版,不能打开洞穴。
-
在我们写的widgets/pickablelevelText.lua文件里添加一个方法
--定义一个更新文本内容的方法(只能用于不开洞穴的离线版) function PickableLevelText:OnUpdate(uiText) self.newText:SetString(uiText) end
-
modmain.lua文件里添加这个调用来更新
-
添加一个时钟来更新
-
时钟也是一个实体
-
给实体一个时钟功能
-
DoperiodicTask(时间间隔,函数)
,字面意思是执行周期性任务local inst = GLOBAL.CreateEntity() --饥荒自带的创建实体的函数 inst:DoPeriodicTask(1, function() --更新文本信息 local level = owner.components.level.level local levelEXP = owner.components.level.exp local uiText = level.." "..levelEXP.."/"..level*level*10 self.PickableLevelText:OnUpdate(uiText) end)
-
-
2.8 采集数据存档
-
退出游戏后再进入游戏,经验丢失。需要保存和加载等级经验数据。
-
给level组件写一个保存数据的方法
OnSave()
,返回一个表--保存游戏是将当前人物的等级保存下来 function Level:OnSave() --保存方法函数,返回必须是一个表,这是固定格式 return { level = self.level, exp = self.exp } end
-
给level组件写一个加载数据方法
OnLoad(data)
, data是个表--加载有游戏时将保存的等级加载进来 function Level:OnLoad(data) --加载方法函数,参数必须是一个表,这是固定格式 if data ~= nil then --防止没有data数据读取时游戏崩溃 if data.level then self.level = data.level end if data.exp then self.exp = data.exp end end end
-
三、释放(触发)技能
3.1技能背景
- 经验只满足条件,执行技能功能 ,经验值到10就触发技能
- 采集组件
- 采集触发经验+1
- 判断经验值 等于10触发
- 经验归零
- UI部分,显示当前经验值
- 技能具体功能,随机给一个物品
- 随机
- 可以放入背包的物品
3.2 随机物品
-
建立一个可以放入背包的物品的表
-
在level组件里填加一个随机物品的方法
--随机给一个物品方法 function Level:Give() local itemTable = { "cutgrass", "log", "pinecone", "charcoal", "flint", "silk", } local num = math.random(#itemTable) --#itemTable表示取表的长度 return = itemTable[num]
-
技能触发时,得到随机物品
if picker.components.level.exp >= 10 then --满足条件触发技能 local = randomItem = picker.components.level:Give() --读取随机物品 picker.components.inventory:GiveItem(SpawnPrefab(randomItem), nil, self.inst:GetPosition()) --给物品 picker.components.level.exp = 0 end
四、实体
-
饥荒里实体都在prefab文件夹里
-
创建预制件,使用函数
Prefab("prefabName", fn)
Prefab(参数1(名称), 参数2(函数),参数3(素材))
local assets = --素材 { } local function fn() --控制属性,功能组件的函数 return Prefab("log", fn, assets)
-
构造fn函数
- CreateEntity()主要就是创建一个实体,这个实体自身也带了一些组件
- Transform:变换组件,控制Prefab的位置、方向、缩放等
- AnimeState:动画组件,控制Prefab贴图(Build),动画集合(Bank)和动画播放(Animation)
- Phiysics:物理组件,控制Prefab的物理行为,比如速度,碰撞类型等等
- Light:光照组件,添加该组件可使得Prefab成为一个光源
- Network:网络组件,添加与否决定了一个Prefab在主机上生成时,是否会被客户端看到
- MapEntity:地图实体组件,使用该组件可以为Prefab在小地图上创建一个小图标
- SoundEmitter:声音组件,控制Prefab的声音集合和播放
- CreateEntity()主要就是创建一个实体,这个实体自身也带了一些组件
五、Prefab的修改
-
AddPrefabPostInit(参数1,参数2)
参数1:要修改的prefab的名字——字符串
参数2:fn函数,预制件里修改的内容
-
在modmain.lua文件里用
AddPrefabPostInit()
对Prefab进行修改 -
Component修改的是所用拥有这个组件的实体,Prefab修改的是单个实体
-
修改长矛
--修改长矛攻击 local function modspear(inst) inst.components.weapon:SetDamage(150) --设置攻击力 inst.components.finiteuses:SetMaxUses(999) --耐久上限 inst.components.finiteuses:SetUses(999) --当前耐久,即制造出来时耐久 inst.components.SetRange(14,14+2) --设置攻击范围和命中范围 end AddPrefabPostInit("spear", modspear)
prefab的名字——字符串
参数2:fn函数,预制件里修改的内容
-
在modmain.lua文件里用
AddPrefabPostInit()
对Prefab进行修改 -
Component修改的是所用拥有这个组件的实体,Prefab修改的是单个实体
-
修改长矛
--修改长矛攻击 local function modspear(inst) inst.components.weapon:SetDamage(150) --设置攻击力 inst.components.finiteuses:SetMaxUses(999) --耐久上限 inst.components.finiteuses:SetUses(999) --当前耐久,即制造出来时耐久 inst.components.SetRange(14,14+2) --设置攻击范围和命中范围 end AddPrefabPostInit("spear", modspear)
更多推荐
所有评论(0)