Is there a reason why the mouse cursor moves up when switching to a controller on PC? It happens in shiftlock mode, you can see the cursor moving up and down when I switch from mouse to controller.
Example:
Is there a reason why the mouse cursor moves up when switching to a controller on PC? It happens in shiftlock mode, you can see the cursor moving up and down when I switch from mouse to controller.
Example:
Could you share a link to a game you are having this issue in? It could also be a controller drift problem. Is it happening only in Roblox? A specific game maybe?
I don’t appear to be having this issue using my Xbox One controller and laptop. At least, I’m not noticing anything.
https://www.roblox.com/games/17191083560/Shonen-Storm
I’m testing a PS4 Controller in this game. Could you check it out with yours and on the shiftlock mode as well? To enter shift lock mode you use your L3/ press in your L3. Or your left joystick press in I believe for XBOX.
The game is private:
Sorry about that, can you try now? I also provided an example of what I mean on the first post.
When in Shiftlock Mode, yes I notice the issue. Are you using a custom or Roblox’s shift-lock system? I notice the icon is different.
I looked around and I think this person had the same issue, nobody had a fix: Make sure Gamepad mouse go center. I don’t think this is a Gamepad Virtual Cursor issue, since that doesn’t seem to be enabled.
So, I assume the issue is something internal inside Roblox’s CoreScripts. It could be Player → PlayerName → PlayerScripts → Player Module → Camera Module → MouseLockController.
--!nonstrict
--[[
MouseLockController - Replacement for ShiftLockController, manages use of mouse-locked mode
2018 Camera Update - AllYourBlox
--]]
--[[ Constants ]]--
local CommonUtils = script.Parent.Parent:WaitForChild("CommonUtils")
local FlagUtil = require(CommonUtils:WaitForChild("FlagUtil"))
local DEFAULT_MOUSE_LOCK_CURSOR = "rbxasset://textures/MouseLockedCursor.png"
local CONTEXT_ACTION_NAME = "MouseLockSwitchAction"
local MOUSELOCK_ACTION_PRIORITY = Enum.ContextActionPriority.Medium.Value
local CAMERA_OFFSET_DEFAULT = Vector3.new(1.75,0,0)
--[[ Services ]]--
local PlayersService = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local Settings = UserSettings() -- ignore warning
local GameSettings = Settings.GameSettings
--[[ Imports ]]
local CameraUtils = require(script.Parent:WaitForChild("CameraUtils"))
local FFlagUserFixCameraOffsetJitter = FlagUtil.getUserFlag("UserFixCameraOffsetJitter2")
--[[ The Module ]]--
local MouseLockController = {}
MouseLockController.__index = MouseLockController
function MouseLockController.new()
local self = setmetatable({}, MouseLockController)
self.isMouseLocked = false
self.savedMouseCursor = nil
self.boundKeys = {Enum.KeyCode.LeftShift, Enum.KeyCode.RightShift} -- defaults
self.mouseLockToggledEvent = Instance.new("BindableEvent")
local boundKeysObj = script:FindFirstChild("BoundKeys")
if (not boundKeysObj) or (not boundKeysObj:IsA("StringValue")) then
-- If object with correct name was found, but it's not a StringValue, destroy and replace
if boundKeysObj then
boundKeysObj:Destroy()
end
boundKeysObj = Instance.new("StringValue")
-- Luau FIXME: should be able to infer from assignment above that boundKeysObj is not nil
assert(boundKeysObj, "")
boundKeysObj.Name = "BoundKeys"
boundKeysObj.Value = "LeftShift,RightShift"
boundKeysObj.Parent = script
end
if boundKeysObj then
boundKeysObj.Changed:Connect(function(value)
self:OnBoundKeysObjectChanged(value)
end)
self:OnBoundKeysObjectChanged(boundKeysObj.Value) -- Initial setup call
end
-- Watch for changes to user's ControlMode and ComputerMovementMode settings and update the feature availability accordingly
GameSettings.Changed:Connect(function(property)
if property == "ControlMode" or property == "ComputerMovementMode" then
self:UpdateMouseLockAvailability()
end
end)
-- Watch for changes to DevEnableMouseLock and update the feature availability accordingly
PlayersService.LocalPlayer:GetPropertyChangedSignal("DevEnableMouseLock"):Connect(function()
self:UpdateMouseLockAvailability()
end)
-- Watch for changes to DevEnableMouseLock and update the feature availability accordingly
PlayersService.LocalPlayer:GetPropertyChangedSignal("DevComputerMovementMode"):Connect(function()
self:UpdateMouseLockAvailability()
end)
self:UpdateMouseLockAvailability()
return self
end
function MouseLockController:GetIsMouseLocked()
return self.isMouseLocked
end
function MouseLockController:GetBindableToggleEvent()
return self.mouseLockToggledEvent.Event
end
function MouseLockController:GetMouseLockOffset()
if FFlagUserFixCameraOffsetJitter then
return CAMERA_OFFSET_DEFAULT
else
local offsetValueObj: Vector3Value = script:FindFirstChild("CameraOffset") :: Vector3Value
if offsetValueObj and offsetValueObj:IsA("Vector3Value") then
return offsetValueObj.Value
else
-- If CameraOffset object was found but not correct type, destroy
if offsetValueObj then
offsetValueObj:Destroy()
end
offsetValueObj = Instance.new("Vector3Value")
assert(offsetValueObj, "")
offsetValueObj.Name = "CameraOffset"
offsetValueObj.Value = Vector3.new(1.75,0,0) -- Legacy Default Value
offsetValueObj.Parent = script
end
if offsetValueObj and offsetValueObj.Value then
return offsetValueObj.Value
end
return Vector3.new(1.75,0,0)
end
end
function MouseLockController:UpdateMouseLockAvailability()
local devAllowsMouseLock = PlayersService.LocalPlayer.DevEnableMouseLock
local devMovementModeIsScriptable = PlayersService.LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.Scriptable
local userHasMouseLockModeEnabled = GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch
local userHasClickToMoveEnabled = GameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove
local MouseLockAvailable = devAllowsMouseLock and userHasMouseLockModeEnabled and not userHasClickToMoveEnabled and not devMovementModeIsScriptable
if MouseLockAvailable~=self.enabled then
self:EnableMouseLock(MouseLockAvailable)
end
end
function MouseLockController:OnBoundKeysObjectChanged(newValue: string)
self.boundKeys = {} -- Overriding defaults, note: possibly with nothing at all if boundKeysObj.Value is "" or contains invalid values
for token in string.gmatch(newValue,"[^%s,]+") do
for _, keyEnum in pairs(Enum.KeyCode:GetEnumItems()) do
if token == keyEnum.Name then
self.boundKeys[#self.boundKeys+1] = keyEnum :: Enum.KeyCode
break
end
end
end
self:UnbindContextActions()
self:BindContextActions()
end
--[[ Local Functions ]]--
function MouseLockController:OnMouseLockToggled()
self.isMouseLocked = not self.isMouseLocked
if self.isMouseLocked then
local cursorImageValueObj: StringValue? = script:FindFirstChild("CursorImage") :: StringValue?
if cursorImageValueObj and cursorImageValueObj:IsA("StringValue") and cursorImageValueObj.Value then
CameraUtils.setMouseIconOverride(cursorImageValueObj.Value)
else
if cursorImageValueObj then
cursorImageValueObj:Destroy()
end
cursorImageValueObj = Instance.new("StringValue")
assert(cursorImageValueObj, "")
cursorImageValueObj.Name = "CursorImage"
cursorImageValueObj.Value = DEFAULT_MOUSE_LOCK_CURSOR
cursorImageValueObj.Parent = script
CameraUtils.setMouseIconOverride(DEFAULT_MOUSE_LOCK_CURSOR)
end
else
CameraUtils.restoreMouseIcon()
end
self.mouseLockToggledEvent:Fire()
end
function MouseLockController:DoMouseLockSwitch(name, state, input)
if state == Enum.UserInputState.Begin then
self:OnMouseLockToggled()
return Enum.ContextActionResult.Sink
end
return Enum.ContextActionResult.Pass
end
function MouseLockController:BindContextActions()
ContextActionService:BindActionAtPriority(CONTEXT_ACTION_NAME, function(name, state, input)
return self:DoMouseLockSwitch(name, state, input)
end, false, MOUSELOCK_ACTION_PRIORITY, unpack(self.boundKeys))
end
function MouseLockController:UnbindContextActions()
ContextActionService:UnbindAction(CONTEXT_ACTION_NAME)
end
function MouseLockController:IsMouseLocked(): boolean
return self.enabled and self.isMouseLocked
end
function MouseLockController:EnableMouseLock(enable: boolean)
if enable ~= self.enabled then
self.enabled = enable
if self.enabled then
-- Enabling the mode
self:BindContextActions()
else
-- Disabling
-- Restore mouse cursor
CameraUtils.restoreMouseIcon()
self:UnbindContextActions()
-- If the mode is disabled while being used, fire the event to toggle it off
if self.isMouseLocked then
self.mouseLockToggledEvent:Fire()
end
self.isMouseLocked = false
end
end
end
return MouseLockController
Edit: more specifically, it could be the MouseLockController:GetMouseLockOffset()
and maybe including the MouseLockController:OnMouseLockToggled()
functions.
Using ROBLOX’s built in shift lock system. And will definitely take a look into those scripts. Thank you for the help :). After messing around with it if I can solve it i’ll select this as the solution.
I removed PlayerModule and made my own code for input output, it’s still offsetting the cursor and changing its appearance when switching to gamepad. There needs to be a setting to adjust this, baddd
Yes but I am try make script but problem it Roblox the cursor mouse is ~= cursor Xbox but it have select buttons but I think with button it can switch from camera players to movement to cursor control like click right mouse and mouse mouse left change to mouse interaction ui like :
local UserInputService = game:GetService(“UserInputService”)
local RunService = game:GetService(“RunService”)
local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
– Cursor Settings
local cursorSpeed = 5 – Adjust this speed to control cursor responsiveness
local cursor = nil – Variable to store the cursor ImageLabel
local isCursorMode = false – Track if we’re in cursor mode
– Initialize the cursor
local function initializeCursor()
local gui = player:WaitForChild(“PlayerGui”)
cursor = gui:WaitForChild(“CursorImage”)
cursor.Visible = false – Start with cursor hidden
cursor.Position = UDim2.new(0.5, 0, 0.5, 0) – Center of screen
end
– Toggle function to switch between camera and cursor control
local function toggleCursorMode()
isCursorMode = not isCursorMode
cursor.Visible = isCursorMode
if isCursorMode then
camera.CameraType = Enum.CameraType.Scriptable -- Lock the camera in place
else
camera.CameraType = Enum.CameraType.Custom -- Restore normal camera control
end
end
– Update cursor position based on thumbstick input
local function updateCursorPosition(deltaX, deltaY)
– Scale the thumbstick input to move the cursor
local newPosX = cursor.Position.X.Scale + (deltaX * cursorSpeed / 100)
local newPosY = cursor.Position.Y.Scale - (deltaY * cursorSpeed / 100)
-- Clamp cursor position to the screen edges
newPosX = math.clamp(newPosX, 0, 1)
newPosY = math.clamp(newPosY, 0, 1)
cursor.Position = UDim2.new(newPosX, 0, newPosY, 0)
end
– Listen for L3 button press to toggle cursor mode
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.ButtonL3 then
toggleCursorMode()
end
end)
– Right thumbstick controls cursor position in cursor mode only
UserInputService.InputChanged:Connect(function(input)
if isCursorMode and input.UserInputType == Enum.UserInputType.Gamepad1 and input.KeyCode == Enum.KeyCode.Thumbstick2 then
local delta = input.Position – Position provides x and y for thumbstick movement
updateCursorPosition(delta.X, delta.Y)
end
end)
– Set up the cursor on player join
initializeCursor()