UserInputService

顯示已棄用項目

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

無法建立
服務
未複製

UserInputService 是用於在使用者裝置上檢測和捕捉可用不同類型輸入的服務。

此服務的主要目的是讓體驗與多種可用輸入形式合作,例如遊戲手柄、觸摸螢幕和鍵盤。它允許 LocalScript 執行不同的操作,根據裝置進行,並最終為最終用戶提供最佳體驗。

這項服務的一些用途包括當使用者與 GUI、工具和其他遊戲實例互動時偵測使用者輸入。為了偵測使用者輸入,服務必須尋找服務事件。例如,服務可以偵測到使用 UserInputService.TouchStarted 觸摸手機螢幕的用戶、使用 UserInputService.GamepadConnected 連接遊戲控制器(例如 Xbox 控制器)到他們的裝置等事件。

因為此服務只能由客戶端使用,因此只能在 LocalScriptModuleScriptLocalScript 需要時才能運作。因為 UserInputService 只是客戶端,遊戲中的用戶只能偵測自己的輸入 - 而不是他人的輸入。

請參閱ContextActionService,一種允許您將函數綁定到多個使用者輸入的服務。

範例程式碼

The following example demonstrates one of many usage examples of handling a UserInputService event.

UserInputService

-- We must get the UserInputService before we can use it
local UserInputService = game:GetService("UserInputService")
-- A sample function providing one usage of InputBegan
local function onInputBegan(input, _gameProcessed)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
print("The left mouse button has been pressed!")
end
end
UserInputService.InputBegan:Connect(onInputBegan)

概要

屬性

方法

活動

屬性

AccelerometerEnabled

唯讀
未複製
平行讀取

此屬性描述用戶的裝置是否有加速器

加速度計是一種在大多數移動裝置中找到的零件,用於測量加速(速度變化)。

例如,以下代碼片段顯示如何檢查用戶的裝置是否有加速器。


local UserInputService = game:GetService("UserInputService")
local accelerometerEnabled = UserInputService.AccelerometerEnabled
if accelerometerEnabled then
print("Accelerometer enabled!")
else
print("Accelerometer not enabled!")
end

如果裝置具有啟用加速度計,您可以使用 UserInputService:GetDeviceAcceleration() 函數或跟蹤當裝置的加速度變更時使用 UserInputService.DeviceAccelerationChanged 事件來獲得其當前加速度。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

範例程式碼

This code adds a force on a part so that it falls in the direction of actual gravity relative to the user's device.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have an accelerometer.

Move a Ball using the Accelerometer

local Workspace = game:GetService("Workspace")
local UserInputService = game:GetService("UserInputService")
local ball = script.Parent:WaitForChild("Ball")
local mass = ball:GetMass()
local gravityForce = ball:WaitForChild("GravityForce")
local function moveBall(gravity)
gravityForce.Force = gravity.Position * Workspace.Gravity * mass
end
if UserInputService.AccelerometerEnabled then
UserInputService.DeviceGravityChanged:Connect(moveBall)
end

This example controls the player's Camera so that it matches the player's device orientation via using the device's gyroscope and accelerometer.

The camera is positioned inside the player's head, and updated to move with the player and the user's device rotation, by executing the following line every RenderStep:


camera.CFrame = CFrame.new(head.Position - Vector3.new(0,8,10)) *
currentRotation

The code sample relies on the device's gyroscope to determine when the player rotates their device. It does so by connecting to the DeviceRotationChanged() event.

The code sample relies on the device's accelerometer to retrieve the gravity vector used to determine the device's orientation (whether it is flipped upside down or not). To determine whether the device's orientation is upside down, the code sample uses the DeviceGravityChanged() event.

Since the script places the camera inside the head to create a first-person camera, the limbs are made transparent by the HideCharacter() function so that the player does not see their Player.Character when rotating the camera.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have a gyroscope and an accelerometer.

Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

GamepadEnabled

唯讀
未複製
平行讀取

此屬性描述使用者使用的裝置是否擁有可用的遊戲控制器。如果遊戲控制器可用,您可以使用 UserInputService:GetConnectedGamepads() 來恢復連接的遊戲控制器列表。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

也見:

範例程式碼

If you are using the default controls, you do not need to worry about this. If you're creating a custom script for handling gamepad controls, this is a good template for retrieving which gamepad enum you should use as the primary gamepad controller.

How to Set the Active Gamepad for Input

local UserInputService = game:GetService("UserInputService")
local function getActiveGamepad()
local activeGamepad = nil
local connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _, gamepad in connectedGamepads do
if activeGamepad == nil or gamepad.Value < activeGamepad.Value then
activeGamepad = gamepad
end
end
end
if activeGamepad == nil then -- Nothing is connected; set up for "Gamepad1"
activeGamepad = Enum.UserInputType.Gamepad1
end
return activeGamepad
end
if UserInputService.GamepadEnabled then
local activeGamepad = getActiveGamepad()
print(activeGamepad)
end

GyroscopeEnabled

唯讀
未複製
平行讀取

此屬性描述用戶的裝置是否擁有陀螺儀。

陀螺儀是一種在大多數移動裝置中找到的組件,可偵測方向和旋轉速度。

如果使用者的裝置具有陀螺儀,您可以使用 UserInputService:GetDeviceRotation() 函數和 UserInputService.DeviceRotationChanged 事件將其融入到您的遊戲中。


local UserInputService = game:GetService("UserInputService")
local gyroIsEnabled = UserInputService.GyroscopeEnabled
if gyroIsEnabled then
print("Gyroscope is enabled!")
else
print("Gyroscope is not enabled!")
end

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

範例程式碼

This example controls the player's Camera so that it matches the player's device orientation via using the device's gyroscope and accelerometer.

The camera is positioned inside the player's head, and updated to move with the player and the user's device rotation, by executing the following line every RenderStep:


camera.CFrame = CFrame.new(head.Position - Vector3.new(0,8,10)) *
currentRotation

The code sample relies on the device's gyroscope to determine when the player rotates their device. It does so by connecting to the DeviceRotationChanged() event.

The code sample relies on the device's accelerometer to retrieve the gravity vector used to determine the device's orientation (whether it is flipped upside down or not). To determine whether the device's orientation is upside down, the code sample uses the DeviceGravityChanged() event.

Since the script places the camera inside the head to create a first-person camera, the limbs are made transparent by the HideCharacter() function so that the player does not see their Player.Character when rotating the camera.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have a gyroscope and an accelerometer.

Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

KeyboardEnabled

唯讀
未複製
平行讀取

此屬性描述用戶的裝置是否有可用的鍵盤。當使用者的裝置具有可用鍵盤時,此屬性為 true ;當它沒有時,為 false

它可以用來確定使用者是否擁有可用的鍵盤 - 這可能很重要,如果您想檢查是否可以使用 UserInputService:IsKeyDown()UserInputService:GetKeysPressed() 來檢查鍵盤輸入。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

範例程式碼

This example prints "The user's device has an available keyboard!" if KeyboardEnabled is true and "The user's device does not have an available keyboard!" if KeyboardEnabled is false.

Check if Keyboard is Enabled

local UserInputService = game:GetService("UserInputService")
if UserInputService.KeyboardEnabled then
print("The user's device has an available keyboard!")
else
print("The user's device does not have an available keyboard!")
end

MouseBehavior

平行讀取

這個屬性設置了使用者的鼠標如何根據 Enum.MouseBehavior 枚列行為。它可以設置為三個值:

此屬性的值不會影響事件追蹤鼠標移動的靈敏度。例如, GetMouseDelta 返回相同的 Vector2 畫面位置,無論滑鼠是否鎖定或能夠在使用者的畫面上自由移動。因結果,控制相機的預設腳本不受此屬性影響。

如果啟用了 GuiButtonModalGuiButton.Visible ,這個屬性將被覆蓋,除非玩家的右鍵按鈕處於下降狀態。

請注意,如果滑鼠被鎖定,UserInputService.InputChanged將在玩家移動滑鼠時仍然發射,並會傳送滑鼠嘗試移動的Delta。此外,如果玩家被踢出遊戲,滑鼠將被強行解鎖。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

範例程式碼

This example creates a binoculars script that decreases the player's FieldOfView() and MouseDeltaSensitivity() when a player with a MouseEnabled() left mouse clicks. The script also points the player's Camera towards the Vector3 world position of the mouse click.

When the player left mouse clicks again, the player's camera reverts back to the a custom Enum.CameraType with the same field of view and CFrame() as before the player zoomed in with the script.

While the player uses the binoculars, the script locks the player's mouse to the center of the screen by setting the player's MouseBehavior() to LockCenter. The player's camera moves when the player moves their mouse according to the InputObject.Delta property passed by InputChanged() indicating the mouse's Vector2 change in screen position.

In order for this example to work as expected, it should be placed in a LocalScript.

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

MouseDeltaSensitivity

未複製
平行讀取

此屬性決定了使用者的 Mouse 敏感度。

靈敏度決定物理滑鼠的移動轉換到遊戲中滑鼠的移動程度。這可以用來調整如何敏感事件追蹤鼠標移動,例如 GetMouseDelta ,對鼠標移動的敏感度。

此屬性不會影響滑鼠圖示的移動。它也不會影響客戶端的 設定選項 選項卡中的 相機靈敏度 設定,該選項也會調整事件追蹤鼠標移動的靈敏度。

此屬性的最大值為 10 和最小值為 0。較低的值對應較低的敏感度,較高的值對應較高的敏感度。

當靈敏度為 0 時,跟蹤滑鼠標移動的事件仍會發射,但所有顯示鼠標位置變更的參數和屬性都會返回 Vector2.new()Vector3.new()InputObject.Delta 的情況下。例如,GetMouseDelta 將永遠返回(0, 0)。

範例程式碼

This example creates a binoculars script that decreases the player's FieldOfView() and MouseDeltaSensitivity() when a player with a MouseEnabled() left mouse clicks. The script also points the player's Camera towards the Vector3 world position of the mouse click.

When the player left mouse clicks again, the player's camera reverts back to the a custom Enum.CameraType with the same field of view and CFrame() as before the player zoomed in with the script.

While the player uses the binoculars, the script locks the player's mouse to the center of the screen by setting the player's MouseBehavior() to LockCenter. The player's camera moves when the player moves their mouse according to the InputObject.Delta property passed by InputChanged() indicating the mouse's Vector2 change in screen position.

In order for this example to work as expected, it should be placed in a LocalScript.

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end

MouseEnabled

唯讀
未複製
平行讀取

此屬性描述用戶的裝置是否有可用的鼠標。當使用者的裝置具有可用的滑鼠時,此屬性為 true ;當它沒有時,為 false


local UserInputService = game:GetService("UserInputService")
if UserInputService.MouseEnabled then
print("The user's device has an available mouse!")
else
print("The user's device does not have an available mouse!")
end

在使用 UserInputService 滑鼠功能,如 UserInputService:GetMouseLocation() 之前,必須檢查此項。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

也見:

範例程式碼

This example creates a binoculars script that decreases the player's FieldOfView() and MouseDeltaSensitivity() when a player with a MouseEnabled() left mouse clicks. The script also points the player's Camera towards the Vector3 world position of the mouse click.

When the player left mouse clicks again, the player's camera reverts back to the a custom Enum.CameraType with the same field of view and CFrame() as before the player zoomed in with the script.

While the player uses the binoculars, the script locks the player's mouse to the center of the screen by setting the player's MouseBehavior() to LockCenter. The player's camera moves when the player moves their mouse according to the InputObject.Delta property passed by InputChanged() indicating the mouse's Vector2 change in screen position.

In order for this example to work as expected, it should be placed in a LocalScript.

Create a Binoculars Script

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head", false)
local mouse = player:GetMouse()
local zoomed = false
local camera = game.Workspace.CurrentCamera
local target = nil
local originalProperties = {
FieldOfView = nil,
_CFrame = nil,
MouseBehavior = nil,
MouseDeltaSensitivity = nil,
}
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
-- Reset camera back to CFrame and FieldOfView before zoom
local function ResetCamera()
target = nil
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = originalProperties._CFrame
camera.FieldOfView = originalProperties.FieldOfView
UserInputService.MouseBehavior = originalProperties.MouseBehavior
UserInputService.MouseDeltaSensitivity = originalProperties.MouseDeltaSensitivity
end
local function ZoomCamera()
-- Allow camera to be changed by script
camera.CameraType = Enum.CameraType.Scriptable
-- Store camera properties before zoom
originalProperties._CFrame = camera.CFrame
originalProperties.FieldOfView = camera.FieldOfView
originalProperties.MouseBehavior = UserInputService.MouseBehavior
originalProperties.MouseDeltaSensitivity = UserInputService.MouseDeltaSensitivity
-- Zoom camera
target = mouse.Hit.Position
local eyesight = head.Position
camera.CFrame = CFrame.new(eyesight, target)
camera.Focus = CFrame.new(target)
camera.FieldOfView = 10
-- Lock and slow down mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseDeltaSensitivity = 1
-- Reset zoom angles
AngleX, TargetAngleX = 0, 0
AngleY, TargetAngleY = 0, 0
end
-- Toggle camera zoom/unzoom
local function MouseClick()
if zoomed then
-- Unzoom camera
ResetCamera()
else
-- Zoom in camera
ZoomCamera()
end
zoomed = not zoomed
end
local function MouseMoved(input)
if zoomed then
local sensitivity = 0.6 -- anything higher would make looking up and down harder; recommend anything between 0~1
local smoothness = 0.05 -- recommend anything between 0~1
local delta = Vector2.new(input.Delta.x / sensitivity, input.Delta.y / sensitivity) * smoothness
local X = TargetAngleX - delta.y
local Y = TargetAngleY - delta.x
TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
TargetAngleY = (Y >= 80 and 80) or (Y <= -80 and -80) or Y
AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
AngleY = AngleY + (TargetAngleY - AngleY) * 0.15
camera.CFrame = CFrame.new(head.Position, target)
* CFrame.Angles(0, math.rad(AngleY), 0)
* CFrame.Angles(math.rad(AngleX), 0, 0)
end
end
local function InputBegan(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
MouseClick()
end
end
local function InputChanged(input, _gameProcessedEvent)
if input.UserInputType == Enum.UserInputType.MouseMovement then
MouseMoved(input)
end
end
if UserInputService.MouseEnabled then
UserInputService.InputBegan:Connect(InputBegan)
UserInputService.InputChanged:Connect(InputChanged)
end

MouseIcon

ContentId
平行讀取

MouseIcon 屬性決定使用作指標的圖像。如果為空白,將使用預設箭頭。當指針漂浮在某些介面對象上,例如 ImageButton , TextButton , TextBoxProximityPrompt 時,此圖像將被覆蓋並暫時忽略。

要完全隱藏鼠標,請不要使用透明圖像。相反,將 設置為 false。

範例程式碼

This example changes the user mouse icon to look like a dragon image.

UserInputService.MouseIcon

local UserInputService = game:GetService("UserInputService")
-- In order to restore the cursor to what it was set to previously, it will need to be saved to a variable
local savedCursor = nil
local function setTemporaryCursor(cursor: string)
-- Only update the saved cursor if it's not currently saved
if not savedCursor then
savedCursor = UserInputService.MouseIcon
end
UserInputService.MouseIcon = cursor
end
local function clearTemporaryCursor()
-- Only restore the mouse cursor if there's a saved cursor to restore
if savedCursor then
UserInputService.MouseIcon = savedCursor
-- Don't restore the same cursor twice (might overwrite another script)
savedCursor = nil
end
end
setTemporaryCursor("http://www.roblox.com/asset?id=163023520")
print(UserInputService.MouseIcon)
clearTemporaryCursor()
print(UserInputService.MouseIcon)

MouseIconEnabled

平行讀取

此屬性決定是否在滑鼠的圖示可見時顯示 圖示,當它不可見時不會。

例如,下面的代碼片段隱藏了滑鼠標的圖示。


local UserInputService = game:GetService("UserInputService")
UserInputService.MouseIconEnabled = false

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

範例程式碼

This example hides the mouse icon while the player beings using their keyboard, such as to chat or enter text into a TextBox. The mouse icon reappears when the user resumes mouse input.

This uses the LastInputType() event to determine when the user begins keyboard input and mouse input - based on the value of the lastInputType argument.

In order for this example to work as expected, it should be placed in a LocalScript.

Hide Mouse During Keyboard Input

local UserInputService = game:GetService("UserInputService")
local mouseInput = {
Enum.UserInputType.MouseButton1,
Enum.UserInputType.MouseButton2,
Enum.UserInputType.MouseButton3,
Enum.UserInputType.MouseMovement,
Enum.UserInputType.MouseWheel,
}
local keyboard = Enum.UserInputType.Keyboard
local function toggleMouse(lastInputType)
if lastInputType == keyboard then
UserInputService.MouseIconEnabled = false
return
end
for _, mouse in pairs(mouseInput) do
if lastInputType == mouse then
UserInputService.MouseIconEnabled = true
return
end
end
end
UserInputService.LastInputTypeChanged:Connect(toggleMouse)

OnScreenKeyboardPosition

唯讀
未複製
平行讀取

此屬性描述屏幕上的鍵盤位置以像素。鍵盤的位置是 Vector2.new(0, 0) 當它不可見時。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScriptScript 使用 RunContext 設為 Enum.RunContext.Client

也見 OnScreenKeyboardVisibleOnScreenKeyboardSize

範例程式碼

This example prints the position of the player's on-screen keyboard.

UserInputService.OnScreenKeyboardPosition

local UserInputService = game:GetService("UserInputService")
print(UserInputService.OnScreenKeyboardPosition)

OnScreenKeyboardSize

唯讀
未複製
平行讀取

此屬性描述屏幕上的鍵盤大小以像素為單位。當鍵盤不可見時,鍵盤的大小為 Vector2.new(0, 0)

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScriptScript 使用 RunContext 設為 Enum.RunContext.Client

也見 OnScreenKeyboardVisibleOnScreenKeyboardPosition

OnScreenKeyboardVisible

唯讀
未複製
平行讀取

此屬性描述是否在使用者的屏幕上目前顯示鍵盤。

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScriptScript 使用 RunContext 設為 Enum.RunContext.Client

也見 OnScreenKeyboardSizeOnScreenKeyboardPosition

TouchEnabled

唯讀
未複製
平行讀取

此屬性描述用戶目前的裝置是否具有可用的觸摸屏。

屬性用於確定使用者的裝置是否具有觸摸屏幕,因此觸摸事件是否會發觸發。如果 TouchEnabled 為真,您可以使用 UserInputService 事件,例如 UserInputService.TouchStartedUserInputService.TouchEnded 來跟蹤用戶開始和停止觸摸裝置屏幕的時間。

下面的代碼片段印出使用者的裝置是否有觸摸屏。


local UserInputService = game:GetService("UserInputService")
if UserInputService.TouchEnabled then
print("The user's device has a touchscreen!")
else
print("The user's device does not have a touchscreen!")
end

也見:

範例程式碼

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

VREnabled

唯讀
未複製
平行讀取

此屬性描述用戶是否使用虛擬現實(VR)裝置。

如果 VR 裝置已啟用,您可以通過函數,例如 UserInputService:GetUserCFrame() 來與其位置和移動互動。您也可以使用 UserInputService.UserCFrameChanged 事件反應到 VR 裝置移動。


local UserInputService = game:GetService("UserInputService")
local isUsingVR = UserInputService.VREnabled
if isUsingVR then
print("User is using a VR headset!")
else
print("User is not using a VR headset!")
end

因為 UserInputService 只是客戶端,這個屬性只能在 LocalScript 中使用。

也見:

範例程式碼

This example demonstrates how to implement a head tracking script that mirrors the movement of a virtual reality (VR) headset (the user's actual head) to their in-game character's head.

The example first check if the user is using a VR device by checking the value of the VREnabled() property. This example only works if the user is using a VR headset.

To determine the initial CFrame of the character's head, the code sample calls GetUserCFrame() and passes Enum.UserCFrame.Head as the argument.

To update the head's CFrame whenever the user's VR headset moves, the example connects the VRService.UserCFrameChanged event to the TrackHead() function. When the event fires to indicate that a VR device moved, TrackHead() checks if the headset moved. If the headset moved, the function updates the CFrame of the character's head to the CFrame value provided as an argument.

As the UserCFrame enum also tracks VR left and right hand devices, the concept of VR device tracking can be expanded to other character bodyparts.

In order for the example to work as expected, it must be placed in a LocalScript.

VR Head Tracking

local VRService = game:GetService("VRService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local function TrackHead(inputType, value)
if inputType == Enum.UserCFrame.Head then
head.CFrame = value
end
end
if VRService.VREnabled then
-- Set the initial CFrame
head.CFrame = VRService:GetUserCFrame(Enum.UserCFrame.Head)
-- Track VR headset movement and mirror for character's head
VRService.UserCFrameChanged:Connect(TrackHead)
end

方法

GamepadSupports

此功能返回指定的 Enum.UserInputType 遊戲控制器是否支持與指定的 Enum.KeyCode 相對應的按鈕。此功能用於確定有效的遊戲控制器輸入。

要確定哪些 Enum.UserInputType 遊戲手柄已連接,請使用 UserInputService:GetConnectedGamepads()

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

遊戲手柄的 Enum.UserInputType

預設值:""
gamepadKeyCode: Enum.KeyCode

問題中的按鈕的 Enum.KeyCode

預設值:""

返回

是否給定的遊戲控制器支持與給定的 Enum.KeyCode 相對應的按鈕。

範例程式碼

This example binds the ButtonX key to action if it is supported by controller (Gamepad1). If bound, pressing the X Button invokes the action() function, which prints "Action".

Binding Functions to Gamepad Controls

local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local controller = Enum.UserInputType.Gamepad1
local buttonX = Enum.KeyCode.ButtonX
local function isSupported(gamepad, keycode)
return UserInputService:GamepadSupports(gamepad, keycode)
end
local function action()
print("Action")
end
if isSupported(controller, buttonX) then
ContextActionService:BindAction("sample action", action, false, buttonX)
end

GetConnectedGamepads

此功能返回目前連接的 Enum.UserInputType 遊戲控制板的一個陣列。如果沒有連接遊戲板,這個陣列將為空。此外,它只返回遊戲控制板的 UserInputType 對象。例個體、實例,此事件將返回連接的 Gamepad1 對象,但不是鍵盤對物件。

例如,以下代碼片段會擷取連接的遊戲控制板並將它們存儲在名為 connectedGamepads 的變量中。


local UserInputService = game:GetService("UserInputService")
local connectedGamepads = UserInputService:GetConnectedGamepads()

要檢查特定遊戲控制器是否連接,請使用 UserInputService:GetGamepadConnected()

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。

也見:


返回

一個由用戶裝置連接到的遊戲控制板對應的 UserInputTypes 數組。

範例程式碼

If you are using the default controls, you do not need to worry about this. If you're creating a custom script for handling gamepad controls, this is a good template for retrieving which gamepad enum you should use as the primary gamepad controller.

How to Set the Active Gamepad for Input

local UserInputService = game:GetService("UserInputService")
local function getActiveGamepad()
local activeGamepad = nil
local connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for _, gamepad in connectedGamepads do
if activeGamepad == nil or gamepad.Value < activeGamepad.Value then
activeGamepad = gamepad
end
end
end
if activeGamepad == nil then -- Nothing is connected; set up for "Gamepad1"
activeGamepad = Enum.UserInputType.Gamepad1
end
return activeGamepad
end
if UserInputService.GamepadEnabled then
local activeGamepad = getActiveGamepad()
print(activeGamepad)
end

GetDeviceAcceleration

GetDeviceAcceleration 函數決定使用者裝置的當前加速。它返回一個 InputObject 描述裝置當前加速的方法。

為了使此功能運作,使用者的裝置必須具有啟用加速度計。若要檢查使用者的裝置是否具有啟用加速度計,您可以檢查 UserInputService.AccelerometerEnabled 屬性。

如果您想在使用者的裝置加速變更時追蹤時間,您可以使用 UserInputService.DeviceAccelerationChanged 事件。

由於只能在本地發射,因此只能在 LocalScript 中使用。


返回

範例程式碼

This example checks if a user's device has an enabled accelerometer. If it does, the example prints the current acceleration of the device. If not, the example prints:

Cannot get device acceleration because device does not have an enabled accelerometer!

Print Device Acceleration

local UserInputService = game:GetService("UserInputService")
local accelerometerEnabled = UserInputService.AccelerometerEnabled
if accelerometerEnabled then
local acceleration = UserInputService:GetDeviceAcceleration().Position
print(acceleration)
else
print("Cannot get device acceleration because device does not have an enabled accelerometer!")
end

GetDeviceGravity

此功能返回 InputObject 描述裝置當前重力向量的函向量力。

重力向量由裝置與重力世界力相對的方向決定。例個體、實例,如果裝置完全垂直(直放),重力向量是 Vector3.new(0, 0, -9.18) 。如果裝置的左側指向下,向量是 Vector3.new(9.81, 0, 0)。最後,如果裝置的後面指向下,向量是 Vector3.new(0, -9.81, 0)。

此功能可能用於啟用使用者的裝置對遊戲內的重力產生影響或控制,或移動遊戲內的物體,例如球。

僅當使用啟用陀螺儀的裝置(例如手機)的玩家時,才追蹤重力 - 例如,移動裝置。

要檢查使用者的裝置是否具有啟用陀螺儀,請檢查 UserInputService.GyroscopeEnabled 的值。如果裝置具有啟用陀螺儀,您也可以使用 UserInputService.DeviceGravityChanged 事件來跟蹤當使用者裝置上的重力力量變化時。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

範例程式碼

Using the Gyroscope gives us the down direction for the player's device. We can use this to move objects in the game world. This example implements a level where the bubble will move along the X and Z axes depending on the device's current gryoscope position in X and Z.

Moving Objects with the Gyroscope

local UserInputService = game:GetService("UserInputService")
local bubble = script.Parent:WaitForChild("Bubble")
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new(0, 20, 0) * CFrame.Angles(-math.pi / 2, 0, 0)
if UserInputService.GyroscopeEnabled then
-- Bind event to when gyroscope detects change
UserInputService.DeviceGravityChanged:Connect(function(accel)
-- Move the bubble in the world based on the gyroscope data
bubble.Position = Vector3.new(-8 * accel.Position.X, 1.8, -8 * accel.Position.Z)
end)
end

GetDeviceRotation

此功能返回 InputObjectCFrame 描述裝置當前旋轉向量的函向量力。

這是用輸入對象發射的。輸入對象的 位置 屬性是一個Enum.InputType.Gyroscope,用於跟蹤每個本地裝置軸的總旋轉。

裝置旋轉只能在具有 gyroscope 的裝置上追蹤。

由於此功能是在本地發射的,因此只能在 LocalScript 中使用。


返回

包含兩個屬性的 tuple:

  1. delta 屬性描述最後發生的旋轉量
  2. CFrame 是裝置目前對其預設參考框的旋轉關係。

範例程式碼

This example prints the current CFrame of a players device. Note that this will only work as expected if the player's device has an enabled gyroscope. If not, the example prints:

Cannot get device rotation because device does not have an enabled gyroscope!

Print Device Rotation

local UserInputService = game:GetService("UserInputService")
local gyroEnabled = UserInputService:GyroscopeEnabled()
if gyroEnabled then
local _inputObj, cframe = UserInputService:GetDeviceRotation()
print("CFrame: {", cframe, "}")
else
print("Cannot get device rotation because device does not have an enabled gyroscope!")
end

GetFocusedTextBox

此功能返回客戶目前聚焦的 TextBox 。A TextBox 可以由使用者手動選擇,或使用 TextBox:CaptureFocus() 函數強制選擇。如果未選擇 TextBox ,此函數將返回 nil

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。

也見「也見」

返回

GetGamepadConnected

此功能返回是否連接給客戶端的具有給定 Enum.UserInputType 的遊戲控制器。

這可以用來檢查特定游戏手柄,例如 'Gamepad1' 是否連接到客戶端設裝置。

要取得所有連接遊戲板的列表,請使用 UserInputService:GetConnectedGamepads()

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

問題中的遊戲手柄的 Enum.UserInputType

預設值:""

返回

是否連接了與 Enum.UserInputType 相關的遊戲控制器。

範例程式碼

This example returns whether Gamepad1 is connected to the client. It will print true if Gamepad1 is connected and false if Gamepad1 is not connected.

Check Whether a Gamepad is Connected

local UserInputService = game:GetService("UserInputService")
local isConnected = UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1)
if isConnected then
print("Gamepad1 is connected to the client")
else
print("Gamepad1 is not connected to the client")
end

GetGamepadState

此功能返回給所有可用輸入的 InputObjects 陣列,代表每個輸入的最後輸入狀態,在指定的 Enum.UserInputType 遊戲手柄上。

要找到連接的遊戲板的 UserInputTypes,請使用 UserInputService:GetConnectedGamepads()

因為這個功能只在本地發射,所以只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

與問題的遊戲控制器相對應的 Enum.UserInputType

預設值:""

返回

一個代表給定遊戲控制器所有可用輸入當前狀態的 InputObjects 陣列。

GetImageForKeyCode

ContentId

這個方法接受要求的 Enum.KeyCode 並返回與連接到的遊戲手柄裝置相關的圖像(限於 Xbox、PlayStation 和 Windows)。這表示如果連接的控制器是 Xbox 一控制器,使用者會看到 Xbox 資產。相同地,如果連接的裝置是遊戲主機控制器,使用者會看到遊戲主機資產。如果您想使用自定义資產,請參閱 GetStringForKeyCode()

參數

keyCode: Enum.KeyCode

要擷取相關圖像的 Enum.KeyCode

預設值:""

返回

ContentId

返回的圖像資產ID。

範例程式碼

This API returns the requested image for the given Enum.KeyCode.

UserInputService - Get Image For KeyCode

local UserInputService = game:GetService("UserInputService")
local imageLabel = script.Parent
local key = Enum.KeyCode.ButtonA
local mappedIconImage = UserInputService:GetImageForKeyCode(key)
imageLabel.Image = mappedIconImage

GetKeysPressed

此功能返回與目前按下的鍵相關的 InputObjects 陣列。

這個陣列可以循環以確定目前正在按下的鍵,使用 InputObject.KeyCode 值。

要檢查是否按下特定鍵,請使用 UserInputService:IsKeyDown()

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

與目前按下的鍵相關的一個陣列 InputObjects

範例程式碼

This example demonstrates how to use the UserInputService:GetKeysPressed() function to create a combo action where the player double jumps when the player presses actionKey key (Left Shift) + Jump key (Spacebar).

The actionKey variable indicates which key, combined with the Jump key, needs to be pressed for the player to double jump.

When the player presses the Jump key, the JumpRequest() event is invoked, which is connected to the script's jumpRequest function. If the Left Shift key is pressed and the player is not already in the middle of a jump, this function sets the canDoubleJump boolean to true.

The example connects the stateChanged function to the StateChanged() event so that the function fires when their humanoid's state changes. If the state changes from Jumping to Freefall, and the canDoubleJump boolean is true, the function makes the player jump again by setting their humanoid's state back to Jumping using the ChangeState() function . The example also uses the canJump boolean variable to determine when the player is in the middle of a jump. Without this variable, the player could press the actionKey + Jump Key (spacebar) to jump endlessly without landing. When the boolean is true, the player is not jumping. If the player is not jumping, jumpRequest() checks if the actionKey is pressed and sets canJump to false. When the player lands, stateChanged() sets the variable to true.

Double Jump Key Combo

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local actionKey = Enum.KeyCode.LeftShift
local canJump = true
local canDoubleJump = false
local function jumpRequest()
local keysPressed = UserInputService:GetKeysPressed()
for _, key in ipairs(keysPressed) do
if key.KeyCode == actionKey and canJump then
canJump = false
canDoubleJump = true
end
end
end
local function stateChanged(oldState, newState)
-- Double jump during freefall if able to
if oldState == Enum.HumanoidStateType.Jumping and newState == Enum.HumanoidStateType.Freefall and canDoubleJump then
canDoubleJump = false
task.wait(0.2)
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
-- Allow player to jump again after they land
if oldState == Enum.HumanoidStateType.Freefall and newState == Enum.HumanoidStateType.Landed then
canJump = true
end
end
UserInputService.JumpRequest:Connect(jumpRequest)
humanoid.StateChanged:Connect(stateChanged)

GetLastInputType

此功能返回與使用者最近輸入相關的 'Enum.UserInputType' 功能。

例如,如果使用者之前的輸入按下了空格鍵,返回的 Enum.UserInputType 將是 '鍵盤'

UserInputService.LastInputTypeChanged可用於跟蹤用戶最後使用的Enum.UserInputType時間。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

與使用者最新輸入相關的 Enum.UserInputType

範例程式碼

This example gets the last input type and indicates if it was keyboard input.

UserInputService:GetLastInputType

local UserInputService = game:GetService("UserInputService")
local lastInput = UserInputService:GetLastInputType()
if lastInput == Enum.UserInputType.Keyboard then
print("Most recent input was via keyboard")
end

GetMouseButtonsPressed

此功能返回一個 array 的 InputObjects 對應目前按下的滑鼠按鈕。

這個功能追蹤的滑鼠按鈕包括:


<td>說明</td>
</tr>
</thead>
<tr>
<td>滑鼠按鈕1</td>
<td>左滑鼠按鈕。</td>
</tr>
<tr>
<td>滑鼠按鈕2</td>
<td>右鍵按钮。</td>
</tr>
<tr>
<td>滑鼠按鈕3</td>
<td>中央滑鼠按鈕。</td>
</tr>
名稱

如果使用者在功能呼叫時沒有按下任何滑鼠按鈕,將返回一個空陣列。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

一個包含 InputObjects 對應目前按下的滑鼠按鈕的陣列。

範例程式碼

This example checks if the user pressed MouseButton1, MouseButton2, or both mouse buttons on InputBegan().

The example can be extended to behave differently depending on which mouse buttons are pressed.

Check which MouseButtons are Pressed

local UserInputService = game:GetService("UserInputService")
-- InputBegan is a UserInputService event that fires when the player
-- begins interacting via a Human-User input device
UserInputService.InputBegan:Connect(function(_input, _gameProcessedEvent)
-- Returns an array of the pressed MouseButtons
local buttons = UserInputService:GetMouseButtonsPressed()
local m1Pressed, m2Pressed = false, false
for _, button in pairs(buttons) do
if button.UserInputType.Name == "MouseButton1" then
print("MouseButton1 is pressed")
m1Pressed = true
end
if button.UserInputType.Name == "MouseButton2" then
print("MouseButton2 is pressed")
m2Pressed = true
end
if m1Pressed and m2Pressed then
print("Both mouse buttons are pressed")
end
end
end)

GetMouseDelta

此功能返回玩家位置的 在最後渲染的框架中的變更,以像素為單位。此功能只能在使用 UserInputService.MouseBehavior 屬性將鼠標鎖定時才能運作。如果滑鼠未被鎖定,返回的 Vector2 值將為零。

在客戶端設定中和 UserInputService.MouseDeltaSensitivity 中確定的滑鼠標靈敏度將對結果產生影響。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

變更滑鼠的移動。

範例程式碼

GetMouseDelta returns the current change in movement of the mouse as a Vector2, but only if the mouse is locked. If the mouse isn't locked the values in the returned Vector2 will be zero. It measures any mouse movement in pixels from the last render step to the current render step. If the user has set their camera sensitivity to be higher or lower than 1 in the in-game menu this will affect the value returned by GetMouseDelta. The camera sensitivity is a multiplier to the amount the camera moves as a result of mouse input.

Getting Mouse Delta

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local function OnRenderStep()
local delta = UserInputService:GetMouseDelta()
print("The mouse has moved", delta, "since the last step.")
end
RunService:BindToRenderStep("MeasureMouseMovement", Enum.RenderPriority.Input.Value, OnRenderStep)

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

GetMouseLocation

此功能返回一個 Vector2 代表玩家的當前屏幕位置 Mouse 以像素來自左上角。這不會計算 Enum.ScreenInsets ; 要獲得最左上角和最右下角的插入,請呼叫 GuiService:GetGuiInset()

如果滑鼠指針的位置處於畫面外或玩家的裝置沒有滑鼠,返回的值將無法確定。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。


返回

A Vector2 代表滑鼠標目前屏幕位置,以畫素為單位。

範例程式碼

This example binds the moveToMouse() to RunService's RenderStep to move the GUI to the location of the player's mouse. It does this by converting the location, a Vector2, into a UDim2.

The example sets the value of the GUI's parent ScreenGui ScreenGui.IgnoreGuiInset property to false force the GUI Inset imposed by Roblox's CoreGuis to be ignored by the ScreenGui and its descendants

In order for this example to work as expected, it should be placed in a LocalScript that is a child of the GUI being moved to the mouse's location.

Move GUI To Mouse Location

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local gui = script.Parent
local screenGui = gui.Parent
screenGui.IgnoreGuiInset = true
local function moveGuiToMouse()
local mouseLocation = UserInputService:GetMouseLocation()
gui.Position = UDim2.fromOffset(mouseLocation.X, mouseLocation.Y)
end
moveGuiToMouse()
RunService:BindToRenderStep("moveGuiToMouse", 1, moveGuiToMouse)

GetNavigationGamepads

此功能返回連接且啟用 GUI 導航的游戏手柄 UserInputTypes 陣列。此列表是按優先級排序的,即可以循環以確定哪個遊戲控制器應具有導航控制。

連接的遊戲手柄是導航遊戲手柄還是僅決定哪些手把手柄控制導航圖形介面。這不會影響導航控件。

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。

也見:


返回

一個由 UserInputTypes 組成的陣列,可用於在優先級順序下的 GUI 導航。

GetStringForKeyCode

取得字串代碼的鑰匙 返回一個代表用戶應按下的鑰匙來輸入給定的 Enum.KeyCode 的字串,同時考慮他們的輸入布局。對於需要保留某些修改器的關鍵代碼,此功能會將關鍵與修改器一起返回,以外加於按下的關鍵。參見以下範例以獲得進一步說明。

當使用非QWERTY鍵盤布局與 Roblox 交互時,鍵代會映射到等值的QWERTY位置。例如,在 AZERTY 鍵盤上按下 A 會導致結果為 Enum.KeyCode.Q。這種映射可能會導致經驗用戶介面元素的不匹配資訊。例如,「按下 M 以開啟地圖」在 AZERTY 鍵盤上不準確;需要「按下 ? 以開啟地圖」,這與 QWERTY 上的 M 相同位置。這個功能可以解決這個問題,提供在使用非QWERTY鍵盤布局時按下的實際鍵。


local UserInputService = game:GetService("UserInputService")
local textLabel = script.Parent
local mapKey = Enum.KeyCode.M
textLabel.Text = "Press " .. UserInputService:GetStringForKeyCode(mapKey) .. " to open the map"
QWERTY 鍵盤的範例

<th>返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>枚列。KeyCode.Q</code></td>
<td><code>Q</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.W</code></td>
<td><code>W</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Equals</code></td>
<td><code>=</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.At</code></td>
<td><code>2</code> 因為 <code>@</code> 被輸入為 <kbd>Shift</kbd><kbd>2</kbd></td>
</tr>
</tbody>
鍵碼
在 AZERTY 鍵盤上的範例

<th>返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>枚列。KeyCode.Q</code></td>
<td><code>A</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.W</code></td>
<td><code>Z</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Equals</code></td>
<td><code>=</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.At</code></td>
<td><code>É</code></td>
</tr>
</tbody>
鍵碼
遊戲控制器使用

返回最近連接的遊戲控制器的字串映射。如果連接的控制器不支持,函數會返回請求的鑰匙代碼的預設字串轉換。

下面的例子顯示了您如何為 ButtonA 映射自定義資產:


local UserInputService = game:GetService("UserInputService")
local imageLabel = script.Parent
local key = Enum.KeyCode.ButtonA
local mappings = {
ButtonA = "rbxasset://BUTTON_A_ASSET", -- Replace with the desired ButtonA asset
ButtonCross = "rbxasset://BUTTON_CROSS_ASSET" -- Replace with the desired ButtonCross asset
}
local mappedKey = UserInputService:GetStringForKeyCode(key)
local image = mappings[mappedKey]
imageLabel.Image = image
遊戲控制器映射

方向鍵代碼不會因裝置而有任何差異。Enum.KeyCode.ButtonSelect在某些情況下有稍微不同的行為。使用兩種PlayStation映射來確保使用者看到正確的按鈕。


<th>遊戲主機返回值</th>
<th>Xbox 返回值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Enum.KeyCode.按鈕A</code></td>
<td><code>按鈕交叉</code></td>
<td><code>按鈕A</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.按鈕B</code></td>
<td><code>按鈕圓圈</code></td>
<td><code>按鈕B</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonX</code></td>
<td><code>按鈕方塊</code></td>
<td><code>按鈕X</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.按鈕Y</code></td>
<td><code>按鈕三角形</code></td>
<td><code>按鈕Y</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL1</code></td>
<td><code>按鈕L1</code></td>
<td><code>按鈕LB</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL2</code></td>
<td><code>按鈕L2</code></td>
<td><code>按鈕LT</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL3</code></td>
<td><code>按鈕L3</code></td>
<td><code>按鈕LS</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR1</code></td>
<td><code>按鈕 R1</code></td>
<td><code>按鈕RB</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR2</code></td>
<td><code>按鈕R2</code></td>
<td><code>按鈕RT</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR3</code></td>
<td><code>按鈕R3</code></td>
<td><code>按鈕RS</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.按鈕開始</code></td>
<td><code>按鈕選項</code></td>
<td><code>按鈕開始</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.按鈕選擇</code></td>
<td><code>按鈕觸摸板</code> 和 <code>按鈕分享</code></td>
<td><code>按鈕選擇</code></td>
</tr>
</tbody>
鍵碼
鍵碼系統圖像

當使用 Enum.KeyCode 可能更好地以圖像形式表示,例如在使用者介面中的 ImageLabel 時,您可以使用以下舊版圖示。然而,建議您使用 GetImageForKeyCode() 作為更現代、跨平台方法來取得 Xbox 和 PlayStation 控制器圖示。


<th>圖像</th>
<th>資產 ID</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Enum.KeyCode.ButtonX</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxX.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxX.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonY</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxY.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxY.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonA</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxA.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxA.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonB</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxB.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxB.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.DPadLeft</code></td>
<td>
<img src="../../../assets/scripting/controls/dpadLeft.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/dpadLeft.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.DPadRight</code></td>
<td>
<img src="../../../assets/scripting/controls/dpadRight.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/dpadRight.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.DPadUp</code></td>
<td>
<img src="../../../assets/scripting/controls/dpadUp.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/dpadUp.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.DPadDown</code></td>
<td>
<img src="../../../assets/scripting/controls/dpadDown.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/dpadDown.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.按鈕選擇</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxView.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxView.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonStart</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxmenu.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxmenu.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL1</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxLB.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxLB.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR1</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxRB.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxRB.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL2</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxLT.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxLT.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR2</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxRT.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxRT.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonL3</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxLS.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxLS.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.ButtonR3</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxRS.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxRS.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Thumbstick1</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxLSDirectional.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxLSDirectional.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Thumbstick2</code></td>
<td>
<img src="../../../assets/scripting/controls/xboxRSDirectional.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/xboxRSDirectional.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Backspace</code></td>
<td>
<img src="../../../assets/scripting/controls/backspace.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/backspace.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Return</code></td>
<td>
<img src="../../../assets/scripting/controls/return.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/return.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.左班次</code></td>
<td>
<img src="../../../assets/scripting/controls/shift.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/shift.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.RightShift</code></td>
<td>
<img src="../../../assets/scripting/controls/shift.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/shift.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Tab</code></td>
<td>
<img src="../../../assets/scripting/controls/tab.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/tab.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Apostrophe</code></td>
<td>
<img src="../../../assets/scripting/controls/apostrophe.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/apostrophe.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Comma</code></td>
<td>
<img src="../../../assets/scripting/controls/comma.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/comma.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Backquote</code></td>
<td>
<img src="../../../assets/scripting/controls/graveaccent.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/graveaccent.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Period</code></td>
<td>
<img src="../../../assets/scripting/controls/period.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/period.png</code></td>
</tr>
<tr>
<td><code>Enum.KeyCode.Space</code></td>
<td>
<img src="../../../assets/scripting/controls/spacebar.png" width="24">
</img>
</td>
<td><code>rbxasset://textures/ui/Controls/spacebar.png</code></td>
</tr>
</tbody>
鍵碼

參數

keyCode: Enum.KeyCode
預設值:""

返回

GetSupportedGamepadKeyCodes

此功能返回與給定 Enum.UserInputType 相關的游戏手柄所支持的 KeyCodes 陣列。

此功能可用於確定哪些鍵碼被支持,而連接的遊戲控制器不支持。要確定是否支持特定的鑰匙碼,請使用 UserInputService:GamepadSupports()

如果在非存在或未連接的遊戲控制器上呼叫此功能,則此功能將返回空陣列。

因為 UserInputService 只是客戶端,這個功能只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

遊戲手柄的 Enum.UserInputType

預設值:""

返回

由指定遊戲控制器支持的一個 KeyCodes 陣列。

範例程式碼

This example gets a list of navigation gamepads and a list of their supported Enum.KeyCodes. Then, it iterates through the supported KeyCode list and binds the ButtonX and X keys to functions if they are supported by a gamepad using the ContextActionService.

Binding Supported Gamepad KeyCodes

local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local function actionHandler(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
print("Action Handler: " .. actionName)
print(inputObject)
end
-- Since this function does not return anything, this handler will
-- "sink" the input and no other action handlers will be called after
-- this one.
end
local navGamepads = UserInputService:GetNavigationGamepads()
for _, gamepad in pairs(navGamepads) do
local supportedKeyCodes = UserInputService:GetSupportedGamepadKeyCodes(gamepad)
for _, keycode in pairs(supportedKeyCodes) do
if keycode == Enum.KeyCode.ButtonX then
ContextActionService:BindAction("SampleAction", actionHandler, false, Enum.KeyCode.ButtonX)
end
if keycode == Enum.KeyCode.X then
ContextActionService:BindAction("SampleAction", actionHandler, false, Enum.KeyCode.X)
end
end
end

IsGamepadButtonDown

此功能檢查特定按鈕是否在特定遊戲控制器上按下。如果 gamepad 具有指定的 button 按下,則返回 true;否則返回 false。

有效的使用者輸入類型

指定的遊戲控制器應該是下列使用者輸入類型枚列值之一:


<tr>
<td>Enum.UserInputType.游戏手柄1-8</td>
</tr>
名稱
有效的鍵碼列表

指定的按鈕應該是下列鍵碼枚值之一:


<tr>
<td>Enum.KeyCode.ButtonX</td>
</tr>
<tr>
<td>Enum.KeyCode.按鈕Y</td>
</tr>
<tr>
<td>Enum.KeyCode.按鈕A</td>
</tr>
<tr>
<td>Enum.KeyCode.按鈕B</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonR1</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonL1</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonR2</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonL2</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonR3</td>
</tr>
<tr>
<td>Enum.KeyCode.ButtonL3</td>
</tr>
<tr>
<td>Enum.KeyCode.按鈕開始</td>
</tr>
<tr>
<td>Enum.KeyCode.按鈕選擇</td>
</tr>
<tr>
<td>Enum.KeyCode.DPad左</td>
</tr>
<tr>
<td>Enum.KeyCode.DPadRight</td>
</tr>
<tr>
<td>Enum.KeyCode.DPadUp</td>
</tr>
<tr>
<td>Enum.KeyCode.DPadDown</td>
</tr>
名稱

這可用於檢查是否有特定按鈕,例如 A,被按住。例如:


local UserInputService = game:GetService("UserInputService")
local button = Enum.KeyCode.ButtonA
local gamepad = Enum.UserInputType.Gamepad1
local isButtonHeld = UserInputService:IsGamepadButtonDown(gamepad, button)

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

指定遊戲控制器的 Enum.UserInputType

預設值:""
gamepadKeyCode: Enum.KeyCode

指定按鈕的 Enum.KeyCode

預設值:""

返回

是否按下指定的遊戲控制器按鈕在指定的遊戲控制器上。

範例程式碼

This example uses the UserInputService:IsGamepadButtonDown() function to create different behaviors when the X gamepad button is pressed than when a X button is not pressed when user input UserInputBegan|begins.

The local function IsGamepadXDown() returns whether the X gamepad button is down. This function checks if the X button is down for the activeGamepad, which is set by GetActiveGamepad. The GetActiveGamepad() fnction finds the lowest numbered navigation gamepad, connected gamepad, or gamepad1 if there are no navigation or connected gamepads.

Special Action on Gamepad Button Combo

local UserInputService = game:GetService("UserInputService")
local activeGamepad = nil
local buttonX = Enum.KeyCode.ButtonX
local function isGamepadXDown()
if activeGamepad then
return UserInputService:IsGamepadButtonDown(activeGamepad, buttonX)
end
return false
end
local function input(_input, _gameProcessedEvent)
if not isGamepadXDown() then
-- Normal event
else
-- X Button down event
end
end
local function getActiveGamepad()
local activateGamepad = nil
local navigationGamepads = {}
navigationGamepads = UserInputService:GetNavigationGamepads()
if #navigationGamepads > 1 then
for i = 1, #navigationGamepads do
if activateGamepad == nil or navigationGamepads[i].Value < activateGamepad.Value then
activateGamepad = navigationGamepads[i]
end
end
else
local connectedGamepads = {}
connectedGamepads = UserInputService:GetConnectedGamepads()
if #connectedGamepads > 0 then
for i = 1, #connectedGamepads do
if activateGamepad == nil or connectedGamepads[i].Value < activateGamepad.Value then
activateGamepad = connectedGamepads[i]
end
end
end
if activateGamepad == nil then -- nothing is connected, at least set up for gamepad1
activateGamepad = Enum.UserInputType.Gamepad1
end
end
return activateGamepad
end
if UserInputService.GamepadEnabled then
activeGamepad = getActiveGamepad()
UserInputService.InputBegan:Connect(input)
end

IsKeyDown

此功能返回用戶是否按住與給定 Enum.KeyCode 相關的鍵。如果指定的鍵按下了,則返回 true ;如果未按下,則返回 false

這可以用來檢查是否按下了特定的鍵,例如空格鍵。例如:


local UserInputService = game:GetService("UserInputService")
local spaceHeld = UserInputService:IsKeyDown(Enum.KeyCode.Space)

要取回使用者按下的所有鍵清單,請使用 UserInputService:GetKeysPressed() 功能。

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。

也見:

參數

keyCode: Enum.KeyCode

鍵匙的 Enum.KeyCode

預設值:""

返回

指定的鍵是否被按住。

範例程式碼

This example uses the UserInputService:IsKeyDown() function to create different behaviors when a shift key is held down than when a shift key is not held down when user input UserInputBegan|begins.

The local function IsShiftKeyDown() returns whether the left or right shift keys are pressed.

Special Action on Key Combo Press

local UserInputService = game:GetService("UserInputService")
local shiftKeyL = Enum.KeyCode.LeftShift
local shiftKeyR = Enum.KeyCode.RightShift
-- Return whether left or right shift keys are down
local function isShiftKeyDown()
return UserInputService:IsKeyDown(shiftKeyL) or UserInputService:IsKeyDown(shiftKeyR)
end
-- Handle user input began differently depending on whether a shift key is pressed
local function input(_input, _gameProcessedEvent)
if not isShiftKeyDown() then
-- Normal input
else
-- Shift input
end
end
UserInputService.InputBegan:Connect(input)

IsMouseButtonPressed

此功能接受滑鼠按鈕 Enum.UserInputType 並返回表示目前是否按下的 bool 值。

檢查的滑鼠按鈕取決於傳送到函數作為參引數的 Enum.UserInputType 值。例如:


local UserInputService = game:GetService("UserInputService")
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)

因為 UserInputService 只能在客戶端使用,這個功能只能在 LocalScript 中使用。

參數

mouseButton: Enum.UserInputType

滑鼠按鈕的 Enum.UserInputType

預設值:""

返回

是否目前按下的滑鼠按鈕已被按住。

範例程式碼

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

IsNavigationGamepad

此功能返回 true 如果指定的 Enum.UserInputType 遊戲手柄允許控制導航和選擇 GuiObjects

如果你想設置導航遊戲手柄,你可以使用UserInputService:SetNavigationGamepad()。你也可以使用UserInputService:GetNavigationGamepads()來獲得所有導航遊戲手柄的列表。

例如,下面的代碼檢查遊戲패드1是否作為導航遊戲패드:


local UserInputService = game:GetService("UserInputService")
if UserInputService:IsNavigationGamepad(UserInputType.Gamepad1) then
print("Gamepad is a navigation gamepad!")
else
print("Gamepad is not a navigation gamepad!")
end

無論使用哪種導航,都可以使用 `UserInput/GetConnectedGamepads 來取得所有連接的遊戲控制板的列表。

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。

也見:

參數

gamepadEnum: Enum.UserInputType

指定游戏手柄的 Enum.UserInputType

預設值:""

返回

指定的遊戲控制器是導航遊戲控制器。

RecenterUserHeadCFrame

()

此功能將 VR 頭戴裝置的 CFrame 重新定位到使用者目前穿戴的頭戴裝置的當前方向。這意味著耳機的當前方向已設為 CFrame.new()

使用此功能將耳機CFRame移至播放區中央,如果看起來有奇怪的偏移值。

這與 VRService 函數相同,VRService:RecenterUserHeadCFrame()

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。


返回

()

範例程式碼

This example fires the function to recenter the CFrame of the user's head to the current location of the VR headset being worn by the user.

UserInputService:RecenterUserHeadCFrame

local UserInputService = game:GetService("UserInputService")
UserInputService:RecenterUserHeadCFrame()

SetNavigationGamepad

()

設置導航遊戲板功能設置是否可以將指定的 Enum.UserInputType 遊戲板移動到 GUI 導航器。允許移動 GUI 導航器的遊戲控制器被視為 導航遊戲控制器

如果 啟用 參數被傳為 true,遊戲控制器可以移動 GUI 導航器。如果引數是 false,遊戲手柄無法移動 GUI 導航器。

如果您想檢查指定的遊戲控制器是否設為導航遊戲控制器,您可以使用 UserInputService:IsNavigationGamepad() 功能。您也可以使用 UserInputService:GetNavigationGamepads() 來取回所有導航遊戲板的列表。

由於 UserInputService 只能在客戶端使用,此功能只能在 LocalScript 中使用。

也見:

參數

gamepadEnum: Enum.UserInputType

指定游戏手柄的 Enum.UserInputType

預設值:""
enabled: boolean

指定的遊戲控制器是否能夠移動 GUI 導航器。

預設值:""

返回

()

範例程式碼

This example sets Gamepad1 as a navigation gamepad by passing Enum.UserInputType.Gamepad1 and true as arguments.

UserInputService:SetNavigationGamepad

local UserInputService = game:GetService("UserInputService")
UserInputService:SetNavigationGamepad(Enum.UserInputType.Gamepad1, true)

活動

DeviceAccelerationChanged

裝置加速變更事件會在使用者移動具有加速度計的裝置時發生。

加速度計是一種在大多數移動裝置中找到的零件,用於測量加速(速度變化)。

要確定使用者的裝置是否啟用加速度計,請參閱UserInputService.AccelerometerEnabled

這個事件可以用來跟蹤擁有加速度計的裝置的運動。範例使用包括當移動裝置加速時移動玩家角色。

此外,此事件可以與 UserInputService:GetDeviceAcceleration() 一起使用,以確定裝置上的現有運動,如果裝置具有加速器。

此事件只在本地發射 - 這意味著只有裝置移動的玩家才能使用事件,並且只能在 LocalScript 中工作。

參數

acceleration: InputObject

一個 ,包含 '加速度計' 的 ' ,以及 顯示每個本地裝置軸的重力力的 ' 。


範例程式碼

This example uses the accelerometer to move the player character when a mobile device is accelerated. The character will move along the axis that the device was moved.

Control Players Using the Accelerometer

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local SENSITIVITY = 0.2
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local ready = true
local function changeAcceleration(acceleration)
if ready then
ready = false
local accel = acceleration.Position
if accel.Y >= SENSITIVITY then
humanoid.Jump = true
end
if accel.Z <= -SENSITIVITY then
humanoid:Move(Vector3.new(-1, 0, 0))
end
if accel.Z >= SENSITIVITY then
humanoid:Move(Vector3.new(1, 0, 0))
end
if accel.X <= -SENSITIVITY then
humanoid:Move(Vector3.new(0, 0, 1))
end
if accel.X >= SENSITIVITY then
humanoid:Move(Vector3.new(0, 0, -1))
end
task.wait(1)
ready = true
end
end
UserInputService.DeviceAccelerationChanged:Connect(changeAcceleration)

DeviceGravityChanged

當裝置的重力 UserInputService.DeviceGravityChanged 在擁有加速度計的裝置上變更時,事件會發生 Vector3

裝置的重力向量代表裝置上的每個 X、Y 和 Z 軸上的重力力。雖然重力永遠不會改變,但當裝置旋轉和變更方向時,所產生的力量在每個軸上會發生變化。對每個軸的力值是一個範圍為 -1 到 1 的單位向量。

加速度計是一種在大多數移動裝置中找到的零件,用於測量加速(速度變化)。

這個事件可以用來確定使用者裝置上的重力力的實際方向。此外,還可以使用它來模擬遊戲中使用者裝置上的重力力,例如在遊戲內對象上(見下面的示例)。

要檢查用戶的裝置是否具有啟用加速度計,請參閱 UserInputService.AccelerometerEnabled 。如果裝置具有啟用加速度計,您可以使用 UserInputService:GetDeviceGravity() 功能來獲得使用者裝置上的當前重力力。

參數

gravity: InputObject

一個 InputObject ,具有 InputObject.Position 屬性,顯示每個本地裝置軸上的重力力。這個位置可以用作確定設備相對於重力方向的方向。


範例程式碼

This code adds a force on a part so that it falls in the direction of actual gravity relative to the user's device.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have an accelerometer.

Move a Ball using the Accelerometer

local Workspace = game:GetService("Workspace")
local UserInputService = game:GetService("UserInputService")
local ball = script.Parent:WaitForChild("Ball")
local mass = ball:GetMass()
local gravityForce = ball:WaitForChild("GravityForce")
local function moveBall(gravity)
gravityForce.Force = gravity.Position * Workspace.Gravity * mass
end
if UserInputService.AccelerometerEnabled then
UserInputService.DeviceGravityChanged:Connect(moveBall)
end

This example controls the player's Camera so that it matches the player's device orientation via using the device's gyroscope and accelerometer.

The camera is positioned inside the player's head, and updated to move with the player and the user's device rotation, by executing the following line every RenderStep:


camera.CFrame = CFrame.new(head.Position - Vector3.new(0,8,10)) *
currentRotation

The code sample relies on the device's gyroscope to determine when the player rotates their device. It does so by connecting to the DeviceRotationChanged() event.

The code sample relies on the device's accelerometer to retrieve the gravity vector used to determine the device's orientation (whether it is flipped upside down or not). To determine whether the device's orientation is upside down, the code sample uses the DeviceGravityChanged() event.

Since the script places the camera inside the head to create a first-person camera, the limbs are made transparent by the HideCharacter() function so that the player does not see their Player.Character when rotating the camera.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have a gyroscope and an accelerometer.

Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

DeviceRotationChanged

當使用者旋轉擁有陀螺儀的裝置時,裝置旋轉變更事件發生。

陀螺儀是一種在大多數移動裝置中找到的組件,可偵測方向和旋轉速度。

事件對於跟蹤裝置的方向和用戶旋轉裝置後的變更有用。若要確定目前裝置的旋轉,您可以使用 UserInputService:GetDeviceRotation() 功能。

要檢查用戶的裝置是否有啟用陀螺儀,以及此事件是否會發觸發,請參閱 UserInputService.GyroscopeEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

參數

rotation: InputObject

一個 InputObject 提供關於裝置旋轉的資訊。 代表新的旋轉值,而 代表在位置值 中的旋轉變化。

cframe: CFrame

一個 CFrame 代表裝置目前的方向。


範例程式碼

This example controls the player's Camera so that it matches the player's device orientation via using the device's gyroscope and accelerometer.

The camera is positioned inside the player's head, and updated to move with the player and the user's device rotation, by executing the following line every RenderStep:


camera.CFrame = CFrame.new(head.Position - Vector3.new(0,8,10)) *
currentRotation

The code sample relies on the device's gyroscope to determine when the player rotates their device. It does so by connecting to the DeviceRotationChanged() event.

The code sample relies on the device's accelerometer to retrieve the gravity vector used to determine the device's orientation (whether it is flipped upside down or not). To determine whether the device's orientation is upside down, the code sample uses the DeviceGravityChanged() event.

Since the script places the camera inside the head to create a first-person camera, the limbs are made transparent by the HideCharacter() function so that the player does not see their Player.Character when rotating the camera.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have a gyroscope and an accelerometer.

Create a Gyroscopic Camera

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
local camera = workspace.CurrentCamera
local currentRotation = camera.CFrame -- CFrame.new(Vector3.new(0,0,0), Vector3.new(0,0,0))
local lastInputFrame = nil
local upsideDown = false
task.wait()
local orientationSet = false
local function GravityChanged(gravity)
if not orientationSet then
upsideDown = (gravity.Position.X < -0.5 or gravity.Position.Z > 0.5)
orientationSet = true
end
end
local function RotationChanged(_rotation, rotCFrame)
if orientationSet then
if not lastInputFrame then
lastInputFrame = rotCFrame
end
local delta = rotCFrame * lastInputFrame:inverse()
local x, y, z = delta:ToEulerAnglesXYZ()
if upsideDown then
delta = CFrame.Angles(-x, y, z)
else
delta = CFrame.Angles(x, -y, z)
end
currentRotation = currentRotation * delta
lastInputFrame = rotCFrame
end
end
local function HideCharacter()
for _, limb in pairs(character:GetChildren()) do
if limb:IsA("Part") then
limb.Transparency = 1
end
end
end
if UserInputService.GyroscopeEnabled then
UserInputService.DeviceGravityChanged:Connect(GravityChanged)
UserInputService.DeviceRotationChanged:Connect(RotationChanged)
HideCharacter()
RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
camera.CFrame = CFrame.new(head.Position - Vector3.new(0, 8, 10)) * currentRotation
camera.Focus = CFrame.new(currentRotation * Vector3.new(0, 0, -10))
end)
end

This code adds a force on a part so that it falls in the direction of actual gravity relative to the user's device.

In order for this example to work as expected, it must be placed in a LocalScript and the user's device must have an accelerometer.

Move a Ball using the Accelerometer

local Workspace = game:GetService("Workspace")
local UserInputService = game:GetService("UserInputService")
local ball = script.Parent:WaitForChild("Ball")
local mass = ball:GetMass()
local gravityForce = ball:WaitForChild("GravityForce")
local function moveBall(gravity)
gravityForce.Force = gravity.Position * Workspace.Gravity * mass
end
if UserInputService.AccelerometerEnabled then
UserInputService.DeviceGravityChanged:Connect(moveBall)
end

GamepadConnected

遊戲控制器連線事件會在遊戲控制器連接到客戶端時發生。

因為 Roblox 遊戲支持多個控制器,當與 UserInputService.GamepadDisconnected 事件配對時,此事件有用於跟蹤哪些控制器/遊戲板是啟用的。您也可以使用 UserInputService:GetConnectedGamepads() 來找到正確的遊戲控制器以使用。

下面的例子顯示了連接遊戲手柄到客戶端時的追蹤使用示例。


local UserInputService = game:GetService("UserInputService")
local function GamepadConnected(gamepad)
print("Player has plugged controller: " .. tostring(gamepad))
end)
UserInputService.GamepadConnected:Connect(GamepadConnected)

如果您想查看哪些裝置已連接,您可以使用 UserInputService:GetConnectedGamepads() 功能。

因為這個事件是在本地發射的,所以只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

連接的遊戲手柄的 Enum.UserInputType


GamepadDisconnected

遊戲控制器斷線事件會在遊戲控制器斷線時發生。

因為 Roblox 遊戲支持多個控制器,當與 UserInputService.GamepadConnected 事件配對時,此事件有用於跟蹤哪些控制器/遊戲板是啟用的。您也可以使用 UserInputService:GetConnectedGamepads() 來找到正確的遊戲控制器以使用。

下面的例子顯示了遊戲控制器從客戶端斷開時追蹤的使用示例。


local UserInputService = game:GetService("UserInputService")
local function GamepadDisconnected(gamepad)
print("Player has unplugged controller: " .. tostring(gamepad))
end)
UserInputService.GamepadDisconnected:Connect(GamepadDisconnected)

因為這個事件是在本地發射的,所以只能在 LocalScript 中使用。

也見:

參數

gamepadNum: Enum.UserInputType

已斷開的遊戲手柄的 Enum.UserInputType


InputBegan

輸入開始事件會在使用者開始使用人工智慧與電腦介面裝置(滑鼠按鈕向下、觸摸開始、鍵盤按鈕向下等)時發生。

它可以用來跟蹤使用者互動的開始,例如當使用者首次與 GUI 元件、遊戲控制器等互動時。它不捕捉滑鼠輪移動。

這個事件可以與 UserInputService.InputChangedUserInputService.InputEnded 一起使用,來跟蹤用戶輸入開始、變更和結束的時間。

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The following example demonstrates one of many usage examples of handling user input from InputBegan depending on its type.

Handling InputBegan

-- In order to use the InputBegan event, the UserInputService service must be used
local UserInputService = game:GetService("UserInputService")
-- A sample function providing multiple usage cases for various types of user input
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard then
print("A key is being pushed down! Key:", input.KeyCode)
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
print("The left mouse button has been pressed down at", input.Position)
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
print("The right mouse button has been pressed down at", input.Position)
elseif input.UserInputType == Enum.UserInputType.Touch then
print("A touchscreen input has started at", input.Position)
elseif input.UserInputType == Enum.UserInputType.Gamepad1 then
print("A button is being pressed on a gamepad! Button:", input.KeyCode)
end
if gameProcessed then
print("The game engine internally observed this input!")
else
print("The game engine did not internally observe this input!")
end
end)

InputChanged

當使用者變更如何透過人工智慧與電腦介面裝置(如滑鼠按鈕向下、觸摸開始、鍵盤按鈕向下等)進行互動時,輸入變更事件會發生。

若要忽略 Roblox 自動處理的事件,例如在 ScrollingFrame 中滾動,請檢查 gameProcessedEvent 參數是否為 false。這個事件可以與 UserInputService.InputBeganUserInputService.InputEnded 一起使用,來跟蹤用戶輸入開始、變更和結束的時間。

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The following example demonstrates one of many usage examples of handling user input from InputChanged depending on its type.

Handling InputChanged

-- In order to use the InputChanged event, the UserInputService service must be used
local UserInputService = game:GetService("UserInputService")
-- Prints the current input position and the change (delta) in position
local function printMovement(input)
print("Position:", input.Position)
print("Movement Delta:", input.Delta)
end
-- A sample function providing multiple usage cases for various types of user input
local function InputChanged(input, _gameProcessed)
if input.UserInputType == Enum.UserInputType.MouseMovement then
print("The mouse has been moved!")
printMovement(input)
elseif input.UserInputType == Enum.UserInputType.MouseWheel then
print("The mouse wheel has been scrolled!")
print("Wheel Movement:", input.Position.Z)
elseif input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.Thumbstick1 then
print("The left thumbstick has been moved!")
printMovement(input)
elseif input.KeyCode == Enum.KeyCode.Thumbstick2 then
print("The right thumbstick has been moved!")
printMovement(input)
elseif input.KeyCode == Enum.KeyCode.ButtonL2 then
print("The pressure being applied to the left trigger has changed!")
print("Pressure:", input.Position.Z)
elseif input.KeyCode == Enum.KeyCode.ButtonR2 then
print("The pressure being applied to the right trigger has changed!")
print("Pressure:", input.Position.Z)
end
elseif input.UserInputType == Enum.UserInputType.Touch then
print("The user's finger is moving on the screen!")
printMovement(input)
elseif input.UserInputType == Enum.UserInputType.Gyro then
local _rotInput, rotCFrame = UserInputService:GetDeviceRotation()
local rotX, rotY, rotZ = rotCFrame:toEulerAnglesXYZ()
local rot = Vector3.new(math.deg(rotX), math.deg(rotY), math.deg(rotZ))
print("The rotation of the user's mobile device has been changed!")
print("Position", rotCFrame.p)
print("Rotation:", rot)
elseif input.UserInputType == Enum.UserInputType.Accelerometer then
print("The acceleration of the user's mobile device has been changed!")
printMovement(input)
end
end
UserInputService.InputChanged:Connect(InputChanged)

InputEnded

輸入已結束事件會在使用者停止使用人工智慧與電腦介面裝置(鼠標向下、觸摸開始、鍵盤向下等)互動時發生。當跟蹤用戶釋放鍵盤按鍵、滑鼠按鍵、觸摸輸入等時,這很有用。

這個事件可以與 UserInputService.InputBeganUserInputService.InputChanged 一起使用,來跟蹤用戶輸入開始、變更和結束的時間。

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The following example demonstrates one of many usage examples of handling user input from InputEnded depending on its type.

Handling InputEnded

-- In order to use the InputChanged event, the UserInputService service must be used
local UserInputService = game:GetService("UserInputService")
-- A sample function providing multiple usage cases for various types of user input
UserInputService.InputEnded:Connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard then
print("A key has been released! Key:", input.KeyCode)
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
print("The left mouse button has been released at", input.Position)
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
print("The right mouse button has been released at", input.Position)
elseif input.UserInputType == Enum.UserInputType.Touch then
print("A touchscreen input has been released at", input.Position)
elseif input.UserInputType == Enum.UserInputType.Gamepad1 then
print("A button has been released on a gamepad! Button:", input.KeyCode)
end
if gameProcessed then
print("The game engine internally observed this input!")
else
print("The game engine did not internally observe this input!")
end
end)

JumpRequest

當從客戶端傳送跳躍請求時,UserInputService事件會發生,例如當客戶端按下空格鍵或跳躍按鈕時。

這個事件會在使用者嘗試使用 Player.Character 跳躍時發生。預設行為會回應跳躍請求,設置玩家的 Humanoid.Jump 屬性為真值,使玩家的角色跳躍。

事件可用於追蹤玩家每次想跳躍的時間。而不是使用它來讓玩家跳躍,這應該用於更改預設跳躍行為 - 例如禁用跳躍。

例如,下面的代碼每次玩家發送跳躍請邀請時都會打印「跳躍」。


local UserInputService = game:GetService("UserInputService")
function onJumpRequest()
print("Jump!")
end
UserInputService.JumpRequest:Connect(onJumpRequest)

由於此事件會為單次跳躍邀請發射多次,因此建議使用 延遲 來使用。

如果您想將鍵或按鈕連接到其他操作,請考慮使用事件,例如 UserInputService:GetKeysPressed()UserInputService.InputBeganContextActionService

由於此事件只在本地發射,因此只能在 LocalScript 中使用。


範例程式碼

This code sample disables jumping for the LocalPlayer by setting the Enum.HumanoidStateType.Jumping state to false. Setting this state to false as soon as the user tries to jump cancels the jump.

In order for this example to work as expected, it should be placed in a LocalScript.

Disable Jumping

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
-- Fires when the user tries to jump
local function jump()
humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
end
UserInputService.JumpRequest:Connect(jump)

LastInputTypeChanged

客戶端每次變更如何通過人工智能/電腦介面裝置進行互動時,都會發出 UserInputService.LastInputTypeChanged 事件。(i.e.從滑鼠移動到滑鼠輪或從拇指棒1到拇指棒2)。

若要取得最後一個輸入類型的值,無論它是否已變更,您可以使用 UserInputService:GetLastInputType() 函數。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

參數

lastInputType: Enum.UserInputType

一個 Enum.UserInputType 指示最後一種輸入類型。


範例程式碼

This example hides the mouse icon while the player beings using their keyboard, such as to chat or enter text into a TextBox. The mouse icon reappears when the user resumes mouse input.

This uses the LastInputType() event to determine when the user begins keyboard input and mouse input - based on the value of the lastInputType argument.

In order for this example to work as expected, it should be placed in a LocalScript.

Hide Mouse During Keyboard Input

local UserInputService = game:GetService("UserInputService")
local mouseInput = {
Enum.UserInputType.MouseButton1,
Enum.UserInputType.MouseButton2,
Enum.UserInputType.MouseButton3,
Enum.UserInputType.MouseMovement,
Enum.UserInputType.MouseWheel,
}
local keyboard = Enum.UserInputType.Keyboard
local function toggleMouse(lastInputType)
if lastInputType == keyboard then
UserInputService.MouseIconEnabled = false
return
end
for _, mouse in pairs(mouseInput) do
if lastInputType == mouse then
UserInputService.MouseIconEnabled = true
return
end
end
end
UserInputService.LastInputTypeChanged:Connect(toggleMouse)

PointerAction

指標操作 在使用者執行特定指標操動作時發生。例如,滚动鼠标轮。

參數

wheel: number
pan: Vector2
pinch: number
gameProcessedEvent: boolean

TextBoxFocusReleased

當客戶失去對 的焦點時,事件會發生,通常是當客戶按下返回鍵或點擊/觸碰屏幕上的其他地方停止輸入文字時。

例如,下面的代碼會列印事件發生時失去焦點的 TextBox 名稱。


local UserInputService = game:GetService("UserInputService")
function TextBoxFocusReleased(textbox)
print(textbox.Name)
end
UserInputService.TextBoxFocusReleased:Connect(TextBoxFocusReleased)

它可以與 UserInputService.TextBoxFocused 一起使用,來跟蹤當 TextBox 獲得和失去焦點時。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見「也見」

參數

textboxReleased: TextBox

那個 TextBox 失去了焦點。


TextBoxFocused

當使用者在 TextBox 上獲得焦點時,此事件會發生,通常是當使用者單擊/點擊文字框以開始輸入文字時。這也會在使用 TextBox:CaptureFocus() 導入文字框焦點時發生。

例如,下面的代碼會列印當事件發生時聚焦的 TextBox 名稱。


local UserInputService = game:GetService("UserInputService")
function TextBoxFocused(textbox)
print(textbox.Name)
end)
UserInputService.TextBoxFocused:Connect(TextBoxFocused)

它可以與 UserInputService.FocusReleased 一起使用,當文字框獲得和失去焦點時跟蹤。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見「也見」

參數

textboxFocused: TextBox

獲得焦點的 TextBox


TouchDrag

參數

dragDirection: Enum.SwipeDirection
numberOfTouches: number
gameProcessedEvent: boolean

TouchEnded

當使用者從啟用觸碰的裝置的螢幕釋放手指時,觸碰結束事件發生,使用裝置結束觸碰輸入。

這個事件可以用來確定使用者何時停止觸碰裝置的螢幕。它可以與 UserInputService.TouchStarted 配對,以決定用戶何時開始和停止觸碰屏幕。

例如,下面的代碼會列印使用者停止觸碰螢幕的屏幕位置。


local UserInputService = game:GetService("UserInputService")
function TouchEnded(touch, gameProcessedEvent)
print("Touch ended at " .. tostring(touch.Position))
end
UserInputService.TouchEnded:Connect(TouchEnded)

觸摸輸入對象在觸摸期間的所有時間都相同的輸入對象。因此,比較 InputObjects 當它們是觸摸對象時是有效的,以確定它們是否相同的手指。

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The code sample below demonstrates the difference between a TouchTap() and TouchLongPress() by creating a GuiObject|GUI Frame that appears when user touches the screen of their device and disappears when the Class.UserInputEvent.TouchEnded|touch ends. When the long press event fires, the GUI doubles in size. Also, the GUI moves to stay centered under the user's finger when the player moves their finger.

In order for the TouchLongPress() to fire, the user touch the screen and hold their finger still for a short period of time. Once the touch moves, the long press event will not fire.

In order for the example to work as expected, it should be placed in a LocalScript that is parented to a ScreenGui.

The Difference Between TouchTap and TouchLongPress

local UserInputService = game:GetService("UserInputService")
-- The parent of this script (a ScreenGui)
local touchScreenGui = script.Parent
-- Create the GUI frame that the user interacts with through Touch
-- events
local touchGui = Instance.new("Frame")
touchGui.Name = "TouchGui"
touchGui.AnchorPoint = Vector2.new(0.5, 0.5)
-- Fires when the touches their device's screen
local function TouchTap(touchPositions, _gameProcessedEvent)
touchGui.Parent = touchScreenGui
touchGui.Position = UDim2.new(0, touchPositions[1].X, 0, touchPositions[1].Y)
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Fires when a user starts touching their device's screen and does not
-- move their finger for a short period of time
local function TouchLong(_touchPositions, _state, _gameProcessedEvent)
touchGui.Size = UDim2.new(0, 100, 0, 100)
end
-- Fires when the user moves their finger while touching their device's
-- screen
local function TouchMove(touch, _gameProcessedEvent)
touchGui.Position = UDim2.new(0, touch.Position.X, 0, touch.Position.Y)
end
-- Fires when the user stops touching their device's screen
local function TouchEnd(_touch, _gameProcessedEvent)
touchGui.Parent = nil
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Only use the Touch events if the user is on a mobile device
if UserInputService.TouchEnabled then
UserInputService.TouchTap:Connect(TouchTap)
UserInputService.TouchLongPress:Connect(TouchLong)
UserInputService.TouchMoved:Connect(TouchMove)
UserInputService.TouchEnded:Connect(TouchEnd)
end

TouchLongPress

當使用者按住至少一個手指,在相同的觸摸啟用裝置的屏幕位置上短時間時,發射。

這個事件可以用來確定用戶何時按住鍵在遊戲中的 GuiObject 或元素。

下面的例子印出使用者按住至少一個手指,在同一個畫面位置短時間內的長按 state 。可能的狀態包括:開始變更結束取消


local UserInputService = game:GetService("UserInputService")
function TouchLongPress(TouchPositions, state, gameProcessedEvent)
print("Long press event fired. State of press: " .. tostring(state))
end
UserInputService.TouchLongPress:Connect(TouchLongPress)

要檢查使用者的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱UserInputService.TouchEnabled

它可以與 UserInputService.TouchStartedUserInputService.TouchEnded 配對,以決定用戶何時開始和停止觸碰屏幕。

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

touchPositions: Array

一個由 Vector2 個對象組成的陣列,指示涉及手勢的手指位置。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The code sample below demonstrates the difference between a TouchTap() and TouchLongPress() by creating a GuiObject|GUI Frame that appears when user touches the screen of their device and disappears when the Class.UserInputEvent.TouchEnded|touch ends. When the long press event fires, the GUI doubles in size. Also, the GUI moves to stay centered under the user's finger when the player moves their finger.

In order for the TouchLongPress() to fire, the user touch the screen and hold their finger still for a short period of time. Once the touch moves, the long press event will not fire.

In order for the example to work as expected, it should be placed in a LocalScript that is parented to a ScreenGui.

The Difference Between TouchTap and TouchLongPress

local UserInputService = game:GetService("UserInputService")
-- The parent of this script (a ScreenGui)
local touchScreenGui = script.Parent
-- Create the GUI frame that the user interacts with through Touch
-- events
local touchGui = Instance.new("Frame")
touchGui.Name = "TouchGui"
touchGui.AnchorPoint = Vector2.new(0.5, 0.5)
-- Fires when the touches their device's screen
local function TouchTap(touchPositions, _gameProcessedEvent)
touchGui.Parent = touchScreenGui
touchGui.Position = UDim2.new(0, touchPositions[1].X, 0, touchPositions[1].Y)
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Fires when a user starts touching their device's screen and does not
-- move their finger for a short period of time
local function TouchLong(_touchPositions, _state, _gameProcessedEvent)
touchGui.Size = UDim2.new(0, 100, 0, 100)
end
-- Fires when the user moves their finger while touching their device's
-- screen
local function TouchMove(touch, _gameProcessedEvent)
touchGui.Position = UDim2.new(0, touch.Position.X, 0, touch.Position.Y)
end
-- Fires when the user stops touching their device's screen
local function TouchEnd(_touch, _gameProcessedEvent)
touchGui.Parent = nil
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Only use the Touch events if the user is on a mobile device
if UserInputService.TouchEnabled then
UserInputService.TouchTap:Connect(TouchTap)
UserInputService.TouchLongPress:Connect(TouchLong)
UserInputService.TouchMoved:Connect(TouchMove)
UserInputService.TouchEnded:Connect(TouchEnd)
end

TouchMoved

當使用者在 TouchEnabled 裝置上移動手指時發生火災,例如平板電腦或智慧型手機。

這個事件有助於追蹤使用者是否移動手指到螢幕上,以及使用者移動手指的位置。

下面的代碼顯示觸摸從以前的位置移動到 TouchEnabled 裝置上的新位置。請注意,傳遞的 InputObject.Position 參數上的 touchVector3 ,但只包含 X 和 Y 坐標;Z 總是為 0。


local UserInputService = game:GetService("UserInputService")
function onTouchMoved(touch, gameProcessedEvent)
local oldPosition = touch.Position - touch.Delta
print("Touch moved from " .. tostring(oldPosition) .. " to " .. tostring(touch.Position))
end
UserInputService.TouchMoved:Connect(onTouchMoved)

UserInputService.TouchStartedUserInputService.TouchEnded 配對此事件以確定用戶開始觸摸屏幕的時間、觸摸時手指移動的時間以及停止觸摸屏幕的時間。

要檢查用戶的裝置是否支持觸摸和觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The code sample below demonstrates the difference between a TouchTap() and TouchLongPress() by creating a GuiObject|GUI Frame that appears when user touches the screen of their device and disappears when the Class.UserInputEvent.TouchEnded|touch ends. When the long press event fires, the GUI doubles in size. Also, the GUI moves to stay centered under the user's finger when the player moves their finger.

In order for the TouchLongPress() to fire, the user touch the screen and hold their finger still for a short period of time. Once the touch moves, the long press event will not fire.

In order for the example to work as expected, it should be placed in a LocalScript that is parented to a ScreenGui.

The Difference Between TouchTap and TouchLongPress

local UserInputService = game:GetService("UserInputService")
-- The parent of this script (a ScreenGui)
local touchScreenGui = script.Parent
-- Create the GUI frame that the user interacts with through Touch
-- events
local touchGui = Instance.new("Frame")
touchGui.Name = "TouchGui"
touchGui.AnchorPoint = Vector2.new(0.5, 0.5)
-- Fires when the touches their device's screen
local function TouchTap(touchPositions, _gameProcessedEvent)
touchGui.Parent = touchScreenGui
touchGui.Position = UDim2.new(0, touchPositions[1].X, 0, touchPositions[1].Y)
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Fires when a user starts touching their device's screen and does not
-- move their finger for a short period of time
local function TouchLong(_touchPositions, _state, _gameProcessedEvent)
touchGui.Size = UDim2.new(0, 100, 0, 100)
end
-- Fires when the user moves their finger while touching their device's
-- screen
local function TouchMove(touch, _gameProcessedEvent)
touchGui.Position = UDim2.new(0, touch.Position.X, 0, touch.Position.Y)
end
-- Fires when the user stops touching their device's screen
local function TouchEnd(_touch, _gameProcessedEvent)
touchGui.Parent = nil
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Only use the Touch events if the user is on a mobile device
if UserInputService.TouchEnabled then
UserInputService.TouchTap:Connect(TouchTap)
UserInputService.TouchLongPress:Connect(TouchLong)
UserInputService.TouchMoved:Connect(TouchMove)
UserInputService.TouchEnded:Connect(TouchEnd)
end

TouchPan

觸摸板事件會在使用者拖曳至少一根手指到TouchEnabled裝置時發生。

這個事件可以用來確定使用者何時在觸摸啟用裝置的螢幕上移動手指--例如,在自訂相機腳指令碼中旋轉 Camera

下面的代碼列印「觸碰速度拖動」,隨後是用戶將手指拖到屏幕上時的速度。


local UserInputService = game:GetService("UserInputService")
UserInputService.TouchPan:Connect(function(touchPositions, totalTranslation, velocity, state, gameProcessedEvent)
print("Speed of touch drag: " .. tostring(velocity))
end)

看看另一個有用的 UserInputService 功能在這裡 UserInputService.TouchRotate

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

touchPositions: Array

一個由 Vector2 個物件組成的陣列,指示涉及手勢的觸碰位置 (例如手指)。

totalTranslation: Vector2

從開始到結束的平底鍋動作的尺寸 (以像素計)。

velocity: Vector2

每秒鐘的平底鍋動作速度 (以像素計)。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

TouchPinch

當使用者在 TouchEnabled 裝置的屏幕上放置並移動兩個手指時,發射時。

例個體、實例,下面的代碼列印了鏡頭縮放比例在觸摸捏動開始時與之前的變化量。


local UserInputService = game:GetService("UserInputService")
UserInputService.TouchPinch:Connect(function(touchPositions, scale, velocity, state, gameProcessedEvent)
print("Scale difference since beginning of pinch: " .. tostring(scale))
end)

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

touchPositions: Array

一個由 Vector2s 組成的陣列,表示捏造手勢涉及的手指屏幕位置,以像素為單位。

scale: number

從開始到結束的按壓強度(以像素計)除以開始按壓位置。

velocity: number

按下按鍵的速度(以像素為單位)每秒。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

TouchRotate

觸摸旋轉事件會在使用者在 TouchEnabled 裝置上旋轉兩個手指時發生。

例如,下面的代碼列出了相機在觸摸旋轉開始時旋轉了多少。


local UserInputService = game:GetService("UserInputService")
UserInputService.TouchRotate:Connect(function(touchPositions, rotation, velocity, state, gameProcessedEvent)
print("Camera has rotated " .. tostring(rotation) .. " degrees!")
end)

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

在移動設備上控制使用者相機的核心腳本使用與此事件相似的功能代碼。對於此事件的最佳做法是在創建移動攝影機系統時使用它來覆蓋預設核心腳本。

也見:

參數

touchPositions: Array

一個由 Vector2s 組成的陣列,表示涉及手勢的手指位置。

rotation: number

姿勢旋轉以來的度數。

velocity: number

旋轉變更 (以度計) 除以變更持續時間 (以秒計)。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

By default, Roblox relies on a LocalScript to control the user's camera. However, this script can be overridden with a custom CameraScript. The example below demonstrates how to create a custom script to control the user's camera using many of the UserInputService events.

The script is broken into two parts:

  1. Mobile camera events, which rely on touch events
  2. Non-mobile camera events, which rely on keyboard input and tracking the user's movement

First, the camera script needs utility functions to setup the camera and set its Camera.CameraType to Scriptable so that the script can control the camera. It also needs a function to update the camera when it moves, rotates, and zooms.

Using touch events allows us to track user input as they interact with the touchscreen on their mobile device. These events allow us to handle camera movement, rotation, and zoom.

The second half of the code sample adds camera support for players on desktop devices. When input begans, the function Input() checks that the state of the input is Enum.UserInputState.Begin to ignore all keypress inputs other than when the user first presses a key down. When the user presses I and O the camera zooms in and out. When the presses down and moves their left mouse button, the script locks the player's mouse by changing the UserInputService.MouseBehavior property. The camera rotates according to the mouse's change in screen position. When the player moves their character, the camera moves with them.

All of the parts discussed above are combined and shown in the code sample below.

Create a Custom CameraScript

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local playerPosition = torso.Position
local default_CameraPosition = torso.Position
local default_CameraRotation = Vector2.new(0, math.rad(-60))
local default_CameraZoom = 15
local cameraPosition = default_CameraPosition
local cameraRotation = default_CameraRotation
local cameraZoom = default_CameraZoom
local cameraZoomBounds = nil -- {10,200}
local cameraRotateSpeed = 10
local cameraMouseRotateSpeed = 0.25
local cameraTouchRotateSpeed = 10
local function SetCameraMode()
camera.CameraType = "Scriptable"
camera.FieldOfView = 80
camera.CameraSubject = nil
end
local function UpdateCamera()
SetCameraMode()
local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) * CFrame.Angles(cameraRotation.Y, 0, 0)
camera.CFrame = cameraRotationCFrame + cameraPosition + cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)
camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end
local lastTouchTranslation = nil
local function TouchMove(_touchPositions, totalTranslation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = totalTranslation - lastTouchTranslation
cameraPosition = cameraPosition + Vector3.new(difference.X, 0, difference.Y)
UpdateCamera()
end
lastTouchTranslation = totalTranslation
end
local lastTouchRotation = nil
local function TouchRotate(_touchPositions, rotation, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = rotation - lastTouchRotation
cameraRotation = cameraRotation
+ Vector2.new(-difference, 0) * math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)
UpdateCamera()
end
lastTouchRotation = rotation
end
local lastTouchScale = nil
local function TouchZoom(_touchPositions, scale, _velocity, state)
if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
local difference = scale - lastTouchScale
cameraZoom = cameraZoom * (1 + difference)
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
lastTouchScale = scale
end
local function Input(inputObject)
if inputObject.UserInputType == Enum.UserInputType.Keyboard then
if inputObject.UserInputState == Enum.UserInputState.Begin then
-- (I) Zoom In
if inputObject.KeyCode == Enum.KeyCode.I then
cameraZoom = cameraZoom - 15
elseif inputObject.KeyCode == Enum.KeyCode.O then
cameraZoom = cameraZoom + 15
end
-- (O) Zoom Out
if cameraZoomBounds ~= nil then
cameraZoom = math.min(math.max(cameraZoom, cameraZoomBounds[1]), cameraZoomBounds[2])
else
cameraZoom = math.max(cameraZoom, 0)
end
UpdateCamera()
end
end
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
if pressed then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
local rotation = UserInputService:GetMouseDelta()
cameraRotation = cameraRotation + rotation * math.rad(cameraMouseRotateSpeed)
else
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
local function PlayerChanged()
local movement = torso.Position - playerPosition
cameraPosition = cameraPosition + movement
playerPosition = torso.Position
UpdateCamera()
end
-- Determine whether the user is on a mobile device
if UserInputService.TouchEnabled then
-- The user is on a mobile device, use Touch events
UserInputService.TouchPan:Connect(TouchMove)
UserInputService.TouchRotate:Connect(TouchRotate)
UserInputService.TouchPinch:Connect(TouchZoom)
else
-- The user is not on a mobile device use Input events
UserInputService.InputBegan:Connect(Input)
UserInputService.InputChanged:Connect(Input)
UserInputService.InputEnded:Connect(Input)
-- Camera controlled by player movement
task.wait(2)
RunService:BindToRenderStep("PlayerChanged", Enum.RenderPriority.Camera.Value - 1, PlayerChanged)
end

TouchStarted

當使用者將手指放置在 TouchEnabled 裝置上時,觸碰開始事件會發生,開始使用裝置進行觸碰輸入。

這個事件可以用來確定使用者何時開始觸摸其裝置的螢幕。它可以與 UserInputService.TouchEnded 配對,以決定用戶何時開始和停止觸碰屏幕。

觸摸輸入對象在觸摸期間的所有時間都相同的輸入對象。因此,比較 InputObjects 當它們是觸摸對象時是有效的,以確定它們是否相同的手指。

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

包含用戶輸入信息的 InputObject 個體、實例例。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

This example demonstrates how to use touch input events to drag a GUI element while a player touches and drags across their screen.

The touch InputObject is the same input object throughout the lifetime of the touch. So comparing input objects when they are touch objects is valid to determine if it is the same touch as the input starts, changes, and ends.

The example starts tracking a drag once the touch is registered by the TouchStarted() event. It continues to update as that touch moves, tracking its position relative to start position to move a GUI until a TouchEvent event fires for that touch.

Tracking Touches

local UserInputService = game:GetService("UserInputService")
local dragging
local dragInput
local dragStart
local startPos
local gui = script.Parent
local function touchStarted(input, _gameProcessed)
if not dragging then
dragging = true
dragInput = input
dragStart = input.Position
startPos = gui.Position
end
end
local function update(input, _gameProcessed)
if input == dragInput and dragging then
local delta = input.Position - dragStart
gui.Position =
UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
end
local function touchEnded(input, _gameProcessed)
if input == dragInput then
dragging = false
end
end
UserInputService.TouchStarted:Connect(touchStarted)
UserInputService.TouchMoved:Connect(update)
UserInputService.TouchEnded:Connect(touchEnded)

TouchSwipe

當使用者在設備上滑動手指時,TouchSwipe會發生,當滑動手指時,TouchEnabled會發生。

這個事件可以用來確定使用者在裝置的屏幕上滑動手指的時間和方向,以及使用者滑動的方向。

若要更精確地追蹤觸摸輸入運動,請使用 UserInputService.TouchMoved

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

也見:

參數

swipeDirection: Enum.SwipeDirection

一個 Enum.SwipeDirection ,指示使用者滑動的方向。

numberOfTouches: number

參與手勢的觸摸次數(例如手指)。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The example below demonstrates the TouchSwipe() event by tweening a GuiObject|GUI element's position 100 pixels in the direction of the swipe according to the value of the swipeDirection argument.

In order for this example to work as expected, it must be placed in a LocalScript that is parented to the gui being swiped.

Touch Swipe a GUI

local UserInputService = game:GetService("UserInputService")
local gui = script.Parent
local swipePositionY = gui.Position.Y.Offset
local swipePositionX = gui.Position.X.Offset
local camera = workspace.CurrentCamera
local maxY = camera.ViewportSize.Y - gui.Size.Y.Offset
local maxX = camera.ViewportSize.X - gui.Size.X.Offset
local function TouchSwipe(swipeDirection, _numberOfTouches, _gameProcessedEvent)
if swipeDirection == Enum.SwipeDirection.Up then
swipePositionY = math.max(swipePositionY - 200, 0)
elseif swipeDirection == Enum.SwipeDirection.Down then
swipePositionY = math.min(swipePositionY + 200, maxY)
elseif swipeDirection == Enum.SwipeDirection.Left then
swipePositionX = math.max(swipePositionX - 200, 0)
elseif swipeDirection == Enum.SwipeDirection.Right then
swipePositionX = math.min(swipePositionX + 200, maxX)
end
gui:TweenPosition(UDim2.new(0, swipePositionX, 0, swipePositionY), "Out", "Quad", 0.25, true)
end
UserInputService.TouchSwipe:Connect(TouchSwipe)

TouchTap

觸摸事件在 TouchEnabled 裝置上的屏幕上觸碰/點擊用戶手指時發生。

此事件無論使用者是否觸碰/點擊遊戲世界或 GuiObject 元素都會發生。如果您只想找到一個事件,只有當使用者觸碰/點擊遊戲世界時才會發生,請使用 UserInputService.TouchTapInWorld

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。

參數

touchPositions: Array

一個由 Vector2 個對象組成的陣列,指示涉及點擊動作的手指位置。

gameProcessedEvent: boolean

指示遊戲引擎是否內部觀察到此輸入並對其進行操作。一般來說,這指的是使用者介面處理,因此如果從此輸入按下或單擊按鈕,gameProcessedEvent將是true。這也適用於透過 ContextActionService 連接的輸入事件。


範例程式碼

The code sample below demonstrates the difference between a TouchTap() and TouchLongPress() by creating a GuiObject|GUI Frame that appears when user touches the screen of their device and disappears when the Class.UserInputEvent.TouchEnded|touch ends. When the long press event fires, the GUI doubles in size. Also, the GUI moves to stay centered under the user's finger when the player moves their finger.

In order for the TouchLongPress() to fire, the user touch the screen and hold their finger still for a short period of time. Once the touch moves, the long press event will not fire.

In order for the example to work as expected, it should be placed in a LocalScript that is parented to a ScreenGui.

The Difference Between TouchTap and TouchLongPress

local UserInputService = game:GetService("UserInputService")
-- The parent of this script (a ScreenGui)
local touchScreenGui = script.Parent
-- Create the GUI frame that the user interacts with through Touch
-- events
local touchGui = Instance.new("Frame")
touchGui.Name = "TouchGui"
touchGui.AnchorPoint = Vector2.new(0.5, 0.5)
-- Fires when the touches their device's screen
local function TouchTap(touchPositions, _gameProcessedEvent)
touchGui.Parent = touchScreenGui
touchGui.Position = UDim2.new(0, touchPositions[1].X, 0, touchPositions[1].Y)
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Fires when a user starts touching their device's screen and does not
-- move their finger for a short period of time
local function TouchLong(_touchPositions, _state, _gameProcessedEvent)
touchGui.Size = UDim2.new(0, 100, 0, 100)
end
-- Fires when the user moves their finger while touching their device's
-- screen
local function TouchMove(touch, _gameProcessedEvent)
touchGui.Position = UDim2.new(0, touch.Position.X, 0, touch.Position.Y)
end
-- Fires when the user stops touching their device's screen
local function TouchEnd(_touch, _gameProcessedEvent)
touchGui.Parent = nil
touchGui.Size = UDim2.new(0, 50, 0, 50)
end
-- Only use the Touch events if the user is on a mobile device
if UserInputService.TouchEnabled then
UserInputService.TouchTap:Connect(TouchTap)
UserInputService.TouchLongPress:Connect(TouchLong)
UserInputService.TouchMoved:Connect(TouchMove)
UserInputService.TouchEnded:Connect(TouchEnd)
end

TouchTapInWorld

觸摸世界事件在 TouchEnabled 裝置上的屏幕上觸摸/點擊用戶的手指時發生。當使用者點擊遊戲世界時,它會被發射。

這個事件可以用來確定用戶點擊屏幕時是否沒有點擊 GuiObject 元素。如果使用者點擊 GUI 元素,UserInputService.TouchTap會發射,而不是 TouchTapInWorld。

要檢查用戶的裝置是否啟用觸摸,以及觸摸事件是否會發觸發,請參閱 UserInputService.TouchEnabled

此事件只在 Roblox 客戶端窗口處於焦點時發生。例如,當窗口縮小時,輸入將不會被捕捉。

因為只能在本地發射,所以只能在 LocalScript 中使用。

也見:

參數

position: Vector2

Vector2 指示觸摸位置。

processedByUI: boolean

使用者點擊了GUI元素嗎。


範例程式碼

This example uses the Vector2 position passed by TouchTapInWorld() to find the Vector3 world position the user tapped. Then, the code spawns an anchored BasePart|Part at the world position.

In order to calculate the Vector3 world position using the viewport position, this example generates a Ray called unitRay originating from position using the ViewportPointToRay() function. Then, since ViewportPointToRay() creates a unit ray that is only 1 stud long, the example uses it to create a longer ray that is length studs long. Using FindPartOnRay(), the code determines where the ray first intersects a part in the world - the Vector3 world position that the user tapped.

Note that the code sample will not spawn a part if the user touches on the screen over an empty skybox. The touch must be on a part for FindPartOnRay() to return a Vector3 position.

Create a Part in World at Touch Position

local UserInputService = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local LENGTH = 500
local function createPart(position, processedByUI)
-- Do not create a part if the player clicked on a GUI/UI element
if processedByUI then
return
end
-- Get Vector3 world position from the Vector2 viewport position
local unitRay = camera:ViewportPointToRay(position.X, position.Y)
local ray = Ray.new(unitRay.Origin, unitRay.Direction * LENGTH)
local hitPart, worldPosition = workspace:FindPartOnRay(ray)
-- Create a new part at the world position if the player clicked on a part
-- Do not create a new part if player clicks on empty skybox
if hitPart then
local part = Instance.new("Part")
part.Parent = workspace
part.Anchored = true
part.Size = Vector3.new(1, 1, 1)
part.Position = worldPosition
end
end
UserInputService.TouchTapInWorld:Connect(createPart)

WindowFocusReleased

當 Roblox 客戶端的窗口失去焦點時,UserInputService事件會發生,通常是當使用者將 Roblox 客戶端最小化時。

例如,下面的代碼會在 Roblox 客戶端失去焦點時打印 「窗口聚焦已釋放」


local UserInputService = game:GetService("UserInputService")
UserInputService.WindowFocusReleased:Connect(function()
print("Window focus released")
end)

這個事件可以與 UserInputService.WindowFocused 一起使用,來跟蹤 Roblox 客戶是否正在積極關注使用者的屏幕。

由於只能在本地發射,因此只能在 LocalScript 中使用。


範例程式碼

This example fires a RemoveEvent to the server name AfkEvent when the LocalPlayer's client gains or loses focus.

The purpose of this code sample is to fire a server-side event to indicate when the player is AFK. This is indicated by spawning a ForceField around the player when the client loses focus and destroying the forcefield when the client gains focus.

In order for this example to work as expected, the code labelled LocalScript must be placed in a LocalScript and the code labelled Script must be placed in a Script. This sample is a Script which should be run in conjunction with the LocalScript code sample: Window Focus AFK Script (LocalScript)

Window Focus AFK Script (Script)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = Instance.new("RemoteEvent")
afkEvent.Name = "AfkEvent"
afkEvent.Parent = ReplicatedStorage
local function setAfk(player, afk)
if afk then
local forcefield = Instance.new("ForceField")
forcefield.Parent = player.Character
else
local forcefield = player.Character:FindFirstChildOfClass("ForceField")
if forcefield then
forcefield:Destroy()
end
end
end
afkEvent.OnServerEvent:Connect(setAfk)

This sample is a LocalScript which should be run in conjunction with the Script code sample: Window Focus AFK Script (Script)

Window Focus AFK Script (LocalScript)

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = ReplicatedStorage:WaitForChild("AfkEvent")
local function focusGained()
afkEvent:FireServer(false)
end
local function focusReleased()
afkEvent:FireServer(true)
end
UserInputService.WindowFocused:Connect(focusGained)
UserInputService.WindowFocusReleased:Connect(focusReleased)

WindowFocused

當 Roblox 客戶端的窗口獲得焦點時,窗口聚焦事件會發生,通常是當 Roblox 客戶端在使用者的屏幕上最大化/開啟時。

例如,下面的代碼會在 Roblox 客戶端獲得焦點時打印 「專注於窗口」


local UserInputService = game:GetService("UserInputService")
UserInputService.WindowFocused:Connect(function()
print("Window focused")
end)

這個事件可以與 UserInputService.WindowFocusReleased 一起使用,來跟蹤 Roblox 客戶是否正在積極關注使用者的屏幕。

由於此事件只在本地發射,因此只能在 LocalScript 中使用。


範例程式碼

This example fires a RemoveEvent to the server name AfkEvent when the LocalPlayer's client gains or loses focus.

The purpose of this code sample is to fire a server-side event to indicate when the player is AFK. This is indicated by spawning a ForceField around the player when the client loses focus and destroying the forcefield when the client gains focus.

In order for this example to work as expected, the code labelled LocalScript must be placed in a LocalScript and the code labelled Script must be placed in a Script. This sample is a Script which should be run in conjunction with the LocalScript code sample: Window Focus AFK Script (LocalScript)

Window Focus AFK Script (Script)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = Instance.new("RemoteEvent")
afkEvent.Name = "AfkEvent"
afkEvent.Parent = ReplicatedStorage
local function setAfk(player, afk)
if afk then
local forcefield = Instance.new("ForceField")
forcefield.Parent = player.Character
else
local forcefield = player.Character:FindFirstChildOfClass("ForceField")
if forcefield then
forcefield:Destroy()
end
end
end
afkEvent.OnServerEvent:Connect(setAfk)

This sample is a LocalScript which should be run in conjunction with the Script code sample: Window Focus AFK Script (Script)

Window Focus AFK Script (LocalScript)

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = ReplicatedStorage:WaitForChild("AfkEvent")
local function focusGained()
afkEvent:FireServer(false)
end
local function focusReleased()
afkEvent:FireServer(true)
end
UserInputService.WindowFocused:Connect(focusGained)
UserInputService.WindowFocusReleased:Connect(focusReleased)