LUACN论坛

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
热搜: YJWOW MagicStone BoL
查看: 1026|回复: 50

[综合] 求教一个奇怪的问题!

[复制链接]
发表于 2024-8-25 21:48:24 | 显示全部楼层 |阅读模式
本帖最后由 xiaoyao1 于 2024-8-25 09:50 PM 编辑

[Lua] 纯文本查看 复制代码
------------初始化----

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"))

以上在魔蜂通过,建立了初始化脚本,在下面继续建立其他脚本
[Lua] 纯文本查看 复制代码
----加状态---
if me.hp then BeeRun("奥术光辉","nogoal") end

这话其实没啥实际意义,不用看运行啥,就看语句就好,提交保存时就报错提示attempt to index global 'me' (a nil value)
但如果在if后加一个条件就能通过,aabbcc甚至都没申明过。
[Lua] 纯文本查看 复制代码
if aabbcc and me.hp then BeeRun("奥术光辉","nogoal")end

多次测试,就是含有“me.”的不能紧放在if后面,放就报错,在if后加个任何其他条件就通过。想想以前编其他的时候似乎也遇到这种情况,当时就以为是方案内的各个脚本不在一个chunk,变量传不过来,所以不能用local,就把所有变量改成全局的,事实上不是这个引起的,改不改都一样。
这个啥情况,请各大佬不吝赐教!!


回复

使用道具 举报

 楼主| 发表于 2024-8-25 23:12:55 | 显示全部楼层
vshrd 发表于 2024-8-25 10:23 PM
嗯- -我看代码没问题
所以我猜你在最上面"初始化"部分的那一部分代码是放在了插件库里面,
所以在游戏里执 ...

还有如果把报错的这句话,也放到初始化区,是不会报错的,第一反应就会想是变量生命周期的问题。是魔蜂的bug?
回复 支持 0 反对 1

使用道具 举报

发表于 2024-8-25 22:23:49 | 显示全部楼层
嗯- -我看代码没问题
所以我猜你在最上面"初始化"部分的那一部分代码是放在了插件库里面,
所以在游戏里执行"加状态"部分才会报错

嗯= =
这个部分其实值得我单独开一篇教程
但我可以先提前简单的回复一下你的问题

当你在库里面去做了"local me = me or myUnit:New("player")"
这个实例化对象me是局部变量
而局部变量的生命周期只存在与当前的代码栈

而你在游戏里魔风编辑器中去调用me.hp的时候
"me"本身就是nil,那通过"me"再去找"me"的从属成员"hp"自然会报错
因为这是空引用,调用了空指针

可能这么说你不打听得懂
没关系
我尽快出一个带图文的详解教程
回复 支持 0 反对 1

使用道具 举报

发表于 2024-8-25 22:26:09 | 显示全部楼层
还有你是不是发错区了
这帖子怎么看都应该发在求助区吧?= =
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-25 23:08:04 | 显示全部楼层
猜错了,没有放在插件库,都是在魔蜂里运行的。
按照你的分析,那么在if里在me.的前面加个条件也不能运行才对,可实际上加个条件就能运行了。
就劳烦大佬转过去了。
回复 支持 反对

使用道具 举报

发表于 2024-8-25 23:13:00 | 显示全部楼层
本帖最后由 vshrd 于 2024-8-25 11:14 PM 编辑
xiaoyao1 发表于 2024-8-25 11:08 PM
猜错了,没有放在插件库,都是在魔蜂里运行的。
按照你的分析,那么在if里在me.的前面加个条件也不能运行 ...

那就比较奇怪了- -
我复制你的代码去测试了下
也没报错
你确定"加状态"的第一行就是直接紧接着上面那部分代码吗
回复 支持 反对

使用道具 举报

发表于 2024-8-25 23:15:21 | 显示全部楼层
xiaoyao1 发表于 2024-8-25 11:12 PM
还有如果把报错的这句话,也放到初始化区,是不会报错的,第一反应就会想是变量生命周期的问题。是魔蜂的 ...

哦 意思你代码分段了?那确实还是生命周期的问题
回复 支持 反对

使用道具 举报

发表于 2024-8-26 00:02:22 | 显示全部楼层
初始化和加状态的不在一个脚本里,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),你这样一股脑的全部更新,浪费算力。
不明白为什么一味的追求面向对象,设计不出好的结构来只会事倍功半。
回复 支持 反对

使用道具 举报

发表于 2024-8-26 02:48:44 | 显示全部楼层
blxyz521 发表于 2024-8-26 12:02 AM
初始化和加状态的不在一个脚本里,me是局部变量,肯定报空值错误。

if aabbcc and me.hp then BeeRun(" ...

不存在的= =
新人先建立个印象就行了
之后我会带着手把手撸一套完整的通用框架出来= =
到时候也不用魔风了
稍微改改335 343 正式服啥版本都能用
现在就先以理解为主。能大概明白咋回事就行
回复 支持 反对

使用道具 举报

发表于 2024-8-26 09:33:34 | 显示全部楼层
大佬说的都对呀。
我那个也只是强行用了面向的方法
没有更新数据,只会建立很多实例
要新建一个更新,比如
[Lua] 纯文本查看 复制代码
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的实例,是个错误
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

小黑屋|手机版|Archiver|LUACN论坛

GMT+8, 2025-5-2 02:26 AM , Processed in 0.432348 second(s), 34 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表