Rotating Character in the air using W A S D

I’m trying to figure out how to rotate the player if they’re in the air and based off what key they are pressing. I also need it to keep the player in the same rotation regardless of letting go of the key. An example would be pressing “W” that would rotate you forward in the air.

In my code, it detects when a player is in the air or has jumped. I figured out how to detect which key the player is pressing and if the player’s in the air, but I can’t figure out how to rotate the player.
I used many things like CFrame.Angles, HumanoidRootPart.Rotation, Char:PivotTo(), but they would all have game breaking flaws.

Here is the code:


local function checkInput(input, realInput, inputState)
	if input.KeyCode == realInput then
		if inputState == "Begin" then
			local ableToPass = checkTable(newInputTable, realInput)

			if not ableToPass then return end
			
			task.spawn(function()
				while hasJumped and isPressing do
					wait()
					if #newInputTable <= 1 then
						-- Activates when more than one key is pressed
					else
						for i, input in newInputTable do
							-- Activates when one key is pressed
						end
					end
				end
			end)
			
		elseif inputState == "Ended" then
			if input.KeyCode ~= realInput then return end
			for i, v in newInputTable do
				wait()
				if v == realInput then
					table.remove(newInputTable, i)
				end
			end
		end
	end
end

1 Like

If I understand your issue right, you can accomplish this using Roblox’s new physics character controllers. The AirController instance has a property called MaintainAngularMomentum which preserves the angular momentum of the character when the player hits a direction in the air. So instead of their angular momentum stopping when the player releases a direction, the character will keep spinning until they hit the ground.

Shameless plug (wink wink): I made a tutorial to set this up if you want to check it out here :wink: How to Actually Use Roblox's Physics Character Controllers

Update: I just realized this might not solve your issue and I am an idiot.

If you can, what are the game-breaking bugs that stop you from using the usual angular stuff like CFrame.Angles or HRP.Rotation?

I just researched your issue you can use a combination of CFrame and BodyGyro to control the player’s orientation.

Try this code:

local function checkInput(input, realInput, inputState)
    if input.KeyCode == realInput then
        if inputState == "Begin" then
            local ableToPass = checkTable(newInputTable, realInput)

            if not ableToPass then return end

            task.spawn(function()
                while hasJumped and isPressing do
                    wait()
                    if #newInputTable <= 1 then
                        -- Activates when more than one key is pressed
                    else
                        for i, input in newInputTable do
                            -- Activates when one key is pressed
                            if input.KeyCode == Enum.KeyCode.W then
                                -- Rotate forward
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(math.rad(-5), 0, 0)
                            elseif input.KeyCode == Enum.KeyCode.S then
                                -- Rotate backward
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(math.rad(5), 0, 0)
                            elseif input.KeyCode == Enum.KeyCode.A then
                                -- Rotate left
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(-5), 0)
                            elseif input.KeyCode == Enum.KeyCode.D then
                                -- Rotate right
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(5), 0)
                            end
                        end
                    end
                end
            end)

        elseif inputState == "Ended" then
            if input.KeyCode ~= realInput then return end
            for i, v in newInputTable do
                wait()
                if v == realInput then
                    table.remove(newInputTable, i)
                end
            end
        end
    end
end

CFrame.Angles does kind of work but it doesn’t keep the rotation updated. HRP.Rotation rotates the player but messes up the controls so if I rotate Y by 180, then it would make the player face backwards but it would seem as your character is facing towards the camera as you’re walking forward. Sorry for the explanation if its complicated since I’m not good at explaining.

I figured out how to implement your code but the player goes back to it’s original rotation immediately

Here is an updated version it was because the script doesn’t maintain the new rotation state so it immediately locked rotation this should fix it so it doesn’t reset the “CFrame”.

Try this new code:

local function checkInput(input, realInput, inputState)
    if input.KeyCode == realInput then
        if inputState == "Begin" then
            local ableToPass = checkTable(newInputTable, realInput)

            if not ableToPass then return end

            task.spawn(function()
                while hasJumped and isPressing do
                    wait()
                    if #newInputTable <= 1 then
                        -- Activates when more than one key is pressed
                    else
                        for i, input in ipairs(newInputTable) do
                            -- Activates when one key is pressed
                            if input.KeyCode == Enum.KeyCode.W then
                                -- Rotate forward
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(math.rad(-5), 0, 0)
                            elseif input.KeyCode == Enum.KeyCode.S then
                                -- Rotate backward
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(math.rad(5), 0, 0)
                            elseif input.KeyCode == Enum.KeyCode.A then
                                -- Rotate left
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(-5), 0)
                            elseif input.KeyCode == Enum.KeyCode.D then
                                -- Rotate right
                                HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.Angles(0, math.rad(5), 0)
                            end
                        end
                    end
                end
            end)

        elseif inputState == "Ended" then
            if input.KeyCode ~= realInput then return end
            for i, v in ipairs(newInputTable) do
                if v.KeyCode == realInput then
                    table.remove(newInputTable, i)
                    break
                end
            end
        end
    end
end

Ok it works a bit but it flings you up and I can’t find out how to make it keep rotating in the direction. I modified the function because I had the if statements mixed up.


local function checkInput(input, realInput, inputState)
	if input.KeyCode == realInput then
		if inputState == "Begin" then
			local ableToPass = checkTable(newInputTable, input)

			if not ableToPass then return end
				
			task.spawn(function()
				while hasJumped and isPressing do
					
					wait()
					if #newInputTable <= 1 then
						if input.KeyCode == Enum.KeyCode.W then
							-- Rotate forward
							hRP.CFrame = hRP.CFrame * CFrame.Angles(math.rad(-50), 0, 0)
						elseif input.KeyCode == Enum.KeyCode.S then
							-- Rotate backward
							hRP.CFrame = hRP.CFrame * CFrame.Angles(math.rad(50), 0, 0)
						elseif input.KeyCode == Enum.KeyCode.A then
							-- Rotate left
							hRP.CFrame = hRP.CFrame * CFrame.Angles(0, math.rad(-50), 0)
						elseif input.KeyCode == Enum.KeyCode.D then
							-- Rotate right
							hRP.CFrame = hRP.CFrame * CFrame.Angles(0, math.rad(50), 0)
						end
						-- Activates when one key is pressed
					else
						for i, input in ipairs(newInputTable) do
							-- Activates when more than one key is pressed
							if input.KeyCode == Enum.KeyCode.W then
								-- Rotate forward
								hRP.CFrame = hRP.CFrame * CFrame.Angles(math.rad(-50), 0, 0)
							elseif input.KeyCode == Enum.KeyCode.S then
								-- Rotate backward
								hRP.CFrame = hRP.CFrame * CFrame.Angles(math.rad(50), 0, 0)
							elseif input.KeyCode == Enum.KeyCode.A then
								-- Rotate left
								hRP.CFrame = hRP.CFrame * CFrame.Angles(0, math.rad(-50), 0)
							elseif input.KeyCode == Enum.KeyCode.D then
								-- Rotate right
								hRP.CFrame = hRP.CFrame * CFrame.Angles(0, math.rad(50), 0)
							end
						end
					end
				end
			end)

		elseif inputState == "Ended" then
			if input.KeyCode ~= realInput then return end
			for i, v in ipairs(newInputTable) do
				if v.KeyCode == realInput then
					table.remove(newInputTable, i)
					break
				end
			end
		end
	end
end

I found out the solution! Thanks for everyone who helped me.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.