4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Unity]タッチ情報のdeltaPositionを使って動かしたオブジェクトの移動量が合わなかった場合の対応

Posted at

はじめに

Unityのタッチ操作で画面上のオブジェクトなどを動かす場合、オブジェクトの動かし方としては大きく

  • タッチの位置を使ってオブジェクトの位置を変える
  • タッチの移動量を使ってオブジェクトを移動させる

があるかと思います。
後者の場合、Touch.deltaPositionを取得して毎フレームの移動量を決めたりすると思いますが、最初思ったように動かなかったので備忘録です。

結論

  • タッチ情報の更新頻度と毎フレーム処理(Update())のタイミングが異なると移動量がずれる
  • Touch.deltaPositionTouch.deltaTimeで割って速度にして使う

##詳細

起きたこと

以下のようなスクリプトを作成し、アタッチしたオブジェクトがタッチ移動に合わせて動くようにしました。

移動量がずれるサンプル
// Update関数
private void Update()
{
    OnTouchOperation();
}

// タッチ移動量に応じてオブジェクトを移動させる処理
private void OnTouchOperation()
{
    // 移動用タッチの情報取得(とりあえずシングルタッチのみ対応)
    if (0 < Input.touchCount)
    {
        Touch touchPos = Input.GetTouch(0);

        // 移動していたら移動量を取得してオブジェクトを移動
        if (TouchPhase.Moved == touchPos.phase)
        {
            this.transform.Translate(touchPos.deltaPosition.x, touchPos.deltaPosition.y, 0.0f);

            // これでもよい
            // this.transform.position = (Vector2)this.transform.position + touchPos.deltaPosition;
        }
    }

    return;
}

※余談:上記コードで各種thisは省略できますが、個人的には明示的に書いておきたい人です

結果:
実際にタッチで移動した距離よりも、オブジェクト(ポインタ)が移動した距離の方が長くなりました。
1.jpg

原因

タッチ情報が取得されるタイミングとUpdate関数のタイミングが違い、Update関数の方が高頻度でTouch.deltaPositionを取得してオブジェクトを動かしていたためです。
逆にUpdate関数の方が頻度が低い場合は、タッチの移動量よりもオブジェクトの移動量の方が少なくなっていたはずです。
大した内容ではないですが一応図解を…
2.jpg

対策

タッチ情報の取得タイミングはTouch.deltaTimeとして取得できるので
タッチ情報の移動量を扱う際はTouch.deltaPositionTouch.deltaTimeで割ることで、移動速度を計算します。
それにUpdate()Time.deltaTimeを乗算することで、そのフレームとしての移動距離が出せます。
(少しは誤差あるかもしれませんが…)

移動量がずれないサンプル
// Update関数
private void Update()
{
    OnTouchOperation();
}

// タッチ移動量に応じてオブジェクトを移動させる処理
private void OnTouchOperation()
{
    // 移動用タッチの情報取得(とりあえずシングルタッチのみ対応)
    if (0 < Input.touchCount)
    {
        Touch touchPos = Input.GetTouch(0);

        // 移動していたら移動量を取得してオブジェクトを移動
        if (TouchPhase.Moved == touchPos.phase)
        {
            Vector2 moveDist = (touchPos.deltaPosition / touchPos.deltaTime) * Time.deltaTime;
            this.transform.Translate(moveDist.x, moveDist.y, 0.0f);

            // これでもよい
            // this.transform.position = (Vector2)this.transform.position + moveDist;
        }
    }

    return;
}

最後に

今回のような手間を加えなくとも、オブジェクト移動量などは何らかの係数をかけてチューニングすれば解決することも多いと思います。
が、タッチ情報取得やUpdate()のフレームレートは環境やその時の負荷で変わることもあると思うので、思わぬ動作に繋がる可能性があると考えています。
気になる動作はできる限り原因を把握して手を打っておきたいものです。

以上です。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?