Rewired + Haptic Feedback Engineで押した感のあるバーチャルパッド実装

shimahinuko

バーチャルパッド、使ってますか?

スマホでも他のゲーム機と同じように操作したいときに便利なバーチャルパッドですが、押した感覚がしない、操作性が悪い、とそれほど評判はよくありません。
実装の基本と、少しでも改善できないかを考えたのがこの記事です。

使うアセット

Rewired

Haptic(Taptic) Feedback Engine for Vibrations on iOS/Android

なお、Rewiredでバーチャルパッドを実装するのは、他のコントローラーと同じように扱えるというRewiredの特性を生かしたいことが理由なので、どちらかというとすでにRewiredを利用している人、またRewiredの導入を検討している人向けです。
単にバーチャルパッドを実装したいだけの場合には、無料の公式のアセットや自作でもある程度できると思うので、Rewiredを使う必要はありません。検索すると日本語の記事も結構出てきます。
後半の Haptic Feedback Engine を使う部分は、どのようなバーチャルパッドにも生かせると思います。

Rewired Touch Joystickの実装

RewiredのバーチャルパッドはTouch Joystickという名前の機能のようです。
ざっと検索した感じ、あまり記事が無いようでしたのでまずはマニュアルからまとめておきます。

準備するもの

あらかじめシーンに置いておく必要があるものです。
とはいえ、GameObject ▶︎ Create Other ▶︎ Rewired ▶︎ Touch Controls ▶︎ Touch Joystick で「Touch Joystick」を新規作成すると全て自動的に置かれるので特に心配する必要はありません。

  • Touch Controller 「Touch Joystick」の親オブジェクトとして設置します。
  • Canvas 「Touch Controller」の親オブジェクトとして設置します。
  • Event System シーン内に置いておきます。

設定するとBaseとStickが自動的に作られます。

プレイヤーが動かす部分を以降Stickと呼びます。

Custom Controllerを作成する

まずはRewiredで入力と左右上下移動のようなアクションを結びつける基本的な設定をします。
基本的な事項に関しては以下の記事が参考になると思います。

アセット触ってみたシリーズ:多種多様なコントローラーに対応しよう!「Rewired」 – Unity公式 Asset Portal

Rewired Editorで、Custom Controllerを作成し、作成したバーチャルパッドの軸を設定します。

  1. 新しいCustom Controllerを作成
  2. 軸を設定

次に、今作成したCustom ControllerをPlayerに割り当てます。

DefaultのCustom Controllerとして扱うときにはDefault Controller Maps のCustom Controller Maps も設定します。

rewired_editor_players02

最後に、あらかじめActionsで設定しておいた動作と結びつけるために、Custom Controller Mapsの設定をします。

rewired_editor_custom_controller_maps

Touch Controller の設定

作成したCustom Controllerを通してバーチャルパッドを使えるようにするために、画像のように、「Use Custom Controller」にチェックを入れ、Custom Controllerに今作ったコントローラーを割り当ててください。

設定項目

次に「Touch Joystick」で設定すると良さそうな項目を確認していきます。
今回記載しなかった項目はデフォルトで良いのではないかなと思います。
詳しくはマニュアルをご覧ください。

General Options
rewired_touch_joystick_general_options
Custom Controller Options
rewired_touch_joystick_custom_controller_options

Rewiredで取り扱うための設定です。
詳しくはRewiredのCustom Controllerに関するマニュアルをご覧ください。

  • Horizontal / Vertical Axis Custom Controller Element X軸、Y軸それぞれのCustom Controllerの設定です。先ほど設定したCustom Controllerの軸を割り当ててください。
  • Tap Custom Controller Element 画像にはありませんが、「Joystick Options」で「Allow Tap」を選択すると表示されます。
Joystick Options
rewired_touch_joystick_joystick_options

バーチャルパッドの設定です。

  • Allowed Mouse Buttons バーチャルパッドを操作できるマウスのボタンを指定します。
  • Stick Range Stickを動かせる範囲をピクセル数で指定します。大きければ大きいほど遠くまで動かせます。
  • Stick Bounds バーチャルパッドの形状を円形にするか正方形にするか選ぶことができます。
  • Joystick Mode AnalogかDigitalかを選ぶことができます。Analogにすると、0から1にいたる途中の0.1や0.52のような値も指の位置で入力できます。方向キーの実装のように、単にOnかOffかを入力させたい時は、Digitalに設定します。
  • Snap Directions 動かしたい方向が決まっている場合には、数字で指定することができます。例えば、4方向や8方向に動かすだけの十字キーを作りたいときには4、8といった数字を指定してあげることで再現できます。
  • Snap Stick To Touch 設定すると、バーチャルパッドのどこかをタッチするだけでStickがその位置に動きますが、設定していない場合は、Stickを掴んでからでないと入力できません。
  • Center Stick On Release Stickを動かした状態で指を離したとき、Stickを中央に戻します。これを設定しないと、指を離してもStickは倒されたまま残り入力状態が続きます。
  • Activate On Swipe In バーチャルパッドの外側から指を滑らせてきてバーチャルパッドに触れたとき、使えるようにするかどうかの設定です。
  • Stay Active On Swipe Out バーチャルパッド内から外側に指を滑らせたときに入力を継続するかどうかの設定です。
  • Follow Touch Position 設定すると、指をバーチャルパッドの外側に滑らせたときにその指にバーチャルパッドがついてきます。
Axis Options
rewired_touch_joystick_axis_options
  • Invert Horizontal Axis X軸方向の入力を反転します。
  • Invert Vertical Axis Y軸方向の入力を反転します。
  • Advanced 軸に関する細かい設定ができます。
Graphic Options
rewired_touch_joystick_graphic_options

バーチャルパッドとして表示される画像の設定です。

  • Transition Type 指を乗せたり動かしたときにどのように見た目が変わるかの設定です。詳しい使い方は、Unity公式ドキュメントの「アニメーション遷移 – Unity マニュアル」を見てください。
  • Visibility Fade Duration 見た目が変わるフェード時間の設定です。0に設定すると即座に切り替わります。
Misc Options
rewired_touch_joystick_misc_options
  • Hide When Idle バーチャルパッドに触れたときだけ表示されるようにします。

使ってみる

これで動くようになったはずです。
それでは実際に使ってみようと思います。
今回は、このようなクォータービューのゲームでキャラクターを4方向に動かすバーチャルパッドを作ってみましょう。

ゲーム画面サンプル

画像のゲームは鋭意開発中です……。
unity1week Meetup in Tokyo 2020にオープニングだけ遊べるようにして持っていく予定です。
1weekerの皆さんを中心によろしくお願いします!

まずは、GameObject ▶︎ Create Other ▶︎ Rewired ▶︎ Touch Controls ▶︎ Touch Joystick を選択してシーンにゲームオブジェクトを表示します。
「Touch Joystick」の親オブジェクトである「Touch Contoller」の「Custom Controller Option」にあらかじめ作成しておいたCustom Controllerを割り当てます。
それから、上記の「Custom Controller Options」で書いたように、Touch Joystickに方向を設定します。

クォータービューなので、Z軸方向に-45度傾けました。
色をつけたり方向を変えたりして、完成です。

動いた!

「押した感」「触っている感」を出す

ここまでできたら、仕上げとして感触のフィードバックを与えてあげようと思います。
調べればそれほど苦労なく自分でも書けそうな気もしますが、ここはiOS/Androidのバイブレーションや軽い振動を簡単に実装できる「Haptic(Taptic) Feedback Engine for Vibrations on iOS/Android – Asset Store」を使いましょう。
時間かけて調べるよりも買った方がコスパ良さそうなぐらい安いです。

こんな感じでスクリプトを書いて、今作ったtouch joy stick にアタッチします。

using Rewired.ComponentControls;
using UnityEngine;
public class VibrateJoyStick : MonoBehaviour
{
    private TouchJoystick _touchJoystick;
    public void Awake()
    {
        Taptic.tapticOn = true;
        _touchJoystick = GetComponent<TouchJoystick>();
    }
    
    public void Update()
    {
        var vector2 = _touchJoystick.GetValue();
        if (Mathf.Abs(vector2.x) > 0.8f || Mathf.Abs(vector2.y) > 0.8f) Taptic.Light();
    }
}

ある閾値(ここでは0.8にしました)を超えると、端末が軽く振動し、反応を得ることができます。
Taptic.Medium();Taptic.Heavy();など、振動の大きさを9種類使い分けることができるので、動き始めにしっかりとした振動、それから動き続けている間は常に軽い振動、みたいな使い分けもできるかもしれません。

なお、void Update()でTaptic.Light();し続けると設定によってはエディタやIDEから警告が出るので、UniRxを使っているならば 代わりにvoid Start()にこう書いても良さそうです。

using Rewired.ComponentControls;
using UniRx;
using UnityEngine;
public class VibrateJoyStick : MonoBehaviour
{
    private TouchJoystick _touchJoystick;
    public void Awake()
    {
        Taptic.tapticOn = true;
        _touchJoystick = GetComponent<TouchJoystick>();
    }
    
    public void Start()
    {
        _touchJoystick.ObserveEveryValueChanged(joystick => joystick.GetValue())
            .Where(vector2 => Mathf.Abs(vector2.x) > 0.8f || Mathf.Abs(vector2.y) > 0.8f)
            .RepeatUntilDestroy(gameObject)
            .Subscribe(vector2 => Taptic.Light())
            .AddTo(gameObject);
    }
}

終わりに

実際に操作すると、それでもやはり劇的に改善!というわけではなく、どうやってもそれなりな操作にしかなりませんでした。
バーチャルパッドはやっぱり難しい……。

この記事はUnityアセット冬のアドベントカレンダー 2019 Winter! – Unity公式 Asset Portal の13日目でした。
明日はElizyさんの「BlackFridayで買ったAssets「Unka the Dragon」と「RTSCamera」について紹介」です。
お楽しみに〜〜!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

%d bloggers like this: