7858321 发表于 2024-5-17 14:40:42

关于NI 对象管理器函数的用法,望高手指点一下

NI的wiki对函数的解释对新手不是特别友好,比如ni.objects的参数实在是看不懂
The object manager also features a set of functions and special way to provide an object oriented type programming for the lua. All of the way to access this feature is via . Functions, variables and examples are as follows:ni.objects

local tar = ni.objects["target"];
if tar:exists() then
    print(tar.guid) --Would print the GUID of the target
end
上图代码中的ni.objects["target"]是指当前目标,就没有别的参数吗?

我看了下贾维斯的挂机通用脚本,他是通过事件来获取尸体的guid,然后写入表中,离开战斗后对表中尸体的guid进行互动(拾取)
我想写一个拾取物品的功能,按理说ni.objects就是周围所有对象,应该包括尸体,遍历这个表应该就能找到,但是苦于不知道这个函数怎么用,望指点一二

powwow1122 发表于 2024-5-17 18:59:09

完全看不懂啊~~~~~~~~~~~~~~~~~~~

7858321 发表于 2024-5-17 19:03:47

卧槽,新手刚接触这个,这个lua面向对象算是理解个大概了,什么表,元表来模拟类,对象,继承,好吧,我想的太简单了,这tm不是一天就能理解的,投降了

blxyz521 发表于 2024-5-21 10:03:57

本帖最后由 blxyz521 于 2024-5-21 10:08 AM 编辑

对于新手来说,要理解ni.objects是有点困难的,而且对大部分人来说是用不到ni.objects的,新手更加用不到,因为封装好的函数已经够用。ni.objects主要是封装好的函数来使用。
比如拾取物品的功能可以用以下函数来实现:    ni.unit.enemiesinrange(unit,range)--返回unit周围range范围内的所有敌人。
    ni.unit.islootable(unit)--判断unit是否可以拾取,这个函数好用,都不需要判断是否死亡。
    ni.player.interact(unit)--互动。
上面的unit 可以是GUID,也可以是unitID

简单写一下就是这样:local enemies = ni.unit.enemiesinrange("player", 30)
for i = 1, #enemies do
local GUID = enemies.guid
if islootable(GUID) then
      interact(GUID)
      break
end
end

当然,上面的逻辑太过简单,只是原理,真正要实现自动拾取,还需要更复杂的逻辑。
因为脚本在不断循环,可能每次enemies都不一样,而上面的代码只是取出enemies中第一个可拾取对象进行拾取。这样会发生在拾取的途中,enemies改变,第一个可拾取对象也跟着改变,结果就是第一个还没拾取到,就跑去拾取第二个。
具体怎么实现可以看一下我以前写的挂机脚本,贾维斯也借鉴过。时间太久,很久不研究ni了,已经忘了,目前主要研究反汇编,比这有意思:lol。

最后如果你还想搞懂ni.objects,可以用下面的代码遍历一下,再看一下enemiesinrange()函数内部封装的代码。自己慢慢体会,如果还是看不懂就只能加强基础了。
for k, v in pairs(ni.objects) do
      print(k,v)
end      



7858321 发表于 2024-5-28 17:38:30

本帖最后由 7858321 于 2024-5-28 05:40 PM 编辑

blxyz521 发表于 2024-5-21 10:03 AM
对于新手来说,要理解ni.objects是有点困难的,而且对大部分人来说是用不到ni.objects的,新手更加用不到, ...
因为脚本在不断循环,可能每次enemies都不一样,而上面的代码只是取出enemies中第一个可拾取对象进行拾取。这样会发生在拾取的途中,enemies改变,第一个可拾取对象也跟着改变,结果就是第一个还没拾取到,就跑去拾取第二个。

这个好说啊,用table.sort()按照guid进行排序不就行了,周围可拾取死亡的单位id是固定的,用id进行排序拾取就好了,除非拾取过程中新生成一个可拾取对象
关键是ni的官方wiki没有ni.unit.islootable(unit)这个函数,只有个正在拾取状态ni.unit.islooting(unit),请问你在哪里知道的这个函数啊?不会是discord上问出来的吧?

7858321 发表于 2024-5-28 19:48:23

本帖最后由 7858321 于 2024-5-28 07:50 PM 编辑

我找到ni.unit.islootable(unit)这个函数在哪里了!
在ni\addon\Core\unit.lua里面,这里的unit的函数库,这可比官方的wiki详细多了,有很多wiki都没有说明,直接用chatgpt翻译一下为

unit.incombat:检查单位是否在战斗中。
unit.itemlvl:获取单位装备物品的平均物品等级。
unit.exists:检查单位是否存在。
unit.los:检查单位是否在视线范围内。
unit.creator:获取单位的创建者。
unit.creations:获取指定单位的创建物。
unit.creaturetype:获取单位的生物类型。
unit.istotem:检查单位是否是图腾。
unit.readablecreaturetype:获取单位的可读生物类型。
unit.combatreach:获取单位的近战攻击范围。
unit.isboss:检查单位是否是boss。
unit.threat:获取单位的威胁值。
unit.ismoving:检查单位是否在移动。
unit.movingtime:获取单位的移动时间。
unit.id:获取单位的唯一标识。
unit.shortguid:获取单位的简短唯一标识。
unit.isdummy:检查单位是否是训练假人。
unit.ttd:获取单位的剩余生存时间。
unit.hp:获取单位的生命值百分比。
unit.hpraw:获取单位的生命值。
unit.hppredicted:获取单位的预测生命值百分比。
unit.power:获取单位的能量值。
unit.powerraw:获取单位的能量值(原始值)。
unit.info:获取单位的信息。
unit.location:获取单位的位置。
unit.newz:获取单位的新高度。
unit.path:获取单位的路径。
unit.castingpercent:获取单位施法进度百分比。
unit.channelpercent:获取单位引导进度百分比。
unit.aura:检查单位是否拥有指定光环。
unit.auras:检查单位是否拥有指定的光环组合。
unit.buff:检查单位是否拥有指定增益效果。
unit.debuff:检查单位是否受到指定减益效果影响。
unit.spellstealable:检查单位是否可以偷取法术。
unit.isfacing:检查单位是否面向另一个单位。
unit.notbehindtarget:检查单位是否不在目标背后。
unit.isbehind:检查单位是否在目标后方。
unit.distance:获取单位之间的距离。
unit.distancesqr:获取单位之间的距离的平方。
unit.meleerange:获取单位的近战范围。
unit.inmelee:检查单位是否处于近战范围内。
unit.enemiesinrange:获取在单位周围指定距离内的敌对单位。
unit.friendsinrange:获取在单位周围指定距离内的友方单位。
unit.unitstargeting:获取瞄准指定单位的其他单位。
unit.iscasting:检查单位是否正在施放法术。
unit.ischanneling:检查单位是否正在引导法术。
unit.target:获取单位的目标。
unit.incombatwithme:检查单位是否在与当前玩家战斗。
unit.flags:获取单位的标识。
unit.dynamicflags:获取单位的动态标识。
unit.istappedbyallthreatlist:检查单位是否被所有威胁列表占用。
unit.islootable:检查单位是否可拾取。
unit.istaggedbyme:检查单位是否被当前玩家标记。
unit.istaggedbyother:检查单位是否被其他玩家标记。
unit.canperformaction:检查单位是否能执行动作。
unit.isconfused:检查单位是否混乱。
unit.notbleed:检查单位是否不会流血。
unit.isdisarmed:检查单位是否被缴械。
unit.isfleeing:检查单位是否正在逃跑。
unit.islooting:检查单位是否正在拾取物品。
unit.ismounted:检查单位是否处于骑乘状态。
unit.isnotattackable:检查单位是否不可被攻

blxyz521 发表于 2024-5-28 22:50:07

7858321 发表于 2024-5-28 07:48 PM
我找到ni.unit.islootable(unit)这个函数在哪里了!
在ni\addon\Core%unit.lua里面,这里的unit的函数库,这 ...

你现在才发现吗?:L Core文件夹里面基本都是函数库,用的最多的就是unit和player。
ni原来有自己的API网站,那个是最全面的,基本和.lua一致,现在貌似挂了。

blxyz521 发表于 2024-5-28 23:19:19

本帖最后由 blxyz521 于 2024-5-28 11:23 PM 编辑

7858321 发表于 2024-5-28 05:38 PM
因为脚本在不断循环,可能每次enemies都不一样,而上面的代码只是取出enemies中第一个可拾取对象进行拾取 ...
都说了只是简单的逻辑,而且enemies都改变了,你觉得enemies按GUID排序有用吗?
比如enemies里面有A、B两个对象,你要去拾取A,结果在半道上视野变了,新的视野多出来一个对象(队友击杀的,或者之前遗漏的),enemies变成了A、B、C,如果C的guid排序靠前,是不是A还没拾取到,就又跑去拾取C了?即使不用GUID排序,新的enemies也可能会是C、A、B,排序机制就是个迷。或者B出了视野,只剩C、A等等。这不仅会影响效率,并且可能导致不可预测的结果,比如卡位等等。
比较靠谱的办法是按距离排序,检测是否在视线范围内(与目标之间是否有障碍物,防止卡位),在拾取途中锁定enemies不更新,并加入时间判断,超时就放弃这个拾取目标。当然,上面的情况出现几率很小,但是做脚本就应该考虑到这些,不然搞不好就白挂很长时间。

a1300787 发表于 2025-4-16 20:28:34

{:5_248:}学习了, 还是有很多坑要走
页: [1]
查看完整版本: 关于NI 对象管理器函数的用法,望高手指点一下