这期我们来聊聊饥荒中的帽子,根据显示的不同,分为露头类帽子(如花环),不露头类帽子(如高礼帽)。这两种帽子除了动画显示部分有所区别外,其他部分是相同的。为了节省制作动画的时间,我直接用花环和高礼帽的动画作演示。
除了动画和prefabs里的,其他可以前几期都有涉及,这里就不多赘述了。
源文件已添加到mods/~myhats.zip中
饥荒联机版开发
https://pan.baidu.com/s/1_-TPRdo86z8PNwK084N_3A?pwd=oc74
两种类型的帽子,动画制作流程其实是一样的。
双击右上角的图片,设置锚点。前三张的锚点对应的是带上帽子后的位置,这个需要多进游戏多试,最后一张的锚点是地面落地点。
inst.AnimState:SetBuild("mytophat") --scml名字自动打包成同名zip,同时也是这个参数
inst.AnimState:SetBank("mytophat") --对应sprite里右下角的第一层名字
inst.AnimState:PlayAnimation("idle") --第一个参数是动画名,对应sprite里右下角的第二层名字
简单声明预设物文件,物品名,物品描述
GLOBAL.setmetatable(env,{__index=function(t,k) return GLOBAL.rawget(GLOBAL,k) end})
PrefabFiles = {
"myflowerhat",
"mytophat"
}
STRINGS.NAMES.MYFLOWERHAT = "我的花帽"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.MYFLOWERHAT = "这是花帽?"
STRINGS.NAMES.MYTOPHAT = "我的高礼帽"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.MYTOPHAT = "这是高礼帽?"
下面这代码属于最基本的代码了,如果看不懂建议回去看第三期和第四期。
--prefabs/myflowerhat.lua
local assets = {
Asset("ANIM", "anim/myflowerhat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/myflowerhat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/myflowerhat.xml")
}
local prefabs = {}
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst) --与地面碰撞
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("myflowerhat")
inst.AnimState:SetBuild("myflowerhat")
inst.AnimState:PlayAnimation("idle")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "myflowerhat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/myflowerhat.xml"
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("myflowerhat", fn, assets, prefabs)
当然这么写还是无法穿戴的,控制物品可穿戴的核心组件是equippable,一般来说我们只要添加这个组件,设置装备的位置,装备/卸载时替换贴图即可。
细心观察你会发现,装备物品其实是一个起手动作结束后,直接换贴图的。
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
--若有耐久组件,则开始扣耐久
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
--若有耐久组件,则停止扣耐久
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
...
if not TheWorld.ismastersim then
return inst
end
...
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
end
其中
owner.AnimState:OverrideSymbol(“swap_hat”, “myflowerhat”, “swap_hat”)
表示用myflowerhat.scml动画中的swap_hat(后)文件夹中的图,替换owner中swap_hat(前)中的图。
由于反解压不出第一个参数表示的透明图文件夹,所以一般我们只配置后两个参数。
owner.AnimState:Show(“HAT”)
显示某个文件夹的图
owner.AnimState:Hide(“HAT”)
隐藏某个文件夹的图
owner.AnimState:ClearOverrideSymbol(“swap_hat”)
取消替换某个文件夹的图,即还原回来。
上面的装备和卸载函数基本是固定的,有新的功能直接在后面加上就好,前面的直接copy吧。
当然这只是完成了基本的装备/卸载,我们可以添加tradable组件,让它可以给猪人、兔人等
inst:AddComponent("tradable") --可交易,给猪人等
其次,花帽加个腐烂做耐久就挺不错的。腐烂结束我们用一朵花来替换好了。
inst:AddComponent("perishable") --腐烂的
inst.components.perishable:SetPerishTime(TUNING.PERISH_FAST) --6天的腐烂时间
inst.components.perishable.onperishreplacement = "flower" --设置腐烂后的替代物
--inst.components.perishable:SetOnPerishFn(inst.Remove) --如果不要替代物,可换为这句,腐烂后直接销毁
inst.components.perishable:StartPerishing() --开始腐烂
当然还要在客户端那表示要显示腐烂度,以及可以放冰箱
...
inst:AddTag("show_spoilage") --加这个就有保鲜度动画
inst:AddTag("icebox_valid") --加这个就可以放进冰箱
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
所以,总的代码如下
--prefabs/myflowerhat.lua
local assets = {
Asset("ANIM", "anim/myflowerhat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/myflowerhat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/myflowerhat.xml")
}
local prefabs = {}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst) --与地面碰撞
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("myflowerhat")
inst.AnimState:SetBuild("myflowerhat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst:AddTag("show_spoilage") --加这个就有保鲜度动画
inst:AddTag("icebox_valid") --加这个就可以放进冰箱
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "myflowerhat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/myflowerhat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
inst.components.equippable.dapperness = TUNING.DAPPERNESS_MED --设置回san值
inst:AddComponent("perishable") --腐烂的
inst.components.perishable:SetPerishTime(TUNING.PERISH_FAST) --6天的腐烂时间
inst.components.perishable.onperishreplacement = "flower" --设置腐烂后的替代物
--inst.components.perishable:SetOnPerishFn(inst.Remove) --如果不要替代物,可换为这句,腐烂后直接销毁
inst.components.perishable:StartPerishing() --开始腐烂
inst:AddComponent("tradable") --可交易,给猪人等
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("myflowerhat", fn, assets, prefabs)
这两种帽子的差异主要是装备函数里对AnimState的调用显示,即Show,Hide的部位。卸载函数是一样的。
--露头
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
--不露头
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
所以最基本的不露头的帽子的代码如下。
local assets = {
Asset("ANIM", "anim/mytophat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/mytophat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mytophat.xml")
}
local prefabs = {}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst)
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("mytophat")
inst.AnimState:SetBuild("mytophat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "mytophat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mytophat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("mytophat", fn, assets, prefabs)
要添加耐久度,需要使用fueled组件,设置使用情况,耐久度,即耐久使用结束后的回调。
inst:AddComponent("fueled") --耐久
inst.components.fueled.fueltype = FUELTYPE.USAGE
inst.components.fueled:InitializeFuelLevel(TUNING.FEATHERHAT_PERISHTIME) --8天
inst.components.fueled:SetDepletedFn(inst.Remove)
inst:AddComponent("waterproofer") --防水
inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_SMALL)
inst:AddComponent("insulator") --绝缘
inst.components.insulator:SetInsulation(TUNING.INSULATION_MED)
inst:AddComponent("armor") --防具
inst.components.armor:InitCondition(TUNING.ARMOR_SLURTLEHAT, TUNING.ARMOR_SLURTLEHAT_ABSORPTION)
对了上面的TUNING.XXX可以在tuning.lua中找到,一般是个数字
--prefabs/mytophat.lua
local assets = {
Asset("ANIM", "anim/mytophat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/mytophat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mytophat.xml")
}
local prefabs = {}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst)
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("mytophat")
inst.AnimState:SetBuild("mytophat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "mytophat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mytophat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
inst.components.equippable.dapperness = TUNING.DAPPERNESS_LARGE --设置回san值
inst:AddComponent("fueled") --耐久
inst.components.fueled.fueltype = FUELTYPE.USAGE
inst.components.fueled:InitializeFuelLevel(TUNING.FEATHERHAT_PERISHTIME) --8天
inst.components.fueled:SetDepletedFn(inst.Remove)
inst:AddComponent("waterproofer") --防水
inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_SMALL)
inst:AddComponent("insulator") --绝缘
inst.components.insulator:SetInsulation(TUNING.INSULATION_MED)
inst:AddComponent("armor") --防具
inst.components.armor:InitCondition(TUNING.ARMOR_SLURTLEHAT, TUNING.ARMOR_SLURTLEHAT_ABSORPTION)
inst:AddComponent("tradable") --可交易
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("mytophat", fn, assets, prefabs)
prefabs/hats.lua
→饥荒联机版Mod开发——衣服(十一)
←饥荒联机版Mod开发——制作栏(九)