Issue with Rotation Tween

Hey everyone,

I have a problem with my tween rotation regarding a model (Arrow). I have created a system where the Arrow will rotate -90 degrees on the X-axis when Power and LightEnabler are true (they are declared as true in separate bindable events prior to this event connection). Conversely, the Arrow will rotate to its original position by rotating +90 degrees if this isn’t the case.

However, this doesn’t work. This is because when the lever fires the GenDialTwoOn event by commenting GenDialTwoOff, the tween occurs and constantly fires, causing the Arrow to spin perpetually in the negative direction. On the other hand, when the GenDialTwoOff is fired, the Arrow constantly spins in the positive direction. This happens even without commenting GenDialTwoOn.

Here is a demonstration:
GenDialTwoOn firing

GenDialTwoOff firing

This is quite a difficult problem as I have tried to halt the tweens when they have reached my desired angles, and also because when the lever is first powered - making the lever become really red - the GenDialTwoOff tween occurs. Regarding the latter, I don’t want this to happen. It should only happen if the switch goes from green to red. This is a really complex problem for me :thinking:

In summary, this is how I’d like Arrow to move:

  1. Player turns on power, causing the Lever to go from smoky gray to really red (works)
  2. The Arrow stays at its original position
  3. When the lever is switched - going from really red to lime green - Arrow moves from 0, 180, 0 to
    -90, -180, 0
  4. When the lever is switched again - going back to really red - Arrow moves back to 0, 180, 0.

Thanks for any input!

local Power = false
local LightEnabler = false
local EventFired = false

FuelInserted.Event:Connect(function()
	local IsPowerOn = false
	local AreLightsEnabled = false

	local function UpdateLights()

		if Power and LightEnabler then	
			
			EventFired = true
			
			if EventFired then
				GenDialTwoOn:Fire()
				EventFired = false
			end
			
			LightPart.BrickColor = BrickColor.new("Lime green")
			LightPart.Material = Enum.Material.Neon
			Light.Enabled = true
			Light.Color = Color3.fromRGB(0, 255, 0)


			for i, Light in pairs(CeilingLights) do
				Light.Bulb.BrickColor = BrickColor.new("Medium red")
				Light.Bulb.Material = Enum.Material.Neon

				Light.Bulb.Beam.Enabled = true
				Light.Bulb.SpotLight.Enabled = true
			end

		else
			
			if not EventFired then
				GenDialTwoOff:Fire()
			end
			
			LightPart.BrickColor = BrickColor.new("Really red")
			LightPart.Material = Enum.Material.Neon
			Light.Enabled = true
			Light.Color = Color3.fromRGB(255, 0, 0)

			for i, Light in pairs(CeilingLights) do
				Light.Bulb.BrickColor = BrickColor.new("Buttermilk")
				Light.Bulb.Material = Enum.Material.Glass

				Light.Bulb.Beam.Enabled = false
				Light.Bulb.SpotLight.Enabled = false
			end
			
		end

	end
	
	UpdateLights()

end)
local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")

local LightPart = script.Parent

local Generator = game.Workspace.Generator
local DialTwo = Generator.Dial2

local GenDialTwo = Generator.Dial2
local GenDialTwoOn = ServerStorage.GenDial2On
local GenDialTwoOff = ServerStorage.GenDial2Off

GenDialTwoOn.Event:Connect(function()
	local Arrow = DialTwo.Arrow
	local PrimaryPart = DialTwo.Arrow.PrimaryPart

	local currentRotation = PrimaryPart.CFrame
	local targetRotation = currentRotation * CFrame.Angles(math.rad(-90), 0, 0)

	local tweenInfo = TweenInfo.new(
		0.5,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.Out,
		0,
		false
	)

	local tween = TweenService:Create(PrimaryPart, tweenInfo, {CFrame = targetRotation})

	tween:Play()

	local function checkRotation()
		local currentAngle = PrimaryPart.Rotation.X
		if currentAngle == -90 then
			tween:Cancel()
		end
	end

	while true do
		checkRotation()
		task.wait(0.1)
	end
	
end)

GenDialTwoOff.Event:Connect(function()
	local Arrow = DialTwo.Arrow
	local PrimaryPart = DialTwo.Arrow.PrimaryPart

	local currentRotation = PrimaryPart.CFrame
	local targetRotation = currentRotation * CFrame.Angles(math.rad(90), 0, 0)

	local tweenInfo = TweenInfo.new(
		0.5,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.Out,
		0,
		false
	)

	local tween = TweenService:Create(PrimaryPart, tweenInfo, {CFrame = targetRotation})
	
	tween:Play()

	local function checkRotation()
		local currentAngle = PrimaryPart.Rotation.X
		if currentAngle == 0 then
			tween:Cancel()
		end
	end

	while true do
		checkRotation()
		task.wait(0.1)
	end
	
end)

1 Like

In the First Script:

It seems like EventFired is not getting reset when the power and light are off. This might cause GenDialTwoOff to be fired continuously. To fix this, you should reset EventFired to false when power or light is off.

First script:

local Power = false
local LightEnabler = false
local EventFired = false

FuelInserted.Event:Connect(function()
    local IsPowerOn = false
    local AreLightsEnabled = false

    local function UpdateLights()

        if Power and LightEnabler then    
            
            EventFired = true
            
            if EventFired then
                GenDialTwoOn:Fire()
                EventFired = false
            end
            
            LightPart.BrickColor = BrickColor.new("Lime green")
            LightPart.Material = Enum.Material.Neon
            Light.Enabled = true
            Light.Color = Color3.fromRGB(0, 255, 0)

            for i, Light in pairs(CeilingLights) do
                Light.Bulb.BrickColor = BrickColor.new("Medium red")
                Light.Bulb.Material = Enum.Material.Neon

                Light.Bulb.Beam.Enabled = true
                Light.Bulb.SpotLight.Enabled = true
            end

        else
            
            if not EventFired then
                GenDialTwoOff:Fire()
                EventFired = true  -- Add this line
            end
            
            LightPart.BrickColor = BrickColor.new("Really red")
            LightPart.Material = Enum.Material.Neon
            Light.Enabled = true
            Light.Color = Color3.fromRGB(255, 0, 0)

            for i, Light in pairs(CeilingLights) do
                Light.Bulb.BrickColor = BrickColor.new("Buttermilk")
                Light.Bulb.Material = Enum.Material.Glass

                Light.Bulb.Beam.Enabled = false
                Light.Bulb.SpotLight.Enabled = false
            end
            
        end

    end
    
    UpdateLights()

end)

here is a snippet for what i changed in the first script

else
    if not EventFired then
        GenDialTwoOff:Fire()
        EventFired = true
    end

    LightPart.BrickColor = BrickColor.new("Really red")
    LightPart.Material = Enum.Material.Neon
    Light.Enabled = true
    Light.Color = Color3.fromRGB(255, 0, 0)

    for i, Light in pairs(CeilingLights) do

    end
end

In the Second Script:

You’re using PrimaryPart.Rotation.X to check the rotation, but Rotation is a property of Model , not Part . Use PrimaryPart.CFrame instead.

Second script:

local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")

local LightPart = script.Parent

local Generator = game.Workspace.Generator
local DialTwo = Generator.Dial2

local GenDialTwo = Generator.Dial2
local GenDialTwoOn = ServerStorage.GenDial2On
local GenDialTwoOff = ServerStorage.GenDial2Off

GenDialTwoOn.Event:Connect(function()
    local Arrow = DialTwo.Arrow
    local PrimaryPart = DialTwo.Arrow.PrimaryPart

    local currentRotation = PrimaryPart.CFrame
    local targetRotation = currentRotation * CFrame.Angles(math.rad(-90), 0, 0)

    local tweenInfo = TweenInfo.new(
        0.5,
        Enum.EasingStyle.Linear,
        Enum.EasingDirection.Out,
        0,
        false
    )

    local tween = TweenService:Create(PrimaryPart, tweenInfo, {CFrame = targetRotation})

    tween:Play()

    local function checkRotation()
        local currentAngle = PrimaryPart.CFrame:ToEulerAnglesXYZ()
        if currentAngle.x == math.rad(-90) then
            tween:Cancel()
        end
    end

    while true do
        checkRotation()
        task.wait(0.1)
    end
    
end)

GenDialTwoOff.Event:Connect(function()
    local Arrow = DialTwo.Arrow
    local PrimaryPart = DialTwo.Arrow.PrimaryPart

    local currentRotation = PrimaryPart.CFrame
    local targetRotation = currentRotation * CFrame.Angles(math.rad(90), 0, 0)

    local tweenInfo = TweenInfo.new(
        0.5,
        Enum.EasingStyle.Linear,
        Enum.EasingDirection.Out,
        0,
        false
    )

    local tween = TweenService:Create(PrimaryPart, tweenInfo, {CFrame = targetRotation})
    
    tween:Play()

    local function checkRotation()
        local currentAngle = PrimaryPart.CFrame:ToEulerAnglesXYZ()
        if currentAngle.x == 0 then
            tween:Cancel()
        end
    end

    while true do
        checkRotation()
        task.wait(0.1)
    end
    
end)

script 2 snippet

local function checkRotation()
    local currentAngle = PrimaryPart.CFrame:ToEulerAnglesXYZ()
    if currentAngle.x == math.rad(-90) then
        tween:Cancel()
    end
end
1 Like

Thanks for the suggestion!

As I mentioned earlier, the lever turns red when powered. However, the tween that’s intended to make it return to 0 occurs, causing it to fall below the dial model anticlockwise. This is because the default lighting of the lever is red. Earlier, I tried sending a bindable event when the color property of the LightPart changes from green to red on the lever, but it produced similar results.

I’m also getting an error in my event connections, which is causing Arrow to constantly spin clockwise still:

local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")

local LightPart = script.Parent

local Generator = game.Workspace.Generator
local DialTwo = Generator.Dial2

local GenDialTwo = Generator.Dial2
local GenDialTwoOn = ServerStorage.GenDial2On
local GenDialTwoOff = ServerStorage.GenDial2Off

GenDialTwoOn.Event:Connect(function()
	local Arrow = DialTwo.Arrow
	local PrimaryPart = DialTwo.Arrow.PrimaryPart

	local currentRotation = PrimaryPart.CFrame
	local targetRotation = currentRotation * CFrame.Angles(math.rad(-90), 0, 0)

	local tweenInfo = TweenInfo.new(
		0.5,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.Out,
		0,
		false
	)

	local tween = TweenService:Create(PrimaryPart, tweenInfo, {CFrame = targetRotation})

	tween:Play()

	local function checkRotation()
		local currentAngle = PrimaryPart.CFrame:ToEulerAnglesXYZ()
		if currentAngle.x == math.rad(-90) then -- attempt to index number with 'x'
			tween:Cancel()
		end
	end

	while true do
		checkRotation()
		task.wait(0.1)
	end
	
end)

Attached is a 30-second clip to a Google Drive mp4 file to demonstrate these problems in detail: