解决报错并完整编写出修复后的脚本
[LUA-print] stack traceback:
[string "scripts/GUI/GUI.lua"]:101: in function 'CheckIsInvalidCObject'
[string "scripts/GUI/GUI.lua"]:1065: in function 'setAnchorPoint'
[string "GUILayout/GUIUtil.lua"]:57: in fu
根据报错信息,问题出现在`GUIUtil.lua`文件的第57、58、61行,分别调用了`setAnchorPoint`、`setPosition`和`setOpacity`函数,但这些函数的参数`widget`是`nil`值。这通常是因为创建控件失败或获取控件对象时出现了问题。
让我帮你修复这个脚本。主要问题在于:
1. 创建控件前没有检查父节点是否有效
2. 没有正确处理控件创建失败的情况
修复后的完整脚本:
```lua
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
cogin = {}
cogin.drop = SL:Require("GUILayout/config/drop.lua", true)
local function init()
SL:Require("GUILayout/FeiJianAction", true)
end
local result, errinfo = pcall(init)
if not result then
SL:Print("初始化错误:", errinfo)
end
-- 注册NPC层状态事件
SL:RegisterLUAEvent('LUA_EVENT_NPCLAYER_OPENSTATUS', 'jiemian', function(status)
if status then
local NPCLayerMediator = global.Facade:retrieveMediator("NPCLayerMediator")
if not NPCLayerMediator or not NPCLayerMediator._layer then
return nil
end
GUI:Timeline_Window2(NPCLayerMediator._layer)
end
end)
-- 注册PC小地图状态变化事件
SL:RegisterLUAEvent('LUA_EVENT_PCMINIMAP_STATUS_CHANGE', '竞速之地', function(status)
if status == 3 then
SL:SendNetMsg(130)
end
end)
-- 创建地图名称显示模块
MapNameDisplay = {}
function MapNameDisplay:create()
-- 获取屏幕尺寸
local screenW = SL:GetMetaValue("SCREEN_WIDTH")
local screenH = SL:GetMetaValue("SCREEN_HEIGHT")
-- 创建父节点(使用主界面附着点) - 先检查父节点是否存在
local parent = GUI:Attach_MainMiniMap()
if GUI:Win_IsNull(parent) then
SL:Print("父节点创建失败,使用备用方案")
-- 尝试使用其他附着点或创建新窗口
parent = GUI:Win_Create("MapNameParent", 0, 0, screenW, screenH, false, false, true, false, false, false, 1)
end
if GUI:Win_IsNull(parent) then
SL:Print("无法创建有效的父节点")
return false
end
-- 创建文字控件
local textLabel = GUI:Text_Create(parent, "MapName_Display", 0, 0, 40, "#ffffff", "")
-- 检查控件是否创建成功
if GUI:Win_IsNull(textLabel) then
SL:Print("文字控件创建失败")
return false
end
-- 设置文字居中
GUI:setAnchorPoint(textLabel, 0.5, 0.5)
GUI:setPosition(textLabel, screenW/2, screenH/2)
-- 初始设置为透明
GUI:setOpacity(textLabel, 0)
-- 存储引用
MapNameDisplay._textLabel = textLabel
-- 注册地图切换事件
SL:RegisterLUAEvent(LUA_EVENT_MAPINFOCHANGE, "MapNameDisplay", MapNameDisplay.onMapChange)
return true
end
function MapNameDisplay.onMapChange()
-- 检查控件是否存在
if GUI:Win_IsNull(MapNameDisplay._textLabel) then
SL:Print("文字控件不存在,重新创建")
MapNameDisplay:create()
if GUI:Win_IsNull(MapNameDisplay._textLabel) then
return
end
end
-- 获取当前地图名称
local mapName = SL:GetMetaValue("MAP_NAME") or ""
-- 更新文字内容
GUI:Text_setString(MapNameDisplay._textLabel, mapName)
-- 淡入淡出动画序列
local fadeIn = GUI:ActionFadeTo(0.5, 255) -- 0.5秒淡入到完全不透明
local delay = GUI:DelayTime(1.5) -- 保持1.5秒
local fadeOut = GUI:ActionFadeTo(0.5, 0) -- 0.5秒淡出到透明
-- 创建动作序列
local sequence = GUI:ActionSequence(fadeIn, delay, fadeOut)
-- 执行动画
GUI:runAction(MapNameDisplay._textLabel, sequence)
end
-- 初始化
function MapNameDisplay.main()
local success = MapNameDisplay:create()
if success then
SL:Print("地图名称显示模块初始化成功")
else
SL:Print("地图名称显示模块初始化失败")
end
end
-- 延迟调用初始化,确保游戏环境已准备好
SL:ScheduleOnce(function()
MapNameDisplay.main()
end, 0.1)
```
**修复的关键点:**
1. **增加了nil值检查**:在所有GUI操作前使用`GUI:Win_IsNull()`检查控件是否有效
2. **父节点验证**:创建父节点时检查是否成功,失败时尝试备用方案
3. **控件创建验证**:创建文字控件后立即检查是否成功
4. **容错处理**:在事件回调中重新检查控件状态,必要时重新创建
5. **延迟初始化**:使用`SL:ScheduleOnce`延迟0.1秒执行,确保游戏环境已完全初始化
**错误原因分析:**
- 原脚本在游戏环境未完全初始化时就尝试创建界面元素
- 没有检查`GUI:Attach_MainMiniMap()`返回的父节点是否有效
- 直接对可能为nil的控件调用GUI操作函数导致报错
现在这个修复后的脚本应该能正常运行,不会再出现"target is nil value"的错误了。如果还有问题,记得检查浮生梦老师前端课程中关于界面初始化的内容!