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

Why Does This Stop Working after the First Execution?

Asked by 9 years ago

What I'm making is a type of "Control Panel" thing that uses Surface GUIs and some brick rotations as "pages" for the Control Panel.

This is what it looks like and that "NEXT" button rotates the brick 90 degrees.

This gif shows how the next button works.

But after that the rotation doesn't work anymore, and it kind of twitches like this. (Unable to see the twitching effect through the gif, I'll provide a link so you can see the twitching directly in game.)

Here's the code for the "NEXT" button:

local screen = script.Parent.Parent.Parent.Parent
bin = script.Parent

bin.MouseButton1Click:connect(function()
    for i = 1, 90 do
        screen.Rotation = screen.Rotation + Vector3.new(0, 1, 0)
        wait()
    end
end)

If you could give me an explanation as to why it just sort of twitches that way after the first use, it'd be much appreciated!

Here's a link to the game to check it out for yourself.

Thanks!

1 answer

Log in to vote
2
Answered by 9 years ago

Since you're using Vector3 to rotate the object, the Vector3 position will flip because one of the values in over 90 and thus causing the axis to change.

To get the result you want, you should be using CFrame and CFrame.Angles. CFrame is much better in this case because it is specifically designed for both position and rotation, allowing for smooth rotation without it "jerking" like your script does.

Great, how do I change my script to use this?

It's quite simple, acutally, as we're only changing one line: Line 6.

Firstly, we're going to change Rotation to CFrame. Then, we can use the following equation to rotate the GUI.

screen.CFrame * CFrame.Angles(0,math.rad(1),0)

That basically rotates the CFrame by one degree each time (approximately 0.0174 radians), and since you're looping it 90 times, it will rotate 90 degrees smoothly (or a half of pi).

So overall, your script will look something like this:

local screen = script.Parent.Parent.Parent.Parent
bin = script.Parent

bin.MouseButton1Click:connect(function()
    for i = 1, 90 do
        screen.CFrame = screen.CFrame * CFrame.Angles(0,math.rad(1),0) --CFrame.Angles is measured in radians, so we are just converting 1 degree into radians so that the rotation isn't overdone.
        wait()
    end
end)

Now, I would also suggest you use debounce. A debounce is essentially a varialbe that stops a function running more than once at a time.

This is good in your case because if someone spams the next button, the rotation will be messed up. Using debounce, you can avoid this.

local screen = script.Parent.Parent.Parent.Parent
bin = script.Parent
local db = false --Our debounce variable.

bin.MouseButton1Click:connect(function()
    if db then return end --If the debounce variable is true then stop the function.
    db = true --Stops the function from running more than once at a time by making it true.
    for i = 1, 90 do
        screen.CFrame = screen.CFrame * CFrame.Angles(0,math.rad(1),0) --CFrame.Angles is measured in radians, so we are just converting 1 degree into radians so that the rotation isn't overdone.
        wait()
    end
    db = false --Make sure the debounce variable is false so you can run the function again.
end)

I hope this answer helped you. If it did, be sure to accept it.

0
Thanks a bunch! But one question, on line 6, how would it know if the debounce variable is true or not without any indication like "if db == true then return end." sidekick83 80 — 9y
0
if db then return end is the shorter way of doing that. If you added a 'not' (without quotes) after the if on line 6, it would basically stop the function if db was false, instead of stopping it when it's true. Spongocardo 1991 — 9y
Ad

Answer this question