Roblox Studio:为何我的while循环仅执行一次?
问题根源与解决方案
你的循环只执行一次的核心原因是:这个while循环是一次性的检查逻辑——脚本启动时只会判断一次script.Event.Value是否为true,执行完循环体后就直接退出了,后续再修改Event.Value也不会触发循环,因为循环已经结束了。
要实现"每次Event.Value变为true时就执行逻辑",应该改用Roblox的事件监听机制,监听Event的Changed事件,而不是用一次性的while循环。同时你的代码还有几个可以优化的点,比如重复命名控件、冗余的if-else判断,下面是修复后的完整代码:
-- 符号映射字典:替代一堆if-else,更简洁 local symbolOffsets = { ["!"] = Vector2.new(0, 0), ["$"] = Vector2.new(34, 0), ["%"] = Vector2.new(85, 0), ["&"] = Vector2.new(128, 0), ["'"] = Vector2.new(170, 0), ["("] = Vector2.new(214, 0), [")"] = Vector2.new(256, 0), ["+"] = Vector2.new(298, 0), [","] = Vector2.new(341, 0), ["-"] = Vector2.new(384, 0), ["."] = Vector2.new(421, 0), ["/"] = Vector2.new(469, 0), } local imagesize = UDim2.new(0, 26, 0, 26) local latin1 = "rbxassetid://12007406706" local backgroundtransparency = 1 local texttransparency = 0 local textcolor = Color3.fromRGB(255, 255, 255) local letternumber = 1 local function createLetter() -- 给每个字母控件唯一命名,避免重复覆盖 local letter = Instance.new("ImageLabel") letter.Name = "Letter_" .. letternumber letter.Position = UDim2.new(0, 0, 0, 37) letter.Size = imagesize letter.Image = latin1 letter.BackgroundTransparency = backgroundtransparency letter.ImageTransparency = texttransparency letter.ImageColor3 = textcolor letter.ImageRectSize = Vector2.new(42, 43) letter.BorderSizePixel = 0 local extend = Instance.new("ImageLabel") extend.Name = "Extend_" .. letternumber extend.Size = UDim2.new(0, 33, 0, 100) extend.Image = "rbxassetid://12049101680" extend.BackgroundTransparency = 1 extend.ImageRectSize = Vector2.new(85, 256) extend.BorderSizePixel = 0 extend.ImageRectOffset = Vector2.new(97, 0) extend.Parent = script.Parent letter.Parent = extend script.LetterImage.Value = letter letternumber = letternumber + 1 script.Event.Value = true end -- 监听Event的Value变化,每次变为true时执行逻辑 script.Event.Changed:Connect(function(newValue) if newValue ~= true then return end script.Event.Value = false -- 动态获取最新的Prompt值,避免一开始赋值后不更新 local promptstring = script.Parent.Prompt.Value local currentChar = string.sub(promptstring, letternumber, letternumber) print(currentChar) -- 用字典直接获取偏移量,替代冗余的if-else local offset = symbolOffsets[currentChar] if offset then createLetter() script.LetterImage.Value.ImageRectOffset = offset end end)
关键改动说明
- 替换循环为事件监听:用
script.Event.Changed:Connect()监听Value变化,每次值变为true时就执行逻辑,这是Roblox中响应变量变化的标准方式,不会像while循环那样执行一次就结束。 - 符号映射字典:把所有符号对应的偏移量放进字典里,直接通过字符索引获取,去掉了十几行冗余的if-else判断,代码更简洁易维护。
- 唯一命名控件:原来的
ip()函数里创建的控件都叫"c1"和"Extend",会导致新创建的控件覆盖旧的,现在用Letter_+序号的方式命名,保证每个控件唯一。 - 动态获取promptstring:原来的
promptstring是脚本启动时赋值的,后续Prompt.Value变化不会更新,现在放在事件回调里每次获取最新值。
内容的提问来源于stack exchange,提问作者tistcraft
相关产品推荐
相关产品推荐

