Hello there!
I am too working on my own platformer and this is definitely a concept I struggled with. I found that disabling the player’s controls of the character and scripting them was the best solution.
You can set “D” to move the player to the right and “A” to the left.
You can also set the character’s humanoid root part’s CFrame to turn 180 degree when they start walking either direction.
Check out my progress at Platformer (2) - Roblox and let me know what I can help with! Not everyone is aiming for the same feeling, but I’m confident I can help.
Here’s a snipit of my code if it helps, I’m happy to offer the whole code, but most of the rest of it is just personalizing it to what I’m trying to accomplish.
local player = game:GetService("Players").LocalPlayer
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local playerModule = require(game.Players.LocalPlayer.PlayerScripts:WaitForChild("PlayerModule"))
local controls = playerModule:GetControls()
local mouse = player:GetMouse()
local char = nil
local humanoid = nil
local rootPart = nil
local camPart = nil
local pressingA = nil
local pressingD = nil
local torso = nil
local neck = nil
local head = nil
local lastFacingDirection = "Left"
local facingDirection = nil
local lastDirection = nil
local camera = workspace.CurrentCamera
local viewX = camera.ViewportSize.X
local zoom = 50
--local maxJumps = 2
local row = 0
local jumping = false
local holdingSpace = false
local zooming = false
controls:Disable()
uis.InputBegan:Connect(function(key)
if char then
if key.KeyCode == Enum.KeyCode.D then
pressingD = true
humanoid:Move(Vector3.new(1,0,0), false)
lastDirection = "d"
elseif key.KeyCode == Enum.KeyCode.A then
pressingA = true
humanoid:Move(Vector3.new(-1,0,0), false)
lastDirection = "a"
elseif key.KeyCode == Enum.KeyCode.Space then
holdingSpace = true
elseif key.KeyCode == Enum.KeyCode.LeftShift then
humanoid:ChangeState(Enum.HumanoidStateType.Running)
end
end
end)
uis.InputEnded:Connect(function(key)
if char then
if key.KeyCode == Enum.KeyCode.D and not pressingA then
humanoid:Move(Vector3.new(0,0,0), false)
pressingD = false
elseif key.KeyCode == Enum.KeyCode.A and not pressingD then
humanoid:Move(Vector3.new(0,0,0), false)
pressingA = false
elseif key.KeyCode == Enum.KeyCode.D and pressingA then
humanoid:Move(Vector3.new(-1,0,0), false)
lastDirection = "a"
pressingD = false
elseif key.KeyCode == Enum.KeyCode.A and pressingD then
humanoid:Move(Vector3.new(1,0,0), false)
lastDirection = "d"
pressingA = false
elseif key.KeyCode == Enum.KeyCode.Space then
holdingSpace = false
end
end
end)
mouse.WheelForward:Connect(function()
if not zooming then
zooming = true
for i = 1, 20 do
if zoom > 20 then
zoom = zoom - .1
end
end
zooming = false
end
end)
mouse.WheelBackward:Connect(function()
if not zooming then
zooming = true
for i = 1, 20 do
if zoom < 80 then
zoom = zoom + .1
end
end
zooming = false
end
end)
player.CharacterAdded:Connect(function(newChar)
camera.CameraType = Enum.CameraType.Scriptable
char = newChar
humanoid = char:WaitForChild('Humanoid')
humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
humanoid.BreakJointsOnDeath = false
rootPart = char:WaitForChild('HumanoidRootPart')
head = char:WaitForChild('Head')
neck = head:WaitForChild('Neck')
torso = char:WaitForChild('UpperTorso')
rootPart.CFrame *= CFrame.Angles(0, math.rad(-90), 0)
rs.RenderStepped:Connect(function()
if humanoid:GetState() == Enum.HumanoidStateType.Running then
jumping = false
else
jumping = true
end
if not jumping and holdingSpace then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
lastFacingDirection = facingDirection
if mouse.X < viewX/2 then
facingDirection = "Left"
else
facingDirection = "Right"
end
if pressingA and facingDirection == "Left" then
humanoid.WalkSpeed = 16
elseif pressingD and facingDirection == "Right" then
humanoid.WalkSpeed = 16
elseif not jumping then humanoid.WalkSpeed = 16
end
if facingDirection == "Right" then
rootPart.CFrame = CFrame.new((rootPart.CFrame.p * Vector3.new(1,1,0)) + Vector3.new(0,0,row * 4), rootPart.CFrame.p + Vector3.new(50,0,0))
else
rootPart.CFrame = CFrame.new((rootPart.CFrame.p * Vector3.new(1,1,0)) + Vector3.new(0,0,row * 4), rootPart.CFrame.p + Vector3.new(-50,0,0))
end
camera.CFrame = CFrame.new(rootPart.CFrame.p + Vector3.new(0,0,zoom),rootPart.Position)
camera.Focus = rootPart.CFrame
end)
end)
EDIT: I’ve decided to include my entire code to avoid confusion. It might be a little messy but it works great. Please note that the player’s facing direction is determined by mouse placement, not movement direction. This code also controls the camera so be aware of that too.
BUG NOTE: In studio only; I find that the center of the screen is not correct, however in the actual game it works fine.