Right now my mouse leaves the window and stops my RTS script from working.
```
local uis = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local maxDist = 500
local camSpeed = 100 -- in studs/sec
local angle = math.rad(-75)
local minPerX, minPerZ = 1 / 3, 1 / 4
local x, z = 0, 0
local minXActivation = 1 / minPerX - 1
local minZActivation = 1 / minPerZ - 1
local userInput
uis.InputChanged:Connect(function(input)
userInput = input
end)
uis.InputEnded:Connect(function(input)
if input == userInput and userInput.UserInputType == Enum.UserInputType.MouseMovement then
local mousePos = uis:GetMouseLocation()
local viewport = camera.ViewportSize
if mousePos.X < 0 or mousePos.X > viewport.X or mousePos.Y < 0 or mousePos.Y > viewport.Y then
uis:SetMouseLocation(viewport.X/2, viewport.Y/2)
end
end
end)
game:GetService("RunService").RenderStepped:Connect(function(dt)
camera.CameraType = Enum.CameraType.Scriptable
local viewport = camera.ViewportSize
local mousePos = uis:GetMouseLocation()
local viewX, viewZ = viewport.X * minPerX, viewport.Y * minPerZ
local perX = mousePos.X / viewX
if perX < 1 then
-- it is on the left side of the margin
perX = (1 - perX) * (camSpeed * dt)
x = math.clamp(x - perX, -maxDist, maxDist)
elseif perX > minXActivation then
-- right side
perX = (perX - minXActivation) * (camSpeed * dt)
x = math.clamp(x + perX, -maxDist, maxDist)
end
local perZ = mousePos.Y / viewZ
if perZ < 1 then
perZ = (1 - perZ) * (camSpeed * dt)
z = math.clamp(z - perZ, -maxDist, maxDist)
elseif perZ > minZActivation then
perZ = (perZ - minZActivation) * (camSpeed * dt)
z = math.clamp(z + perZ, -maxDist, maxDist)
end
local currentPos = CFrame.new(x, 50, z)
camera.CFrame = currentPos * CFrame.Angles(angle, 0, 0)
end)
```
:SetMouseLocation() is not a method you can call, only :GetMouseLocation()
There are several security reasons why moving the player’s mouse for them are not possible, including making players accidently click on purchase prompts and preventing them for accessing things out of the window.
If it breaks your scripts, GET the location, and see if it is outside of the viewport. If it is, then don’t run the function
I just need to lock the cursor to the game window. Like an RTS game where you pan your camera to the edge of the screen and the camera will pan. You can’t have the mouse leaving the window.
Is there any way to achieve this? To lock to the game window?
GetMouseLocation Vector2
This function returns a Vector2 representing the current screen location of the player’s Mouse in pixels relative to the top left corner. This does not account for the GUI inset.
If the location of the mouse pointer is offscreen or the players device does not have a mouse, the value returned will be undetermined instead of Vector2.
As UserInputService is client-side only, this function can only be used in a LocalScript.
According to the docs, if you use GetMouseLocation, and it returns nil, it is either out of the viewport, or the user does not have a mouse connected. Just check that the player is on a computer and it should be good. (ill find an article I had ages ago for finding the device)
I guess you can determine which way it was going prior to returning nil. Note that if the player moves their mouse REALLY fast (more than half the screen in 1 frame) then it may break. Also wouldn’t work for panning diagonally.
Code is completely untested, so if it errors, Good luck! (I can try to explain things that break if need be). (Hopefully the code hasn’t got a flaw in it)
local LastX, LastY = 0, 0
local ViewportSize = workspace.CurrentCamera.ViewportSize
workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
ViewportSize = game.Workspace.CurrentCamera.ViewportSize -- Incase they change the size
end
while true do -- Change to whichever looping thing you were using
local pos = UIS:GetMouseLocation()
if pos then
LastX = pos.X
LastY = pos.Y
else
local X = math.round(LastX/ViewportSize.X) -- for finding which border it is closest to
local Y = math.round(LastY/ViewportSize.Y) -- 0,0 is top left, 1,1 is bottom right
local RatioX = LastX/ViewportSize.X
local RatioY = LastY/ViewportSize.Y
if RatioX > 0.5 then RatioX = 1-RatioX
if RatioY > 0.5 then RatioY = 1-RatioY
if RatioX < RatioY then
if X == 1 then
print("Right")
else
print("Left")
end
else
if Y == 1 then
print("Down")
else
print("Up")
end
end
task.wait()
end
end
In answer to your original question: No, you can not prevent the mouse from leaving.
Your goal of panning is still possible. I did some testing and found a better way to pan it than using the method i put above.
The documentation is misleading - :GetMouseLocation DOES return a value if it is outside of the viewport, which is basically the last known location. Using that you can calculate which border direction it is and hence which way to pan
Does it just return last known mouse location? Cause what if someone pans outside at the top, moves mouse around outside the viewport and comes back inside the bottom for example.
Last known location that was inside the viewport, so they could have their mouse position jump from 0,0 to whatever the bottom right position is by moving their mouse around the outside
set the uis.MouseBehavior to lock the mouse to the center
but it the mouse is too fast, it can’t catch it
local uis = game:GetService("UserInputService")
local plrs = game:GetService("Players")
local player = plrs.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local maxDist = 500
local camSpeed = 100 -- in studs/sec
local angle = math.rad(-75)
local minPerX, minPerZ = 1 / 3, 1 / 4
local x, z = 0, 0
local minXActivation = 1 / minPerX - 1
local minZActivation = 1 / minPerZ - 1
local maxMouseBound = 25
uis.InputChanged:Connect(function(input)
if uis.MouseBehavior == Enum.MouseBehavior.LockCenter then
return
end
if input.UserInputType == Enum.UserInputType.MouseMovement then
local mousePos = Vector2.new(mouse.X, mouse.Y)
local viewport = camera.ViewportSize
if mousePos.X <= maxMouseBound or mousePos.X >= viewport.X - maxMouseBound or mousePos.Y <= maxMouseBound or mousePos.Y >= viewport.Y - maxMouseBound then
print("tried to go out")
while game:GetService("RunService").RenderStepped:Wait() and (uis:GetMouseLocation() - viewport / 2).Magnitude > 10 do
uis.MouseBehavior = Enum.MouseBehavior.LockCenter
-- repeat until the mouse in in the center because bug
end
uis.MouseBehavior = Enum.MouseBehavior.Default
end
end
end)
game:GetService("RunService").RenderStepped:Connect(function(dt)
camera.CameraType = Enum.CameraType.Scriptable
local viewport = camera.ViewportSize
local mousePos = uis:GetMouseLocation()
local viewX, viewZ = viewport.X * minPerX, viewport.Y * minPerZ
local perX = mousePos.X / viewX
if perX < 1 then
-- it is on the left side of the margin
perX = (1 - perX) * (camSpeed * dt)
x = math.clamp(x - perX, -maxDist, maxDist)
elseif perX > minXActivation then
-- right side
perX = (perX - minXActivation) * (camSpeed * dt)
x = math.clamp(x + perX, -maxDist, maxDist)
end
local perZ = mousePos.Y / viewZ
if perZ < 1 then
perZ = (1 - perZ) * (camSpeed * dt)
z = math.clamp(z - perZ, -maxDist, maxDist)
elseif perZ > minZActivation then
perZ = (perZ - minZActivation) * (camSpeed * dt)
z = math.clamp(z + perZ, -maxDist, maxDist)
end
local currentPos = CFrame.new(x, 50, z)
camera.CFrame = currentPos * CFrame.Angles(angle, 0, 0)
end)
local mouse = game.Players.LocalPlayer:GetMouse()
game:GetService("UserInputService").InputBegan:Connect(function(inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
local x = mouse.X
local y = mouse.Y
local size = game.Workspace.CurrentCamera.ViewportSize
if x <= 0 or x >= size.X then
mouse.X = x < 0 and 0 or size.X
end
if y <= 0 or y >= size.Y then
mouse.Y = y < 0 and 0 or size.Y
end
end
end)
if the cursor is detected by the userinputservice to be outside of the windows coordinates it sets the mouse pos to the edge of the screen effectively keeping it inside of the game window
I guess a way is to constantly check if the mouse is close enough to the edge of thr screen then Center lock it and unlock it, although this would obviously cause your mouse to get locked for a split second