モバイル端末では, Input クラスはタッチスクリーン,加速度センサー,地理的/位置入力へアクセスする機能を提供します。
モバイル端末でキーボードにアクセスする権限は iOS キーボード を経由して与えられます。
iPhone と iPod タッチは5本の指がスクリーンを同時にタッチしているのを追跡する能力があります。配列プロパティである Input.touches へ直前のフレームにアクセスしている間は,それぞれの指のスクリーンタッチ状況を感知することができます。
Android 端末には,どれだけの指を追跡するかということに対して統一された制限はありません。その代わりに,端末によって違いますし,古い端末での2本指対応から,新しい端末での5本指対応までありえます。
それぞれの指のタッチは Input.Touch のデータ構造体に掲載してあります:
プロパティ: | 特徴: |
---|---|
fingerId | タッチに対する無二のインデックス |
position | タッチしたスクリーンの位置 |
deltaPosition | 直前のフレームから変わったスクリーンの位置 |
deltaTime | 最後に状態が変わってから経過した時間の合計 |
tapCount | iPhone と iPad のスクリーンはユーザーによる素早いタップを感じ取ることができます。このカウンターは指を動かさずにスクリーンを何回タップしたかを知らせてくれます。 Android 端末はタップの回数を数えません。常に1になります。 |
phase | 「 phase 」と呼ばれるタッチの状態を述べます。タッチが始まったばかりなのか,指が動いているのか,指が離れたところなのかを判断するのに役立ちます。 |
phase は以下の内の一つになります:
Began | 指がスクリーンに触れた瞬間 |
Moved | 画面上で指が動いたとき |
Stationary | 指はスクリーンに触れているが直前のフレームから動いていない |
Ended | 画面から指が離れたとき |
Canceled | システムがタッチの追跡を止めたとき。(例えば)ユーザーが顔を押しつけたり,同時に5本以上の指でタッチした時などです。これがタッチの最後の phase になります。 |
以下のものはユーザーがスクリーンをタップした場所にレイを発射するスクリプトの例です:
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);
}
}
}
}
ネイティヴタッチサポートの最たるものとして, Unity の iOS と Android はマウスシミュレーションを提供します。標準的な Input クラスからマウスの機能を使用することができます。
モバイル端末の動きに応じて,ビルトインの加速度センサーは 三次元空間内で主要な3つの軸に沿った線形加速度の変化を報告します。 それぞれの軸に沿った加速度は重力の値としてハードウェアによって直接報告されます。 1.0 という値は対象の軸に関して +1 の重力値を表しており, –1.0 という値は –1 の重力値を表しています。 もし端末を(ホームバタンは下にある)直立状態で持っているなら,X軸は右に沿って正の値を取り, Y軸は上向きがそのまま正の値を取り,X軸は手前に向かって指している方が正の値を取ります。
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 = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}
LowPassKernelWidthInSeconds
の値が大きいほど,フィルターをかけられた値は現在の入力サンプル(及びその逆)に向かって遅く収束します。
Input.acceleration 変数を読み取ることは,ハードウェアをサンプリングすることとは一致しません。簡単に言えば,Unity は周波数が60ヘルツの時にハードウェアをサンプリングし,変数に結果を保存します。実際はもう少しだけ複雑です。どういうことかというと,CPUが過負荷状態にあるならば,加速度センサーのサンプリングは決まった間隔では行われないということです。結果として,システムは1フレームの間に2回サンプルを報告し,次のフレームでは1サンプルを報告するかもしれないのです。
各フレームの加速度センサーによる全ての測定結果にアクセスすることができます。以下のコードは直前のフレームで収集された全ての加速度センサーイベントの平均を説明するものです:
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;