I’ve been working on a Minecraft Dungeons styled game for a while, and now I’m rewriting the roblox movement code from scratch in order to make the player move with the mouse instead of WASD. To achieve this I had to set the DevComputerMovementMode to Scriptable, but as a side-effect it also completely disabled the gamepad thumbstick movement, thus forcing me to remake it from scratch (Thanks Roblox!)
Minecraft Dungeons locks your camera to a 45° topdown view (example below), so in order to re-add the gamepad movement I’d have to rotate the gamepad’s thumbstick vector in order to match the current camera angle
The way I’m currently handling movement is by inserting a part that the character is constantly moving towards (example below, again), so instead of moving the character I’m moving the part since it simplifies a lot of things
I’m running this code every frame in order to rotate the thumbstick’s direction relative to the camera rotation, and then move the part according to the rotated thumbstick direction
local movePart = workspace:WaitForChild('MovePart') --The part the character is moving towards
local rotation = - player:GetAttribute('Rotation') --The camera's rotation (negative)
local partDistance = 10 --Distance between the MovePart and the Humanoid when moving
local abs = math.abs --Just making my life easier
local sin = math.sin
local cos = math.cos
function module.Move() --Called every frame if LastInputType == Enum.UserInputType.Gamepad1
for i,v in uis:GetGamepadState(Enum.UserInputType.Gamepad1) do --Gets all buttons currently pressed by the gamepad
if v.KeyCode ~= Enum.KeyCode.Thumbstick1 then continue end --Saves me some yucky nesting
--Raw thumbstick direction
local xPos = v.Position.X * partDistance
local yPos = - v.Position.Y * partDistance
--Deadzone stuff, feel free to ignore it
if abs(xPos) <= deadZone and abs(yPos) <= deadZone then
yPos = 0
xPos = 0
end
--The thumbstick direction rotated using the Rotation Matrix formula I got from wikipedia cuz I don't know linear algebra lol
local xRot = xPos * cos(rotation) - yPos * sin(rotation)
local yRot = xPos * sin(rotation) + yPos * cos(rotation)
gamepadDelta = Vector2.new(xRot, yRot) --Rotated thumbstick direction
end
movePart.Position = hrp.Position + Vector3.new(gamepadDelta.X, 0, gamepadDelta.Y) --Finally, moves the part
end
Although this code works well when the camera is rotated either 0 or 45 degrees, it breaks in every other angle for some reason (example below, I had DS4Windows open in the left so you can see that the movement does not match my thumbstick’s position most of the times), I’ve been scratching my head over this for the past day and I still can’t figure out why
I’ve seen a lot of different solutions to similar problems but none of them really work. I’m guessing that the problem comes when I rotate the thumbstick’s direction but I still can’t figure out what’s wrong
In case you’re wondering, this is the code for the camera, I’m pretty sure this works fine though.
local player = game:GetService('Players').LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild('Humanoid')
local hrp = char:WaitForChild('HumanoidRootPart')
local cam = workspace.CurrentCamera
cam.CameraType = Enum.CameraType.Scriptable
local camOffset = 22
local camHeight = 28
player:SetAttribute('Rotation', 45) --Dummy rotation angle
local heartbeat = runService.Heartbeat:Connect(function(dt)
if cam.CameraType ~= Enum.CameraType.Scriptable then return end
local camRotation = player:GetAttribute('Rotation')
local cframe = CFrame.new(hrp.Position) * CFrame.Angles(0, math.rad(camRotation), 0) * CFrame.new(0, camHeight, camOffset)
cam.CFrame = CFrame.lookAt(cframe.Position, hrp.Position)
end)
English isn’t my first language so let me know if I had any grammar mistakes lol