跳至内容
DST-MOD
用户工具
注册
登录
站点工具
搜索
工具
显示页面
修订记录
反向链接
最近更改
媒体管理器
网站地图
注册
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
•
李令仪
•
人物介绍
•
测试1
•
海洋传说
06mod教程区:高级技巧:userdata
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
==== 什么是userdata ==== 在饥荒中,有一些东西是可以找到代码定义的: - ```EntityScript:DoTaskInTime()``` 定义在 ```scripts/entityscript.lua``` - ```KnownModIndex:GetModInfo()``` 定义在 ```scripts/modindex.lua``` - ```TheFrontEnd:PushScreen()``` 定义在 ```scripts/frontend.lua``` 但是也有一些东西只能找到使用它的地方,而找不到定义位置: - ```TheNet:IsDedicated()``` - ```TheSim:FindEntities()``` - ```WorldSim:SetWorldSize()``` - ```inst.AnimState:PlayAnimation()``` 如果更仔细一点研究,可以发现```TheNet```, ```TheSim```, ```WorldSim``` 这些东西的类型不是table,而是userdata。 <code lua> print(type(TheNet)) </code> ``` userdata ``` 饥荒用的代码是c++和Lua,userdata其实就是写在了c++部分,所以看不见定义。 userdata不是表,不能直接用pairs和ipairs遍历。 <code lua> for k,v in pairs(TheNet)do print(k,v) end </code> ``` bad argument #1 to 'pairs' (table expected, got userdata) ``` ==== 查看userdata方法 ==== 你可以查看userdata的所有函数名字,注意这里使用了元表相关操作: (不懂元表也没关系,知道代码怎么写就行) <code lua> for k,v in pairs(getmetatable(TheNet).__index)do print(k,v) end </code> <code lua> GetDefaultMaxPlayers function: 0x6000005d88c0 SetIsMatchStarting function: 0x6000005da840 GetServerIsDedicated function: 0x6000005d9c00 PrintNetwork function: 0x6000005df680 SetDefaultMaxPlayers function: 0x6000005d8900 ViewNetFriends function: 0x6000005d9d40 SetDefaultGameMode function: 0x6000005d8540 GetClientMetricsForUser function: 0x6000005d9940 GetServerIsClientHosted function: 0x6000005d9c40 TruncateSnapshotsInClusterSlot function: 0x6000005d9640 SystemMessage function: 0x6000005df740 GetWorldSessionFile function: 0x6000005d9180 SendRPCToClient function: 0x6000005deec0 ...(还有一大堆) </code> 虽然能看到函数名字,但是看不了源代码定义,具体用法需要结合函数名和官方使用案例去理解。 ==== 修改userdata方法 ==== 你可以修改现有的userdata里面的函数,也可以定义一个自己的函数。 函数的第一个参数是userdata自身。 === 创建新函数 ===== 写一个新的函数,叫```TheNet:PrintStatus()```。 <code lua> getmetatable(TheNet).__index.PrintStatus = function(net) print("Is Server:", net:GetIsServer()) print("Is Client:", net:GetIsClient()) print("Is Dedicated", net:IsDedicated()) end TheNet:PrintStatus() </code> 因为我是在游戏主界面运行的,所以结果都是false。 <code> Is Server: false Is Client: false Is Dedicated false </code> === 修改已有函数 ===== 让```TheSim:FindEntities()```函数每次被调用的时候,都打印搜索到的实体数量。 <code lua> local mt = getmetatable(TheSim).__index local old_FindEntities = mt.FindEntites mt.FindEntities = function(sim, ...) local ents = old_FindEntities(sim, ...) print("查找到"..#ents.."个实体!") return ents end </code> ==== 小技巧 ==== 如果要修改AnimState, Physics, Transform 之类的函数,常规操作是获取元表修改: <code lua> local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() local mt = getmetatable(inst.AnimState).__index function mt.PlayAndPush(anim, name1, name2) anim:PlayAnimation(name1) anim:PushAnimation(name2) end </code> 但其实klei已经把这个表放到全局变量里了,你可以直接修改: <code lua> function AnimState.PlayAndPush(anim, name1, name2) anim:PlayAnimation(name1) anim:PushAnimation(name2) end </code> 然后就能在其他地方用这个新增的```PlayAndPush```函数了: <code lua> local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.AnimState:SetBank("wilson") inst.AnimState:SetBuild("wilson") inst.AnimState:PlayAndPush("run_start", "run_loop") ---< </code> ==== 完整事例 ==== 上述操作都可以在klei源代码里看到。 - ```scripts/debugsounds.lua``` - ```scripts/postprocesseffects.lua``` (联机)
06mod教程区/高级技巧/userdata.txt
· 最后更改: 2021/11/08 11:16 (外部编辑)
页面工具
显示页面
修订记录
反向链接
回到顶部