9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:03:35 | 显示全部楼层 |阅读模式 15048 16

分享一些lua作图过程中的经验还有方法吧
A.开局入门的选择
y3的lua作图,是基于y3程序会在"游戏初始化"之前加载 script\main 文件,注意,是"游戏初始化"之前,比如界面ui编辑器,触发编辑器这些都是没有加载的,会先加载lua再加载这些
因此,如果需要开局调用资源,必须添加一个小的计时器

y3官方目前有两套框架,一个up,一个y3,up需要在官方群下载,y3是新建地图附送
我个人的建议是还是使用up框架,y3框架作为参考,因为我认为up框架更像过去的魔兽框架ac结构,简单清晰(可能我先入为主了)
以下是up框架需要修改的地方,请注意修改

event.lua  :{EVENT.ABILITY_ATTR_CHANGED,        '技能-属性变化',{{'__ability','skill'},'__ability_runtime_id'}},
    {EVENT.ABILITY_CS_START,            '技能-开始施法',{{'__ability','skill'},'__ability_runtime_id'}},  --开始阶段
    {EVENT.ABILITY_PS_START,            '技能-前摇开始',{{'__ability','skill'},'__ability_runtime_id'}}, --动作阶段
    {EVENT.ABILITY_PS_END,              '技能-施法引导',{{'__ability','skill'},'__ability_runtime_id'}}, --伤害阶段
    {EVENT.ABILITY_CST_END,             '技能-施法完成',{{'__ability','skill'},'__ability_runtime_id'}},  --引导结束
    {EVENT.ABILITY_END,                 '技能-施法停止',{{'__ability','skill'},'__ability_runtime_id'}}, --中间打断
   {{EVENT.MOUSE_WHEEL_EVENT,0xF3},      '鼠标-滚轮上滑',{{'__role_id','player'},'__mouse_wheel'}},
     {{EVENT.MOUSE_WHEEL_EVENT,0xF4},      '鼠标-滚轮下滑',{{'__role_id','player'},'__mouse_wheel'}},
{{EVENT.EVENT_CUSTOM,自定义事件id},"接受自定义事件",{'__c_param_dict'}},







原本的技能在注册的时候会丢失runtime_id,因此需要修改一下。注册上述技能事件的时候,请把runtimeid加上,不然会无法获取技能目标
比如

up.game:event('技能-开始施法',
function (_,ability,cast)
    ability._cast=cast
    Ability_Start(ability)
end)


需要加上 ability._cast=cast
其中自定义事件id这个是创建自定义事件后做TL交互的,等会我会讲一下简单的TL交互方法

--根据路径获取UI
function up.get_ui(path, _player)
   return gameapi.get_comp_by_absolute_path(_player._base or player, path)
end


获取ui的方法我记得原本好像忘了写return


修改完错误后,可以开始了~~~~
2楼讲热更新

9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:14:41 | 显示全部楼层
本帖最后由 无名拉二胡#7884 于 2023-5-17 17:46 编辑

2L 关于热更新的方法:
群里提供了断点调试的方法,这里我就不多说了,我想分享的是F5热更新的方法,比较简单
首先需要注册键盘事件,
我比较喜欢用table来处理修改事件,以下是我的注册方法:

Keyboard_EventFucs={} --键盘事件存储
up.game:event('键盘-按下',
function (_,player,key)   --注册键盘事件
    for k,v in pairs(Keyboard_EventFucs) do    --当存储表中存在键位的时候激活
        if key==KEY[k] then
            v(player)
        end
   
end
end)
--上述代码可以放到main里,必须在require 'up'的后面,因为依赖了up的库
--接下来是写一个热更新代码的方法,热读代码的渠道众所周知有load,loadfile,require 等
--这里是一个依赖require的方法,因为加载过的模块会被放在package.loaded,require识别到读过就不会再读,所以可以在package.loaded里删除该模块,重新加载
function reloadlua(name) --重新加载名字为name的lua文件
    package.loaded[name]=nil
    return(require (name))
end
--reloadlua即可重新加载任何lua文件,最后我们注册一个F5事件
Keyboard_EventFucs["F5"]=function()
    reloadlua("hotfresh")--这里我是在main下面做了一个hotfresh.lua ,现在我们按下F5就能重新加载lua文件了
end

--[[以上是所有可以直接复制的代码,接下来是一些注意事项
这个只是重新加载代码,和魔兽里七老大做的热更相比肯定还是有些缺陷,大家可能需要自己写重建事件,重建触发这些
我本人不喜欢重建,只喜欢修改,所以我没有做重构触发这些东西,我只是把需要更新的东西放在hotfresh里,在hotfresh文件下再次reloadlua XXX,实现热更文件内容
注意,热更会让所有全局变量重写,如果一些变量你怕丢失,怕需要重新弄,可以用or或if的结构来防止重写
比如ui的热更新,我更新换用  ui=ui or createui()这种方法,这样就不会重复创建,只会更新内容,对所有创建的代码采用or就会很舒服
防止重复加载的可以用if a==nil then 来保护
]]

3

主题

70

回帖

280

积分

管理员

【问题收集】

积分
280
发表于  2023-5-17 17:17:48 | 显示全部楼层
手动点赞,感谢分享-标注一次优秀
  • 现在能热更?不是每次发布之后的地图都是全量更新吗?
    2023-7-17 14:31

9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:25:58 | 显示全部楼层
本帖最后由 无名拉二胡#7884 于 2023-5-17 17:47 编辑

3L关于 TL交互:
我本人没有尝试用lua从T拿数据,因为我是纯lua作图,没这个需求,我这里就不献丑了,简单说一下怎么从T调用lua,可能这是T玩家比较需要的
首先 需要在T新建自定义事件,转成lua记录下id,自定义事件的参数需要1个字符串,1个字符串就行,就一个参数就行

{{EVENT.EVENT_CUSTOM,自定义事件id},"接受自定义事件",{'__c_param_dict'}},    在event里面加上这行,这个参数就是那一个参数了
然后在lua注册下面的事件
up.game:event('接受自定义事件',
function (_,dict)
    local fucstr=string.match(tostring(dict),".*': '(.-)'.-")
    load(fucstr)()
   
end

)--注册自定义事件


--解释一下,当你在T运行自定义事件时,你需要做的就是事件传个参数比如"add(a,b)"
--之后这个lua事件就会运行,你从lua拿到__c_param_dict,这是一个python的字典格式,可以通过字符串抓取拿到字符串,然后利用load函数,直接转化字符串为lua 函数,并运行
--没错,其实等于魔兽的japi   ExExcuteScript () 这里的问题是缺乏参数,运行个add()
--如果需要参数,最好都用整数或者字符串的参数,单位,特效这些都是有id的,自己在lua写转化id为对象就行了,up框架都有是吧.字符串就无所谓了,直接刚
--一些参数你也可以通过t转l自己拿放进去,懂得都懂
--返回值这件事,可以新建另一个自定义事件,用lua启动自定义事件来拿

9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:35:08 | 显示全部楼层
本帖最后由 无名拉二胡#7884 于 2023-5-17 17:47 编辑

D.关于ui和ui事件的注册
ui事件的注册方法是这样的
需要在event.lua 添加一些事件名称

table.insert(UI_EVENT_LIST,"移动格子_点击")
table.insert(UI_EVENT_LIST,"移动格子_右击")
table.insert(UI_EVENT_LIST,"底板背包_进入")
table.insert(UI_EVENT_LIST,"底板背包_离开")
table.insert(UI_EVENT_LIST,"退出按钮_进入")
table.insert(UI_EVENT_LIST,"退出按钮_离开")
table.insert(UI_EVENT_LIST,"退出按钮_点击")
--这些都是初始化之前完成的,如果不做,后面就没法使用
--如果你不确定名字,没关系,我们可以如下
for i=1,1000 do
table.insert(UI_EVENT_LIST,tostring(i))
end
--随便给1000个名字,之后给ui注册事件的时候用这个名字就行了,就是说,没有在初始化给名字的ui事件,是没法用的
--我还是习惯用表来存ui事件
UI_EventFucs={}
up.game:event('UI-事件',
function(_,player,eventid)  --和键盘事件一样,随时在表里添加删除
   for k,v in pairs(UI_EventFucs) do
        if k==eventid then
            v(player,eventid)
        end
   end
end)
end,0.5,false)
UIEvent_TYPE={
['点击']=1,
['弹起']=2,
['长按']=3,
['双击']=22,
['悬停']=23,
['进入']=24,
['离开']=25,
['右击']=26,
}--这里提供一下ui事件的类型啊,免得大家找不到对应,
--注册ui时间的方法
    local eventname= GameAPI.create_ui_comp_event_ex_ex(uid,UIEvent_TYPE[type],name)

--type方才介绍过了,uid就是ui的id,name就是事件名称,需要是初始化给过的哦,如果没给,就按我刚才说的,tostring(1到1000) 自己分配绑定,就能动态注册了

4

主题

6

回帖

81

积分

普通创作者

积分
81
发表于  2023-5-17 17:36:48 | 显示全部楼层
感谢感谢.希望论坛多一些技术分享。

9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:43:05 | 显示全部楼层
本帖最后由 无名拉二胡#7884 于 2023-5-17 17:47 编辑

E.关于ui的创建和定位
编辑器拿到的ui的uid是一串字符,新建ui是ui_comp啥啥的,无所谓,效果一样的,都能用
说些大伙可能不知道咋搞的?
1. 关于ui的定位
ui默认是中心对中心锚点,且对应的是父ui,就是子ui的坐标一定是相对父ui的,如果需要相对屏幕,可以自己在ui编辑器做一个四端锁0全屏的ui父模板,跟着这个模板就能坐标完全ok的
如果需要控制锚点,简单,如下:

local sitetab={
    [0]={-1,1},[1]={0,1},[2]={1,1},[3]={-1,0},[4]={0,0},[5]={1,0},[6]={-1,-1},[7]={0,-1},[8]={1,-1}}
   
    --["左上"]=0,["顶"]=1,["右上"]=2,["左"]=3,["中心"]=4,["右"]=5,["左下"]=6,["底"]=7,["右下"]=8
    --这个规则和魔兽一样的
    GameAPI.get_ui_comp_width(uid) 可以获取控件宽
    GameAPI.get_ui_comp_height(uid) 可以获取控件高
    --通过中心加减乘除不是都有了,以下是一个例子,宽高这些我是提前获取的
    local xc,yc= UIScripts[ui2].x or 0,UIScripts[ui2].y or 0 --参考ui的中心位置
      
        if UIScripts[ui1].father==UIScripts[ui1].related then
            xc,yc=(UIScripts[ui2].w/2),(UIScripts[ui2].h/2)
        end
      
        local xc1,yc1=sitetab[site2][1]*(UIScripts[ui2].w)/2+xc,sitetab[site2][2]*(UIScripts[ui2].h)/2 +yc--参考ui锚点位置
      
        local xc2,yc2=x+sitetab[site1][1]*(-(UIScripts[ui1].w)/2)+xc1,sitetab[site1][2]*(-UIScripts[ui1].h/2)+yc1+y
      
      
        --先偏移获得锚点位置,再根据宽高反偏移获得中心坐标
        UIScripts[ui1].x=xc2
        UIScripts[ui1].y=yc2
          --记录锚地便于实时移动

        up.ui:set_position(UIScripts[ui1].uid,{xc2,yc2}))

9

主题

17

回帖

881

积分

优秀创作者

积分
881

夏日·闪闪发光勋章

发表于  2023-5-17 17:44:47 | 显示全部楼层
本帖最后由 无名拉二胡#7884 于 2023-5-17 17:54 编辑

2.关于场景ui和ui模板
场景ui其实不一定要在界面编辑器场景ui模块建立,其实就在普通的画板画完隐藏都行
用法如下

local UIscence=  GameAPI.create_scene_node_on_point(UIScripts["SceneUI.物品名称"].uid,point._base,99999,100)
local text_uid=GameAPI.get_ui_comp_in_scene_ui(UIscence,"名称")
local uid=GameAPI.get_ui_comp_in_scene_ui(UIscence,"物品名称")
GameAPI.set_ui_comp_world_pos(up.get_localplayer()._base, uid,-75,0)

--ui模板用法也很类似,这里是我简单写的一个小面向对象封装

UIMods=UIMods or {}
ALLUIMods=ALLUIMods or {}
ALLUIModsN=ALLUIModsN or 0
UIMods.__index = UIMods

function UIMods.new(tempname,father,player)--建立ui模板
    --初始化self$如果没有这句$那么类所建立的对象改变$其他对象都会改变
    local self = {}
   --将self的元表设定为Class
    setmetatable(self,UIMods)
    local uid=UITemps[tempname] or tempname
    local father_uid=UIScripts[father].uid
    player=player or up.get_localplayer()
    local id=player:get_id()
    ALLUIModsN=ALLUIModsN +1
   
    self._base=(GameAPI.create_ui_prefab_instance(player._base,uid,father_uid))
    self.id=ALLUIModsN
    ALLUIMods[ALLUIModsN]=self
    return(ALLUIMods[ALLUIModsN])--返回ui组件
end
function UIMods:Getuid(name)--获取子控件的uid
    return GameAPI.get_ui_prefab_child_by_path(self._base,name)
end

function UIMods:Delete(time)--删除子控件
   
    GameAPI.del_ui_prefab(self._base)
    ALLUIMods[self.id]=nil
end



8

主题

10

回帖

182

积分

普通创作者

积分
182
发表于  2023-5-17 19:50:47 | 显示全部楼层
大佬牛逼
发表于  2023-5-17 22:02:49 | 显示全部楼层
大佬牛b
12下一页