So I’m making a puzzle inspired by the one in the game “The Door in the Basement” in which you have to line up some platforms rotated 90 degrees by valves in order to cross a cave. I managed to get the platforms to rotate, but there are one or two that I’d prefer to only be able to rotate a limited number of times before rotating back. Here’s 2 clips from The Door in the Basement showing this:
As you can see, they can only be rotated so many times in a certain direction. Now here’s a clip showing my game:
As you can see, the first platform in my game rotates an infinite amount of times towards the left, causing it to clip through the other rotating platforms and just makes things look messy. I’d like for it to only rotate a limited amount of times (2) in said direction before it’s able to rotate back again with the cycle continuing. Here’s the script that controls the current rotation behavior:
local info = TweenInfo.new(1.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,0,false,0)
local alreadyTriggered = false
local Valve = script.Parent
local ValveClickDetector = script.Parent.ClickDetector
Valve.ClickDetector.MouseClick:Connect(function()
if alreadyTriggered == false then
alreadyTriggered = true
local goals = {
Orientation = Vector3.new(RotatingPart.Orientation.X, RotatingPart.Orientation.Y - -90, RotatingPart.Orientation.Z)
}
local tween = game:GetService("TweenService"):Create(RotatingPart,info,goals)
ValveClickDetector.MaxActivationDistance = 0
tween:Play()
tween.Completed:Wait(1.5)
ValveClickDetector.MaxActivationDistance = 12
alreadyTriggered = false
end
end)
The whole little setup just incase you wanna see it:
You could keep track of the number of turns like this:
local info = TweenInfo.new(1.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,0,false,0)
local alreadyTriggered = false
local Valve = script.Parent
local ValveClickDetector = script.Parent.ClickDetector
local turnLeft = true
local maxTurns = 2
local turnNum = 0
Valve.ClickDetector.MouseClick:Connect(function()
if alreadyTriggered == false then
alreadyTriggered = true
turnNum+=1
if turnNum==maxTurns then
turnLeft = not turnLeft
turnNum = 0
end
local goals
if turnLeft then
goals = {
Orientation = Vector3.new(RotatingPart.Orientation.X, RotatingPart.Orientation.Y + 90, RotatingPart.Orientation.Z)
}
else
goals = {
Orientation = Vector3.new(RotatingPart.Orientation.X, RotatingPart.Orientation.Y - 90, RotatingPart.Orientation.Z)
}
end
local tween = game:GetService("TweenService"):Create(RotatingPart,info,goals)
ValveClickDetector.MaxActivationDistance = 0
tween:Play()
tween.Completed:Wait(1.5)
ValveClickDetector.MaxActivationDistance = 12
alreadyTriggered = false
end
end)
Thanks, it works (almost). When you turn the maxTurns backwards again though and you get it back at the starting position, it moves to the right 1 time when you try turning it back around again but it then goes back to working normal towards the left if that makes sense. Why could that be?
(Btw I’ve been trying to send some clips on the problem but it keeps failing to upload for some reason)
Why are you using the Orientation property? That is a terrible approach. The property should never be edited unless you have something like an F3X-like tool.
Use CFrame instead and do CFrame = RotatingPart.CFrame * CFrame.Angles(0,math.pi,0)
The orientation part of the script was made by someone else who helped me the other day with something else, had no idea it’s a bad approach but works fine for me at the end of the day. Would you happen to know though why
?
I’m using the code that Kolvian provided now and it almost worked but the rotation acts a little off at the end:
Rotated towards the right when it’s only supposed to rotate towards the left.
Orientation is a property that resets after going above 180 degrees. If you add 90 to 180 you get 270, but orientation will go negative at that direction (for whatever reason), thus your model will be rotated incorrectly.
Alright cool cool, and what exact changes and where in the script should they be made? I tried changing it to CFrame rather than Orientation as you recommended but am struggling a tad bit with that. This is what the script looks like right now:
local info = TweenInfo.new(1.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,0,false,0)
local alreadyTriggered = false
local Valve = script.Parent
local ValveClickDetector = script.Parent.ClickDetector
local RotatingPart = game.Workspace.RotatingPart1
local turnLeft = true
local maxTurns = 3
local turnNum = 0
Valve.ClickDetector.MouseClick:Connect(function()
if alreadyTriggered == false then
alreadyTriggered = true
turnNum+=1
if turnNum==maxTurns then
turnLeft = not turnLeft
turnNum = 0
end
local goals
if turnLeft then
goals = {
Orientation = Vector3.new(RotatingPart.Orientation.X, RotatingPart.Orientation.Y + 90, RotatingPart.Orientation.Z)
}
else
goals = {
Orientation = Vector3.new(RotatingPart.Orientation.X, RotatingPart.Orientation.Y - 90, RotatingPart.Orientation.Z)
}
end
local tween = game:GetService("TweenService"):Create(RotatingPart,info,goals)
ValveClickDetector.MaxActivationDistance = 0
tween:Play()
tween.Completed:Wait(1.5)
ValveClickDetector.MaxActivationDistance = 12
alreadyTriggered = false
end
end)
Replace Orientation = ... with CFrame = RotatingPart.CFrame * CFrame.Angles(0,math.pi/2,0) and make it -math.pi/2 for the other one that rotates it in the other direction.
Awesome! Got it to work with CFrame now. It just seems to still do the weird rotating to the right 1 time at the end thing though just like in the previous footage I shared back when it still had Orientation. What do you think could be the cause this time?
local info = TweenInfo.new(1.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,0,false,0)
local alreadyTriggered = false
local Valve = script.Parent
local ValveClickDetector = script.Parent.ClickDetector
local RotatingPart = game.Workspace.RotatingPart1
local turnLeft = true
local maxTurns = 3
local turnNum = 0
Valve.ClickDetector.MouseClick:Connect(function()
if alreadyTriggered == false then
alreadyTriggered = true
turnNum+=1
if turnNum==maxTurns then
turnLeft = not turnLeft
turnNum = 0
end
local goals
if turnLeft then
goals = {
CFrame = RotatingPart.CFrame * CFrame.Angles(0,math.pi/2,0)
}
else
goals = {
CFrame = RotatingPart.CFrame * CFrame.Angles(0,-math.pi/2,0)
}
end
local tween = game:GetService("TweenService"):Create(RotatingPart,info,goals)
ValveClickDetector.MaxActivationDistance = 0
tween:Play()
tween.Completed:Wait(1.5)
ValveClickDetector.MaxActivationDistance = 12
alreadyTriggered = false
end
end)
but now it seems to go back to rotating infinitely like how the problem was from the start?
If I were to guess, something of the way the script is set up at the top could be adding additional movement towards the right side once you’ve reached the maxTurns backwards. If you notice, it doesn’t do this movement the first time you reach the maxTurns, only when you are back to the original state it was in. Do you think there’s a way for it to avoid any movement towards the other side once it’s back in it’s original state? Not sure how it would be.
Sorry still a bit confused on how printing this will help fix the problem. It does print though after you turn it and the tween plays. What from here though?
I added a wait of 1.5 seconds in hopes that that’s the wait before the ClickDetector MaxActivationDistance = 12 again.
By results do you mean like if I’m satisfied with when it prints true and false representing how many times it rotates each direction? If so probably not so much satisfied
If I’m understanding right though, the number of trues and falses here represents how many rotations there are in each direction right? I’m guessing that there should only be two trues and 2 falses in a row each time as it’s supposed to only move twice only. Looks like it starts printing 3 times in a row after the first 2 trues play and I’m assuming this is where the running an extra time thing happens.
local info = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0)
local alreadyTriggered = false
local Valve = script.Parent
local ValveClickDetector = script.Parent.ClickDetector
local direction = 1
local maxPos = 2
local currentPos = 0
Valve.ClickDetector.MouseClick:Connect(function()
if alreadyTriggered == false then
alreadyTriggered = true
local goals = {
Orientation = RotatingPart.Orientation + Vector3.new(0, 90 * direction, 0)
}
local tween = game:GetService("TweenService"):Create(RotatingPart,info,goals)
ValveClickDetector.MaxActivationDistance = 0
tween:Play()
-- update currentPos in direction
currentPos += direction
-- if currentPos has reached either end
if currentPos == 0 or currentPos == maxPos then
-- invert direction
direction = -direction
end
tween.Completed:Wait()
ValveClickDetector.MaxActivationDistance = 12
alreadyTriggered = false
end
end)
I’m not sure that the starting direction and pos are correct (because of the - -90), if not you’d have to change currentPos to maxPos and direction to -1.