はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Screen.sleepTimeoutでスマホの画面が暗くならないようにする

はじめに

今回はiOSAndroidにて画面をスリープ状態にさせないようにしたいと思います。

やり方

既にUnityがそれ用のAPIを用意してくれているので、そちらを使えばOKです。
UnityEngine.SleepTimeout - Unity スクリプトリファレンス

// 自動でスリープしないようにする
Screen.sleepTimeout = SleepTimeout.NeverSleep;
            
// スマホに設定されている一定時間でスリープする(通常のモード)
Screen.sleepTimeout = SleepTimeout.SystemSetting;

一工夫してみる

基本的にSleepTimeout.SystemSettingの状態がデフォルトであり、SleepTimeout.NeverSleepの状態が特殊だと個人的に思ったので、戻し忘れがないようにしたいと考え以下のラッパーを作ってみました。

public static class WakeLock
{
    /// <summary>
    /// スリープさせない状態かどうか
    /// </summary>
    public static bool IsLocked => Screen.sleepTimeout == SleepTimeout.NeverSleep;
        
    /// <summary>
    /// スリープさせないよう設定する
    /// </summary>
    public static IDisposable Acquire()
    {
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        return new Subscription();
    }

    /// <summary>
    /// スリープするよう設定する
    /// </summary>
    public static void Release()
    {
        Screen.sleepTimeout = SleepTimeout.SystemSetting;
    }

    private class Subscription : IDisposable
    {
        public void Dispose()
        {
            Release();
        }
    }
}


こちらを使うとこんな感じ。

private void Start()
{
    Debug.Log(WakeLock.IsLocked);           // false (SystemSetting) 
            
    using (WakeLock.Acquire())
    {
        Debug.Log(WakeLock.IsLocked);       // true (NeverSleep)
    }
    Debug.Log(WakeLock.IsLocked);           // false

    var disposable = WakeLock.Acquire();
    Debug.Log(WakeLock.IsLocked);           // true
    disposable.Dispose();
    Debug.Log(WakeLock.IsLocked);           // false
}

さいごに

WakeLock.Acquire()を実行すると無駄にインスタンスが生成されるので、GC.Allocが余分に増えちゃいますが何かうまく対処できるものなのでしょうか。

正直フィールドが一つもないので誤差程度だと思いますが、メモリのプールとかを作ったりとか考えたりした方がいいんですかね。

一つを使い回すとかいってもIDisposableを実装してる時点で破棄されるのが前提な気がするので難しそうな。

メモリ周りのもっと勉強していけたらなと思うのですが、もし何かあるかたはコメント等で教えてくださると嬉しいです。

ではまた。