Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

My while loop won't work even though VALUE is true?

Asked by 5 years ago
Edited 5 years ago

Even though pressed is true the loop won't start?

btw there is a value called pressed and it is false

wait(5)
--Varibles
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local pressed = false
local character = game.Workspace[player.Name]
local RoundNumber = 10

--Round function
local function Round(Number)
    return math.floor((Number / RoundNumber) + 0.5) * RoundNumber
end

--Wall
while pressed == true do
    print("test")
    local x = character.LowerTorso.Position.x
    local y = character.LowerTorso.Position.y
    local z = character.LowerTorso.Position.z
    game.Workspace.TransparentTestWall.Position = Vector3.new(Round(x), y+7.8, Round(z) -16.5)
    wait(0.01)
end

mouse.KeyDown:Connect(function(key)
    if key == "q" then
        pressed = true
        print(pressed)
    end
end)
0
no retrobricks 162 — 5y
0
*wait (0.01)* Doesn't work anymore, only *(0.1)* works now. dawidu156 5 — 5y
0
its a local script retrobricks 162 — 5y
0
yes retrobricks 162 — 5y
View all comments (8 more)
0
in the script retrobricks 162 — 5y
0
il edit it for the whole script retrobricks 162 — 5y
0
Im not certain this is the issue but, try putting your Keydown function above the while loop in the script. DinozCreates 1070 — 5y
0
already have... retrobricks 162 — 5y
0
once the script runs to the point of the while loop and it sees that pressed is false, it will go past it. its not going to wait for the value to turn to true. you have to use an event for that or an infinite loop Gey4Jesus69 2705 — 5y
0
.1* Ziffixture 6913 — 5y
0
I would just do while wait() do and put if statement in it. (if pressed == true then) CrazyTwinkle -1 — 5y
0
That is bad practice. I wouldn't recommend it. User#25115 0 — 5y

2 answers

Log in to vote
3
Answered by 5 years ago
Edited 5 years ago

Hello there! Your issue is common to many and unique to none. We should be able to get your script working pretty quickly. I'll just list the issues here for a quick overview:

  • You assume that a while loop keeps checking after the condition is determined to be false.

  • You are using KeyDown, a deprecated event.

  • You are defining the character through the workspace, which is not good practice.

  • You have a wait(5) at the top of your script for no reason.

  • I couldn't find anything about LowerTorso. I'm not sure if it exists. I'll be using the HumanoidRootPart instead.


Now that I've listed the problems, let's go about solving them. First of all, your while loop will stop checking the condition once it's false. Here's a simpler example so you can see why:

local x = 1
while x < 5 do
    x = x + 1
    print(x)
end
print("loop is done")
x = 3
-- Nothing else prints

As you can see, this won't work for what you are trying to do. There are two alternatives to your problem (I will include examples at the end of my answer):

1.) Put the while loop in a function that is called whenever q is pressed.

2.) Put the while loop in the event listener directly.


The next problem is that you are using KeyDown, a deprecated event. If you look here, you can see a message that says, "Mouse events have been superseded by UserInputService which should be used in all new work." Clearly, we are intended to use UserInputService instead. For this answer, I'm just going to cover how to detect a key being pressed(If you want a button to pop up for a mobile user, you may want to consider using ContextActionService instead). Here's an example of how you would implement UserInputService to detect the q key being pressed with InputBegan:

--[[
    GetService is the recommended method 
    for getting services, especially on the client.
--]]
local userInputService = game:GetService("UserInputService") 

userInputService.InputBegan:Connect(function(inputObj, gameProcessed)
    if not gameProcessed and inputObj.KeyCode == Enum.KeyCode.Q then
        print("Pressed")
    end
end)

Quick note about the gameProcessed parameter from the API reference:

Indicates whether the game engine internally observed this input and acted on it. Generally this refers to UI processing, so if a button was touched or clicked from this input, gameProcessedEvent would be true. This is also true for input events connected via ContextActionService.


Finally, that wait(5) at the top of your script is unnecessary. If you're using the proper methods in their proper places, there is no need to yield. You can use the :Wait() method of the CharacterAdded event to wait for the character to load in, if it hasn't already.


Ok, here you are. Your final script should look like one of these two options:

--[[ Services ]]--

local players = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

--[[ Variables ]]--

local player = players.LocalPlayer
local pressed = false
local character = player.Character or player.CharacterAdded:Wait()
local wall = workspace.TransparentTestWall -- define variables for things you are using
local RoundNumber = 10

--[[ Functions ]]--

local function Round(Number)
    return math.floor((Number / RoundNumber) + 0.5) * RoundNumber
end

local function changePos()
    while pressed do -- pressed == true is redundant
        print("test")

        local torsoPos = character.HumanoidRootPart.Position
        local x = hrpPos.x
        local y = hrpPos.y
        local z = hrpPos.z

        wall.Position = Vector3.new(Round(x), y+7.8, Round(z) -16.5)

        wait(0.01)
    end
end

userInputService.InputBegan:Connect(function(inputObj, gameProcessed)
    if not gameProcessed and inputObj.KeyCode == Enum.KeyCode.Q then
        print("Pressed")
        if pressed then -- I included a way to turn it off
            pressed = false
        else
            pressed = true
            changePos()
        end
    end
end)

or

--[[ Services ]]--

local players = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

--[[ Variables ]]--

local player = players.LocalPlayer
local pressed = false
local character = player.Character or player.CharacterAdded:Wait()
local wall = workspace.TransparentTestWall -- define variables for things you are using
local RoundNumber = 10

--[[ Functions ]]--

local function Round(Number)
    return math.floor((Number / RoundNumber) + 0.5) * RoundNumber
end

userInputService.InputBegan:Connect(function(inputObj, gameProcessed)
    if not gameProcessed and inputObj.KeyCode == Enum.KeyCode.Q then
        print("Pressed")
        if pressed then -- I included a way to turn it off
            pressed = false
        else
            pressed = true
            while pressed do -- pressed == true is redundant
                print("test")

                local hrpPos = character.HumanoidRootPart.Position
                local x = hrpPos.x
                local y = hrpPos.y
                local z = hrpPos.z

                wall.Position = Vector3.new(Round(x), y+7.8, Round(z) -16.5)

                wait(0.01)
            end
        end
    end
end)

Personally, I prefer the former, but it's really up to you.

I hope this helps. Have a great day scripting!

0
Note that anything you do client side will not replicate to the server. If you want to have that functionality, you'll have to use remotes. More on those here: https://wiki.roblox.com/index.php?title=Remote_Functions_%26_Events User#25115 0 — 5y
0
If you have any additional comments or questions, feel free to ask them below. User#25115 0 — 5y
0
Your a god. retrobricks 162 — 5y
Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

Try this:

wait(5)
--Varibles
local UIS = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local pressed = Instance.new("BoolValue")
pressed.Name = "Pressed" --so we can run .Changed
pressed.Parent = player
local character = player.Character or player.CharacterAdded:Wait() --never scan in workspace for character
local RoundNumber = 10

--Round function
local function Round(Number)
    return math.floor((Number / RoundNumber) + 0.5) * RoundNumber
end

--Wall
pressed:GetPropertyChangedSignal("Value"):Connect(function()
    while pressed.Value == true do
        print("test")
        local x = character.LowerTorso.Position.x
        local y = character.LowerTorso.Position.y
        local z = character.LowerTorso.Position.z
        game.Workspace.TransparentTestWall.Position = Vector3.new(Round(x), y+7.8, Round(z) -16.5)
        wait(0.01)
    end
end)

UIS.InputBegan:Connect(function(key,gameProc) --mouse.KeyDown deprecated
    if not gameProc then --if not interacting with core gui
        if key.KeyCode == Enum.KeyCode.Q then
            pressed.Value = true
        end
    end
end)

Note my comments, as well as the fact that changes to parts in workspace via the client will not replicate to the server. If you don't want this change to occur locally, you'll have to use remote events.

0
Answers beginning with "Try this:" are generally bad. User#25115 0 — 5y
0
i explained my answer in the code so whatever Gey4Jesus69 2705 — 5y

Answer this question