Gamepad Haptic Feedback
Gamepad Haptic Feedback
The Xbox One controller and some other USB gamepad controllers have motors built in to provide haptic feedback. Adding rumbles and vibrations can greatly enhance a game’s experience and provide subtle feedback that is hard to convey through visuals or audio. Roblox provides a service to developers called the
HapticService to handle haptic feedback.
Checking for Vibration Support
Not all controllers support vibration so it is important to check if the plugged-in controllers have support before attempting to use the ClassLink|HapticService. To check if a given controller has rumble support at all, you can call
local HapticService = game:GetService("HapticService") local isVibrationSupported = HapticService:IsVibrationSupported(Enum.UserInputType.Gamepad1)
Once you have checked if a gamepad supports vibration, you should also check if it supports the motors you intend to use. On XBox One the controller has 4 motors:
- Large: in the left side of the controller. Good for generic rumble.
- Small: in the right side of the controller. Good for more subtle rumbles(tire slipping, electric shock, etc.)
- Left Trigger: underneath the left trigger. Good for braking, gun reloading, etc.
- Right Trigger: underneath the right trigger. Good for recoil, acceleration, etc.
On PC you will have less guarantee of what kind of controller the user has. Many only support the Large and Small motors (no triggers). You can use
HapticService/IsMotorSupported to see if the user’s controller supports the motor you want to use.
local HapticService = game:GetService("HapticService") local isVibrationSupported = HapticService:IsVibrationSupported(Enum.UserInputType.Gamepad1) local largeSupported = false if isVibrationSupported then largeSupported = HapticService:IsMotorSupported(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large) end
Turning on Motors
Once you have confirmed that a user’s gamepad supports vibration you can start using the gamepad motors. You can use
HapticService/SetMotor to turn on a specific motor on a gamepad. This function takes the gamepad and the amplitude of the vibration as arguments. The amplitude can be any value between 0 and 1 (0 being no vibration, 1 being max vibration).
local HapticService = game:GetService("HapticService") HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large, .5)
You can also use
HapticService/GetMotor to get the current vibration amplitude of a given motor.
local HapticService = game:GetService("HapticService") print(HapticService:GetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Large)
-- Services local HapticService = game:GetService("HapticService") local Players = game:GetService("Players") local RunService = game:GetService("RunService") -- Make sure we are running in a LocalScript. local player = Players.LocalPlayer assert(player,"This should be running in a LocalScript!") -- Setup Haptic Feedback Listener local function updateHapticFeedback() -- Check if we currently have a character. local character = player.Character if character then -- Do we have a Humanoid? local humanoid = character:FindFirstChildOfClass("Humanoid") if humanoid then -- Are we in a vehicle seat? local seatPart = humanoid.SeatPart if seatPart and seatPart:IsA("VehicleSeat") then -- Measure the current speed of the vehicle by taking the magnitude of the seat's velocity. local speed = seatPart.Velocity.Magnitude -- Measure the current throttle from the user. local throttle = math.abs(seatPart.ThrottleFloat) -- Compute how much the controller should be vibrating. local vibrationScale = math.min(1, (speed * throttle) / seatPart.MaxSpeed) -- Apply the vibration. HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Small, vibrationScale) -- Return so the motor doesn't get reset. return end end end -- If nothing is happening, turn off the motor. HapticService:SetMotor(Enum.UserInputType.Gamepad1, Enum.VibrationMotor.Small, 0) end -- Connect our haptic feedback listener to be updated 60 times a second. RunService.Heartbeat:Connect(updateHapticFeedback)