Userinput and Tweenservice issue [REPOST]

Recently, i’ve been creating tweens based on certian key inputs which are based on the Piano Key Order.

My issue encounters in the inputEnded function.

Explanation

  • While pressing lowercase notes if you press SHIFT and release it at the right moment, this issue will encounter. Making the upper key (shifted key), constantly be the incorrect color. Same goes for opposite and for CTRL

Issues

  • The function that should end and revert the colors back is not doing it right.
  • There are no error messages whatsoever.
  • Tried many methods which include: Remote Event (which handles the tween), Decreasing tween animation time (0), Re-doing the code, etc.

Code Snippet

  • InputEnded
if input.UserInputType == Enum.UserInputType.Keyboard and input.UserInputState == Enum.UserInputState.End then
	if input.KeyCode == Enum.KeyCode.LeftControl then 
		EvaluateKeyOrderCTRLPress = false
		return
	end
		if input.KeyCode == Enum.KeyCode.LeftShift then 
		EvaluateKeyOrderSHIFTPress = false 
		return
	end

--[[
 In this line theres a code that is supposed to restrict certian keybinds.
]]
	task.wait()
	if letter then
		EvaluateHitPress(KeyOrderify(letter), false) -- pass function.
	end
end
  • KeyOrderify
function KeyOrderify(letter)
-- Full 88 keys btw
	if EvaluateKeyOrderCTRLPress then
		if letter == "1" then
			return "-14"
		elseif letter == "2" then
			return "-13"
		elseif letter == "3" then
			return "-2"
		elseif letter == "r" then
			return "-1"
		elseif letter == "t" then
			return "0"
-- etc...
     elseif EvaluateKeyOrderSHIFTPress then
		if letter == "1" then
			return "2"
		elseif letter == "2" then
			return "4"
		elseif letter == "4" then
			return "7"
		elseif letter == "5" then
			return "9"
		elseif letter == "6" then
			return "11"
-- etc...

	-- White note while also shifting. this is important so it doesn't return nil on these keybinds
		if letter == "3" then
			return "5"
		elseif letter == "7" then
			return "12"
		elseif letter == "0" then
-- etc...


		-- White notes
	else
		if letter == "1" then
			return "1"
		elseif letter == "2" then
			return "3"
		elseif letter == "3" then

		else
			return nil
		end
    end
end

Tween Function

function EvaluateHitPress(keylead, phase)
	local keyloc  -- location to the keys
	local fadeTween
	if phase == true then -- start
		if keyloc:FindFirstChild("Shift") then
			fadeTween = TWEEN:Create(keyloc, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), { BackgroundColor3 = Color3.fromRGB(100, 100, 100) })
			fadeTween:Play()
		else
			fadeTween = TWEEN:Create(keyloc, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), { BackgroundColor3 = Color3.fromRGB(197, 197, 197) })
			fadeTween:Play()
		end
	else
		if keyloc:FindFirstChild("Shift") then -- find if there exists a shift value inside
			TWEEN:Create(keyloc, TweenInfo.new(0, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), { BackgroundColor3 = Color3.fromRGB(6, 6, 6) }):Play() 
		else
			TWEEN:Create(keyloc, TweenInfo.new(0, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0), { BackgroundColor3 = Color3.fromRGB(255, 255, 255) }):Play()
		end
	end
end

Addition

  • One script handles the whole functionality

Video

Let me know what is the issue here, would appreciate it.

could have just bumped instead of reposting, oh well.

this is an issue of execution, and incorrect implementation of debounces, ontop of tween conflicts. your code doesn’t have a consistent way of veryfing that the logic regarding the previous task (previous input began / finished) has finished, and the tweens for the new inputs could be conflicting with the old.

the solution isn’t easy, unless you are willing to learn to use something like the Promise library, which has the purpose of allowing the chaining, execution, and cancellation of tasks (threads).
(because each input began / end is its own separate thread and cause conflict between them)

1 Like

on a side note, i think it would be better for you if you used a dictionary for this instead:

dictKeyOrder = {
	["1"] =  "-14",
	["2"] = "-13",
	["r"] = "-1",
}

function KeyOrderify(letter)
	return dictKeyOrder[letter]	
	--will return nil anyways if doesn't exist
end
1 Like

I’ve implemented debounces which may be “correct” but this issue still persists.

local debounce = function(func, delay)
	local timerId = nil
	return function(arg)
		if timerId then
			timerId:Disconnect()
		end
		timerId = game:GetService("RunService").Heartbeat:Connect(function()
			func(arg)
			timerId:Disconnect()
		end)
	end
end

Alongside attempted to make sure tweens dont conflict which still didnt fix the issue.

If i use color without tweening it works as intended.

Alongside trying “promise” library, my issue still persists and no errors in the output whatsoever.

whereas even seperating scripts into two handling the input began and the other input ended still wont fix

I’m either using promise library incorrectly or the tween is just not working right even while stopping conflicts

Alongside this side note, this what you just sent is not needed, due to the fact my piano order is for 88 keys [buttons] and if i put it like so it would bug out and press in the unneccesary locations. However it could be useful in some way.
if used like:

local KeyOrder = {
   CTRL = {},
   SHIFT = {},
   QWERTY = {},
}

IDEA

My only conclusion that could help this is if i used an library for tweening or used basic color looping to visualize tweening

I’ve analyzed the issue and ultimately fixed it, the issue is always unexpected.

Overall the issue was releated to my “if” statements when disabling shift and ctrls.

I may also use promise library for some cases like this. Eitheraway thanks