求教一个奇怪的问题!
本帖最后由 xiaoyao1 于 2024-8-25 09:50 PM 编辑------------初始化----
local myUnit = {}
function myUnit:New(unit)
local s = {}
setmetatable(s,self)
self.__index = self
s.name = GetUnitName(unit)
s.lv = UnitLevel(unit)
s.hp = UnitHealth(unit)
s.maxHp = UnitHealthMax(unit)
s.mp = UnitMana(unit)
s.maxMp = UnitManaMax(unit)
s.buff = BeeUnitBuffList(unit)
s.php = (s.hp / s.maxHp)*100
s.pmp = (s.mp / (s.maxMp > 0 and s.maxMp or 1)) * 100
s.Skill = {}
return s
end
function update_var(var,new_var)
var.value = new_var
end
local me = me or myUnit:New("player")
local tar = tar or myUnit:New("target")
update_var(me,myUnit:New("player"))
update_var(tar,myUnit:New("target"))
以上在魔蜂通过,建立了初始化脚本,在下面继续建立其他脚本
----加状态---
if me.hp then BeeRun("奥术光辉","nogoal") end
这话其实没啥实际意义,不用看运行啥,就看语句就好,提交保存时就报错提示attempt to index global 'me' (a nil value)
但如果在if后加一个条件就能通过,aabbcc甚至都没申明过。
if aabbcc and me.hp then BeeRun("奥术光辉","nogoal")end
多次测试,就是含有“me.”的不能紧放在if后面,放就报错,在if后加个任何其他条件就通过。想想以前编其他的时候似乎也遇到这种情况,当时就以为是方案内的各个脚本不在一个chunk,变量传不过来,所以不能用local,就把所有变量改成全局的,事实上不是这个引起的,改不改都一样。
这个啥情况,请各大佬不吝赐教!!
vshrd 发表于 2024-8-25 10:23 PM
嗯- -我看代码没问题
所以我猜你在最上面"初始化"部分的那一部分代码是放在了插件库里面,
所以在游戏里执 ...
还有如果把报错的这句话,也放到初始化区,是不会报错的,第一反应就会想是变量生命周期的问题。是魔蜂的bug? 嗯- -我看代码没问题
所以我猜你在最上面"初始化"部分的那一部分代码是放在了插件库里面,
所以在游戏里执行"加状态"部分才会报错
嗯= =
这个部分其实值得我单独开一篇教程
但我可以先提前简单的回复一下你的问题
当你在库里面去做了"local me = me or myUnit:New("player")"
这个实例化对象me是局部变量
而局部变量的生命周期只存在与当前的代码栈
而你在游戏里魔风编辑器中去调用me.hp的时候
"me"本身就是nil,那通过"me"再去找"me"的从属成员"hp"自然会报错
因为这是空引用,调用了空指针
可能这么说你不打听得懂
没关系
我尽快出一个带图文的详解教程 还有你是不是发错区了
这帖子怎么看都应该发在求助区吧?= = 猜错了,没有放在插件库,都是在魔蜂里运行的。
按照你的分析,那么在if里在me.的前面加个条件也不能运行才对,可实际上加个条件就能运行了。
就劳烦大佬转过去了。 本帖最后由 vshrd 于 2024-8-25 11:14 PM 编辑
xiaoyao1 发表于 2024-8-25 11:08 PM
猜错了,没有放在插件库,都是在魔蜂里运行的。
按照你的分析,那么在if里在me.的前面加个条件也不能运行 ...
那就比较奇怪了- -
我复制你的代码去测试了下
也没报错
你确定"加状态"的第一行就是直接紧接着上面那部分代码吗
xiaoyao1 发表于 2024-8-25 11:12 PM
还有如果把报错的这句话,也放到初始化区,是不会报错的,第一反应就会想是变量生命周期的问题。是魔蜂的 ...
哦 意思你代码分段了?那确实还是生命周期的问题
初始化和加状态的不在一个脚本里,me是局部变量,肯定报空值错误。
if aabbcc and me.hp then BeeRun("奥术光辉","nogoal")end,能编译通过时因为第一个条件aabbcc为空,所以后面的条件me.hp就不用判断了,直接就是假了。你给aabbcc赋值再运行还是会提示空值。
至于改成全局,也提示me是空值,应该是改了之后没运行一次,语法是没问题。
函数update_var看不明白是什么意思,猜测应该是泛型for没写完。
虽然语法是没问题,但是处理方式不对。update_var用来更新me的成员属性,你的处理方式是new一个新对象出来,然后再将每个属性赋值给me,这样有两个问题:
1、hp等属性需要频繁更新(一般都是逐帧更新),就会产生大量的对象,虽然lua自动回收死对象,但总归不太好。
2、各属性的更新频率,有的要求快速更新(hp、mp、buff),有的可以慢(lv,maxhp等),有的不需要更新(name),你这样一股脑的全部更新,浪费算力。
不明白为什么一味的追求面向对象,设计不出好的结构来只会事倍功半。 blxyz521 发表于 2024-8-26 12:02 AM
初始化和加状态的不在一个脚本里,me是局部变量,肯定报空值错误。
if aabbcc and me.hp then BeeRun(" ...
不存在的= =
新人先建立个印象就行了
之后我会带着手把手撸一套完整的通用框架出来= =
到时候也不用魔风了
稍微改改335 343 正式服啥版本都能用
现在就先以理解为主。能大概明白咋回事就行 大佬说的都对呀。
我那个也只是强行用了面向的方法
没有更新数据,只会建立很多实例
要新建一个更新,比如
function myUnit:Update()
self.name = self.name
self.lv = UnitLevel(self.unit)
self.hp = UnitHealth(self.unit)
self.maxHp = UnitHealthMax(self.unit)
self.mp = UnitMana(self.unit)
self.maxMp = UnitManaMax(self.unit)
self.php = (self.hp / self.maxHp) * 100
self.pmp = (self.mp / (self.maxMp > 0 and self.maxMp or 1)) * 100
end
然后要看什么时候调用这个更新,
me = myUnit:New("player")
me:Update()
不调用更新,只会是初始值
我的方法是 一直 创建me的实例,是个错误{:5_237:}