Version: 2017.3
Традиционный игровой ввод
Мобильная клавиатура

Ввод на мобильном устройстве

On mobile devices, the Input class offers access to touchscreen, accelerometer and geographical/location input.

Доступ к клавиатуре на мобильных устройствах обеспечивается через iOS keyboard.

Multi-Touch Screen

iPhone и iPod способны отслеживать до пяти нажатий на экран одновременно. Вы можете получить статус каждого нажатия на протяжении последнего кадра через массив Input.touches.

Android устройства не имеют определенного лимита на количество нажатий, которое можно отслеживать. Он колеблется от устройства к устройству и может варьироваться от одного-двух нажатий на старых устройствах, до пяти нажатий на некоторых новых.

Каждое нажатие пальцем представлено в структуре данных Input.Touch:

Свойство: Функция:
fingerId Уникальный индекс для нажатия.
position Позиция нажатия на экран.
deltaPosition Изменение позиции на экране с последнего кадра.
deltaTime Количество времени, которое прошло с тех пор как изменилось последнее состояние.
tapCount The iPhone/iPad screen is able to distinguish quick finger taps by the user. This counter will let you know how many times the user has tapped the screen without moving a finger to the sides. Android devices do not count number of taps, this field is always 1.
phase Describes so called “phase” or the state of the touch. It can help you determine if the touch just began, if user moved the finger or if they just lifted the finger.

Фазы могут быть следующими:

Began Палец только что прикоснулся к экрану.
Moved Палец передвинулся по экрану.
Stationary Палец прикоснулся к экрану, но с последнего кадра не двигался.
Ended Палец только что оторван от экрана. Это последняя фаза нажатий.
Canceled The system cancelled tracking for the touch, as when (for example) the user puts the device to their face or more than five touches happened simultaneously. This is the final phase of a touch.

Ниже приведен пример скрипта, который выпускает луч там, где пользователь тапает по экрану:

var particle : GameObject;
function Update () {
    for (var touch : Touch in Input.touches) {
        if (touch.phase == TouchPhase.Began) {
            // Construct a ray from the current touch coordinates
            var ray = Camera.main.ScreenPointToRay (touch.position);
            if (Physics.Raycast (ray)) {
                // Create a particle if hit
                Instantiate (particle, transform.position, transform.rotation);
            }
        }
    }
}


Симуляция Мыши

On top of native touch support Unity iOS/Android provides a mouse simulation. You can use mouse functionality from the standard Input class. Note that iOS/Android devices are designed to support multiple finger touch. Using the mouse functionality will support just a single finger touch. Also, finger touch on mobile devices can move from one area to another with no movement between them. Mouse simulation on mobile devices will provide movement, so is very different compared to touch input. The recommendation is to use the mouse simulation during early development but to use touch input as soon as possible.

Акселерометр

As the mobile device moves, a built-in accelerometer reports linear acceleration changes along the three primary axes in three-dimensional space. Acceleration along each axis is reported directly by the hardware as G-force values. A value of 1.0 represents a load of about +1g along a given axis while a value of –1.0 represents –1g. If you hold the device upright (with the home button at the bottom) in front of you, the X axis is positive along the right, the Y axis is positive directly up, and the Z axis is positive pointing toward you.

Вы можете получить значение акселерометра, путем доступа к свойству Input.acceleration.

Приведенный ниже пример скрипта позволяет двигать объект, используя акселерометр:

var speed = 10.0;
function Update () {
    var dir : Vector3 = Vector3.zero;

    // we assume that the device is held parallel to the ground
    // and the Home button is in the right hand

    // remap the device acceleration axis to game coordinates:
    // 1) XY plane of the device is mapped onto XZ plane
    // 2) rotated 90 degrees around Y axis
    dir.x = -Input.acceleration.y;
    dir.z = Input.acceleration.x;

    // clamp acceleration vector to the unit sphere
    if (dir.sqrMagnitude > 1)
        dir.Normalize();

    // Make it move 10 meters per second instead of 10 meters per frame...
    dir *= Time.deltaTime;

    // Move object
    transform.Translate (dir * speed);
}


Фильтр низких частот

Показания акселерометра могут быть отрывистыми и с шумом. Применив низкочастотную фильтрацию на сигнал, вы сгладите его и избавитесь от высокочастотного шума.

Приведенный ниже скрипт демонстрирует, как применить низкочастотную фильтрацию на показания акселерометра:

var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;

private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
    lowPassValue = Input.acceleration;
}

function LowPassFilterAccelerometer() : Vector3 {
    lowPassValue = Vector3.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
    return lowPassValue;
}


Чем больше значение LowPassKernelWidthInSeconds, тем медленнее фильтруется значение, которое будет приближаться к значению входного образца (и наоборот).

Я хочу получить как можно более точные показания акселерометра. Что я должен делать?

Чтение переменной Input.acceleration не означает дискретизацию. Проще говоря, Unity замеряет результат при частоте 60 Гц. и сохраняет его в переменную. На самом деле все немного сложнее - в случае значительной нагрузки на процессор, замеры акселерометра не происходят с постоянными временными интервалами. В результате, система может сделать два замера за один кадр, и один замер за следующий кадр.

Вы можете получить доступ ко всем замерам, выполненным акселерометром в текущем кадре. Следующий код иллюстрирует простое среднее всех событий акселерометра, которые были собраны в течение последнего кадра:

var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
    acc += evnt.acceleration * evnt.deltaTime;
    period += evnt.deltaTime;
}
if (period > 0)
    acc *= 1.0/period;
return acc;


Традиционный игровой ввод
Мобильная клавиатура