7
5

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 5 years have passed since last update.

【Unity】既存のSliderやToggleの状態を簡易的に保存する拡張メソッド【SaveStateExtensions】

Last updated at Posted at 2019-09-25

はじめに

20190925-024041.png

設定画面など、スライダーやチェックボックス(Toggle)を扱うことがあります。多分ソースコードはこんな感じになっています。

ConfigController.cs
using UnityEngine;
using UnityEngine.UI;

namespace hoge
{
    public class ConfigController : MonoBehaviour
    {
        [SerializeField] Toggle BGMToggle, SEToggle, VoiceToggle;
        [SerializeField] Slider BGMSlider, SESlider, VoiceSlder;
        [SerializeField] InputField MemoInputField;
        [SerializeField] AudioSource BGMSource, SESource, VoiceSource;

        void Update()
        {
            // AudioSourceのミュート状態を制御
            BGMSource.mute = BGMToggle.isOn;
            SESource.mute = SEToggle.isOn;
            VoiceSource.mute = VoiceToggle.isOn;

            // AudioSourceの音量を制御
            BGMSource.volume = BGMSlider.value;
            SESource.volume = SESlider.value;
            VoiceSource.volume = VoiceSlder.value;
        }
    }
}

これらは多くの場合、アプリが終了しても保持しておく必要があると思うので、今回は拡張メソッドを使って実現してみました。

使い方

まずSaveStateExtensions.csをDLし、プロジェクト内にインポートします。

次に保存したいコンポーネントに対して、Start()内などで以下の様に呼び出してあげるだけです。

.cs
void Start()
{
    // Toggleの場合
    BGMToggle.SaveState("BGMToggle");
    SEToggle.SaveState("SEToggle");
    VoiceToggle.SaveState("VoiceToggle");

    // Sliderの場合
    BGMSlider.SaveState("BGMSlider");
    SESlider.SaveState("SESlider");
    VoiceSlder.SaveState("VoiceSlder");

    // InputFieldの場合
    MemoInputField.SaveState("MemoInputField");
}

引数のkeyだけは重複しないように気を付けて下さい。(nameof(BGMToggle)を渡してもいいかも)

アプローチ

ソースコード全文はこのようになっています。

Gits: SaveStateExtensions.cs

SaveStateExtensions.cs
using UnityEngine;
using UnityEngine.UI;

public static class SaveStateExtensions
{
    public static void SaveState(this Toggle toggle, string key)
    {
        key = $"{new System.Diagnostics.StackFrame(1).GetMethod().ReflectedType}+{key}";
        Debug.Log(key);
        toggle.isOn = PlayerPrefs.GetInt(key, 0) == 1;
        toggle.onValueChanged.AddListener(isOn => PlayerPrefs.SetInt(key, isOn ? 1 : 0));
    }
    public static void SaveState(this Slider slider, string key)
    {
        key = $"{new System.Diagnostics.StackFrame(1).GetMethod().Name}+{key}";
        slider.value = PlayerPrefs.GetFloat(key, 0f);
        slider.onValueChanged.AddListener(value => PlayerPrefs.SetFloat(key, value));
    }
    public static void SaveState(this InputField inputField, string key)
    {
        key = $"{new System.Diagnostics.StackFrame(1).GetMethod().Name}+{key}";
        inputField.text = PlayerPrefs.GetString(key, string.Empty);
        inputField.onValueChanged.AddListener(value => PlayerPrefs.SetString(key, value));
    }
    public static void SaveState(this Dropdown dropdown, string key)
    {
        key = $"{new System.Diagnostics.StackFrame(1).GetMethod().Name}+{key}";
        dropdown.value = PlayerPrefs.GetInt(key, 0);
        dropdown.onValueChanged.AddListener(value => PlayerPrefs.SetInt(key, value));
    }
}

SaveStateToggleを例に見てみると、やっていることは①PlayerPrefs.GetInt()で取得した値をToggleの初期値として代入し、②Toggleの変更が合った場合のイベント(toggle.onValueChanged)内でPlayerPrefs.SetInt()を呼んでいます。

.cs
public static void SaveStateToggle(this Toggle toggle, string key)
{
    key = $"{new System.Diagnostics.StackFrame(1).GetMethod().ReflectedType}+{key}";
    toggle.isOn = PlayerPrefs.GetInt(key, 0) == 1;
    toggle.onValueChanged.AddListener(isOn => PlayerPrefs.SetInt(key, isOn ? 1 : 0));
}

少し工夫しているのかkeyの生成で、System.Diagnostics.StackFrame(1).GetMethod().ReflectedTypeを使って呼び出し元のクラス名を先頭に追加しています。先の例では"hoge.ConfigController+BGMToggle"keyになる形です。こうすることによって、このメソッドを多くの場所で利用してもkeyの衝突が起きにくくしています。

最後に

今回は保存にPlayerPrefsを使っていますが、異常終了時には正しく保存されない場合があります。(PlayerPrefs.Save();で明示的に保存することもできます)

あくまで簡易的なものですので、その点に気をつけてぜひご活用ください。

7
5
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
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?