📗

【Unity】Android/iOSで端末を振動させる方法

に公開

はじめに

初めての方も、そうでない方もこんにちは!
現役ゲームプログラマーのたむぼーです。
自己紹介を載せているので、気になる方は見ていただければ嬉しいです!

今回は
 UnityのAndroid/iOSで端末を振動させる
方法について紹介します

https://zenn.dev/tmb/articles/1072f8ea010299

使い方

VibrationManagerクラスが提供するVibrate関数で一括管理します
※UnityのEdetor上では確認できないので、端末にビルドする必要があります。

LayerSelectorAttribute.cs
using UnityEngine;

public class Example : MonoBehaviour
{
    [SerializeField]
    private bool _isVibrationShort;

    [SerializeField]
    private bool _isVibrationMedium;

    [SerializeField]
    private bool _isVibrationLong;

    private void Start()
    {
        // 開始時に一度だけ振動させる例
        ExampleVibrate();
    }

    private void ExampleVibrate()
    {
        // 振動(小)
        if (_isVibrationShort) // 条件式は任意の条件に変えてね
        {
            VibrationManager.Vibrate(VibrationType.Short);
        }

        // 振動(中)
        if (_isVibrationMedium) // 条件式は任意の条件に変えてね
        {
            VibrationManager.Vibrate(VibrationType.Medium);
        }

        // 振動(大)
        if (_isVibrationLong) // 条件式は任意の条件に変えてね
        {
            VibrationManager.Vibrate(VibrationType.Long);
        }
    }
}

実装について

振動の実装には以下のファイルを作成する必要があります
※拡張子「.mm」ファイルの作成は、txtでもcsでもいいので、一度作成して、エクスプローラー(Macの場合はファインダー)から名前変更で拡張子を「.mm」に変更します。
・playSystemSound.mm:iOS用の振動管理
・VibrationType.cs:振動タイプ(振動の長さの列挙)
・VibrationManager.cs:振動マネージャークラス

playSystemSound.mm

playSystemSound.mm
#import <Foundation/Foundation.h>
#import <AudioToolBox/AudioToolBox.h>

extern "C" void _playSystemSound(int soundId)
{
    AudioServicesPlaySystemSound(soundId);
}

VibrationType.cs

VibrationType.cs
/// <summary>
/// 振動の種類
/// </summary>
public enum VibrationType
{
    /// <summary>短い振動</summary>
    Short = 0,

    /// <summary>中程度の振動</summary>
    Medium = 1,

    /// <summary>長い振動</summary>
    Long = 2,
}

VibrationManager.cs

VibrationManager.cs
using UnityEngine;

#if UNITY_IOS
using System.Runtime.InteropServices;
#endif

public static class VibrationManager
{
    private static bool _isEnable;

    /// <summary>
    /// 振動を有効にする
    /// </summary>
    public static void EnableVibrate(bool isEnable)
    {
        _isEnable = isEnable;
    }

    /// <summary>
    /// 振動
    /// </summary>
    public static void Vibrate(VibrationType type)
    {
        if (!_isEnable)
        {
            return;
        }
        if (SystemInfo.supportsVibration)
        {
            switch (type)
            {
                case VibrationType.Short:
                    {
                        PlaySystemSound(1519); // iOSの場合はSoundIdで1519を指定
                        Vibrate(20); // Androidの場合は20ミリ秒(任意のミリ秒に変更可能)
                    }
                    break;
                case VibrationType.Medium:
                    {
                        PlaySystemSound(1520); // iOSの場合はSoundIdで1520を指定
                        Vibrate(50); // Androidの場合は50ミリ秒(任意のミリ秒に変更可能)
                    }
                    break;
                case VibrationType.Long:
                    {
                        PlaySystemSound(1521); // iOSの場合はSoundIdで1521を指定
                        Vibrate(100); // Androidの場合は100ミリ秒(任意のミリ秒に変更可能)
                    }
                    break;
            }
        }
    }

    // iOS設定
#if UNITY_IOS && !UNITY_EDITOR
    [DllImport ("__Internal")]
    static extern void _playSystemSound(int n);
#endif

    private static void PlaySystemSound(int n) //引数にIDを渡す
    {
#if UNITY_IOS && !UNITY_EDITOR
        if (n > 0)
        {
            _playSystemSound(n);
        }
        else
        {
            Handheld.Vibrate();
        }
#endif
    }

    // Android設定
#if UNITY_ANDROID && !UNITY_EDITOR
    public static AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    public static AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    public static AndroidJavaObject vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator");
#endif

    private static void Vibrate(long milliseconds)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        if (milliseconds >= 1000)
        {
            Handheld.Vibrate();
        }
        else
        {
            vibrator.Call("vibrate", milliseconds);
        }
#endif
    }
}

iOSのSoundIdについて

SoundId 強さ 説明
1519 弱(約15〜25ms) 軽い触覚フィードバック(タップ感)
1520 中(約40〜60ms) やや強い触覚(成功フィードバック向き)
1521 強(約80〜120) しっかりとしたバイブ(エラー・衝撃向き)
0 長め(約400~500ms) 0指定の場合は、Unityの簡易振動APIを使う

Discussion