Контроллер: вибрация, свет и датчики
Проверить возможности, отправить короткую вибрацию и подготовить датчики.
Вибрация, подсветка и датчики — дополнительные возможности конкретного устройства и драйвера. Проверяйте каждую отдельно и оставляйте основной способ управления без неё. Подключённый контроллер не обязательно поддерживает все функции Input.
Проверки перед командой
| Возможность | Проверка | Команда / чтение |
|---|---|---|
| Вибрация | Input.HasJoyVibration(device) | StartJoyVibration() / StopJoyVibration(). |
| Подсветка | Input.HasJoyLight(device) | SetJoyLight(). |
| Датчики движения | Input.HasJoyMotionSensors(device) | Включение датчиков, калибровка и чтение. |
Берите ID из GetConnectedJoypads() и храните назначение игроку явно. Ненулевой вектор или сохранённые параметры команды не заменяют проверку подключения. Повторяйте проверку после смены устройства; отписывайтесь от JoyConnectionChanged, когда объект перестал обслуживать ввод.
Короткая вибрация с отказом без устройства
Обвязка проверяет диапазон интенсивности, положительную длительность и возможности выбранного контроллера. Второй метод читает гироскоп только после включения и калибровки датчиков.
using System;
using Reckfell;
public static class ControllerFeedback
{
public static bool TryPulse(int device, float strength, float seconds)
{
if (!float.IsFinite(strength) || strength < 0 || strength > 1 ||
!float.IsFinite(seconds) || seconds <= 0) return false;
if (!Input.GetConnectedJoypads().Contains(device) || !Input.HasJoyVibration(device)) return false;
Input.StartJoyVibration(device, strength, strength, seconds);
return true; // Request submitted, not proof that the motors moved.
}
public static bool TryReadGyroscope(int device, out Vector3 radiansPerSecond)
{
radiansPerSecond = Vector3.Zero;
if (!Input.GetConnectedJoypads().Contains(device) ||
!Input.HasJoyMotionSensors(device) || !Input.IsJoyMotionSensorsEnabled(device) ||
!Input.IsJoyMotionSensorsCalibrated(device)) return false;
radiansPerSecond = Input.GetJoyGyroscope(device);
return radiansPerSecond.IsFinite();
}
}Вызывайте TryPulse один раз на игровое событие. Возвращённое true означает отправку запроса, а не подтверждение движения моторов. false означает, что запрос не отправлен. Не вызывайте импульс каждый кадр вместо одной команды с длительностью.
У StartJoyVibration() есть две интенсивности: слабого и сильного мотора, каждая 0–1. Длительность измеряется в секундах. Не считайте 0 гарантией бесконечной работы: текущий SDL-бэкенд преобразует его в 65 535 мс. Пример намеренно требует положительную конечную длительность. Добавьте настройку силы/отключения вибрации и остановку на смене контекста игры.
Подсветка
Перед SetJoyLight(device, color) проверьте HasJoyLight. Посылайте новый цвет при изменении состояния, а не бессмысленно каждый кадр. Не кодируйте подсветкой единственный сигнал об опасности: тот же статус должен быть виден на экране. Поддержка API не обещает определённое число светодиодов, яркость или одинаковую цветопередачу устройств.
Датчики и калибровка
- Проверьте подключение и
HasJoyMotionSensors. - Включите датчики через
SetJoyMotionSensorsEnabled(device, true)и проверьтеIsJoyMotionSensorsEnabled. - Предложите положить устройство неподвижно. Вызовите
StartJoyMotionSensorsCalibration, дождитесь выбранного вами периода сбора и завершите черезStopJoyMotionSensorsCalibration. - Проверьте состояние калибровки и только затем используйте показания. Не считайте фиксированную паузу в одну секунду универсальной гарантией точности.
- При завершении использования выключите датчики, если именно ваш код ими управляет; не отключайте их у другой системы, которая продолжает чтение.
В 1.0.0 StopJoyMotionSensorsCalibration() выставляет флаг calibrated; это флаг завершения процедуры, а не оценка качества неподвижности. Контролируйте дрейф на целевом устройстве и разрешите повторную калибровку.
GetJoyGyroscope() возвращает угловую скорость в радианах в секунду. Для накопления угла учитывайте время и выбранные оси управления. GetJoyAccelerometer() и GetJoyGravity() используют м/с²; для оценки ускорения без гравитации сравнивают их разность. Интегрирование этих данных само по себе не даёт надёжного положения контроллера в комнате.
Нулевой результат может означать отсутствие данных или игнорируемый ввод, а не только неподвижность. Сначала проверяйте возможности и состояние. Отсутствие конкретной функции не должно блокировать игру.
Выполнены ветви отсутствующего устройства, нулевых показаний и отказов обвязки. Команды не создают поддержку датчиков у неизвестного ID. Реальные моторы, подсветка, точность датчиков, калибровка на устройстве, горячее отключение и экспорт не проверялись; перечисление API не является матрицей совместимости.