Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

1vdlrwnsv1 님의 블로그

유니티 PlayerPref를 이용한 사운드 값, 마우스 감도 값 저장 불러오기 본문

Unity 최종

유니티 PlayerPref를 이용한 사운드 값, 마우스 감도 값 저장 불러오기

1vdlrwnsv1 2025. 4. 23. 20:19

PlayerPref란? 유니티에서 간단한 설정 값이나 데이터를 저장 할 수 있는 가능

데이터는 문자열, 정수, 실수 만 저장 가능

구조체, 배열, 리스트 등은 직접 변환해야함

 

저장 위치

  • Windows: HKEY_CURRENT_USER\Software\Unity\UnityEditor\<company>\<product>
  • Mac: ~/Library/Preferences/unity.<company>.<product>.plist
  • Android: /data/data/<package>/shared_prefs/*.xml
  • iOS: NSUserDefaults

 

사용법

PlayerPref.SetInt("MyInt", 100);
PlayerPref.SetFloat("MyFloat", 0.1);
PlayerPref.SetString("PlayerName", "IkJoon");

 

디스크에 저장하고 싶으면

PlayerPref.Save();

 

존재 여부 확인

if(PlayerPref.HasKey("MyScore")){
	//데이터가 존재한다면 실행할 로직
    }

 

삭제

PlayerPrefs.DeleteKey("MyScore");//특정 키 삭제
PlayerPrefs.DeletAll();//전부 삭제

 

저장/불러오기 예시

PlayerPrefs.SetFloat("MasterVol", 0.8f);
PlayerPrefs.Save(); //선택사항

//불러오기
float volume = PlayerPrefs.GetFloat("MasterVol", 1f); //불러오고 없으면 1로 초기화

 

일단 SoundManger.cs

using System;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 예시
/// 배경음악: SoundManager.Instance.PlayBackgroundMusic("사운드 이름");
/// 효과음: SoundManager.Instance.PlaySFX("사운드 이름");
/// </summary>

public class SoundManager : MonoBehaviour
{
    public static SoundManager Instance; // 싱글톤 패턴을 위한 인스턴스

    private AudioSource musicSource; // 배경음악용 오디오 소스
    private AudioSource sfxSource;   // 효과음용 오디오 소스

    [Header("Settings")]
    [Tooltip("마스터 볼륨")]
    [Range(0f, 1f)]
    public float masterVol = 1f; // 전체 볼륨 비율

    [Tooltip("효과음 볼륨")]
    [Range(0f, 1f)]
    public float sfxVol = 0.5f; // 효과음 볼륨 비율

    [Tooltip("배경음악 볼륨")]
    [Range(0f, 1f)]
    public float backgroundMusicVol = 0.5f; // 배경음악 볼륨 비율

    [Header("오디오 클립")]
    public AudioClip backgroundMusic; // 초기 재생할 배경음악
    public Dictionary<string, AudioClip> soundEffects = new(); // 효과음 저장용 딕셔너리

    private void Awake()
    {
        // 싱글톤 패턴 초기화
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject); // 씬 전환에도 사운드 매니저 유지
        }
        else
        {
            Destroy(gameObject); // 이미 있으면 삭제
            return;
        }

        // AudioSource 컴포넌트가 없으면 추가
        if (sfxSource == null) sfxSource = gameObject.AddComponent<AudioSource>();
        if (musicSource == null) musicSource = gameObject.AddComponent<AudioSource>();
        musicSource.loop = true; // 배경음악 반복 재생

        // 이전에 저장된 볼륨 불러오기 (없으면 기본값 유지)
        masterVol = PlayerPrefs.GetFloat("MasterVol", masterVol);
        backgroundMusicVol = PlayerPrefs.GetFloat("MusicVol", backgroundMusicVol);
        sfxVol = PlayerPrefs.GetFloat("SFXVol", sfxVol);

        // 불러온 값으로 볼륨 적용
        SetMasterVolume(masterVol);
        SetSFXVolume(sfxVol);
        SetMusicVolume(backgroundMusicVol);

        // 배경음악 재생
        PlayBackgroundMusic(backgroundMusic);
    }

    private void OnEnable()
    {
        // 오브젝트가 다시 활성화됐을 때 볼륨 재적용
        SetMasterVolume(masterVol);
        SetSFXVolume(sfxVol);
        SetMusicVolume(backgroundMusicVol);
    }

    #region 배경음악 관련

    // 배경음악 재생
    void PlayBackgroundMusic(AudioClip music)
    {
        if (music != null)
        {
            musicSource.clip = music;
            musicSource.Play();
        }
    }

    // 배경음악 일시 정지
    public void PauseBackgroundMusic()
    {
        musicSource.Pause();
    }

    // 배경음악 재개
    public void ResumeBackgroundMusic()
    {
        musicSource.Play();
    }

    #endregion

    #region 효과음 관련

    // 사운드 이름과 클립 등록
    public void AddSoundEffect(string soundName, AudioClip clip)
    {
        if (!soundEffects.ContainsKey(soundName))
        {
            soundEffects.Add(soundName, clip);
        }
    }

    // 이름으로 효과음 재생 (Resources에서 로드하거나 기존 딕셔너리에서 찾음)
    public void PlaySFX(string soundName)
    {
        if (soundEffects.TryGetValue(soundName, out AudioClip clip))
        {
            sfxSource.pitch = 1f;
            sfxSource.PlayOneShot(clip, sfxVol);
        }
        else
        {
            // 로드 실패 시 Resources 폴더에서 시도
            clip = Resources.Load<AudioClip>("Audio/SFX/" + soundName);

            if (clip != null)
            {
                soundEffects[soundName] = clip;
                sfxSource.pitch = 1f;
                sfxSource.PlayOneShot(clip, sfxVol);
            }
            else
            {
                Debug.Log("sound 못찾음 " + soundName);
            }
        }
    }

    // 직접 클립으로 효과음 재생
    public void PlaySFX(AudioClip clip)
    {
        if (clip != null)
        {
            sfxSource.PlayOneShot(clip, sfxVol);
        }
    }

    #endregion

    #region 볼륨 설정

    // 마스터 볼륨 설정 및 저장
    public void SetMasterVolume(float volume)
    {
        masterVol = Mathf.Clamp(volume, 0f, 1f);
        PlayerPrefs.SetFloat("MasterVol", masterVol); // 저장
        sfxSource.volume = sfxVol * masterVol;
        musicSource.volume = backgroundMusicVol * masterVol;
    }

    // 효과음 볼륨 설정 및 저장
    public void SetSFXVolume(float volume)
    {
        sfxVol = Mathf.Clamp(volume, 0f, 1f);
        PlayerPrefs.SetFloat("SFXVol", sfxVol); // 저장
        sfxSource.volume = sfxVol * masterVol;
    }

    // 배경음악 볼륨 설정 및 저장
    public void SetMusicVolume(float volume)
    {
        backgroundMusicVol = Mathf.Clamp(volume, 0f, 1f);
        PlayerPrefs.SetFloat("MusicVol", backgroundMusicVol); // 저장
        musicSource.volume = backgroundMusicVol * masterVol;
    }

    #endregion
}

 

 

OptionUI.cs

using UnityEngine;
using UnityEngine.UI;

//TODO: 정조준 감도 구현해야함
/// <summary>
/// TestUIScene 오픈
/// option 버튼 눌러서 팝업창 켜지는지 확인
/// myRoom 버튼 눌러서 다른 팝업창 교체 되는지 확인(아무 UI나 넣은것임)
/// Option창에서 사운드 슬라이더 바로 소리 잘 조절 되나 확인
/// Player프리펩 하이어라키에 끌어다 놓기
/// OPtion창의 마우스 감도(비 조준만) 조절 잘 되나 확인
/// Player의 FpsCamera클래스의 sensitivity가 잘 바뀌나 확인
/// </summary>
public class OptionUI : PopupUI
{
    [Header("Mouse Sensitivity")]
    public Text hipSensitivityText;
    public Text adsSensitivityText;
    public float hipSensitivity = 1f;
    public float adsSensitivity = 1f;

    // 캐싱된 감도 값을 저장할 static 변수
    public static float cachedHipSensitivity = 1f;
    public static float cachedAdsSensitivity = 1f;

    private const string HipSensitivityKey = "HipSensitivity";
    private const string AdsSensitivityKey = "ADSSensitivity";


    [Header("Sound Sliders")]
    public Slider masterSlider;
    public Slider seSlider;
    public Slider bgmSlider;

    public Text masterValueText;
    public Text seValueText;
    public Text bgmValueText;

    protected override void Awake()
    {
        base.Awake();

        //슬라이더 최대 최소값
        masterSlider.minValue = 0;
        masterSlider.maxValue = 100;
        seSlider.minValue = 0;
        seSlider.maxValue = 100;
        bgmSlider.minValue = 0;
        bgmSlider.maxValue = 100;

        // masterSlider.value = SoundManager.Instance.GetMasterVolume() * 100f;

        UpdateSensitivityTexts();

        // 사운드 슬라이더 값 변경 리스너 등록
        masterSlider.onValueChanged.AddListener((v) =>
        {
            masterValueText.text = v.ToString("0");
            SoundManager.Instance.SetMasterVolume(v / 100f);
        });

        seSlider.onValueChanged.AddListener((v) =>
        {
            seValueText.text = v.ToString("0");
            SoundManager.Instance.SetSFXVolume(v / 100f);
        });

        bgmSlider.onValueChanged.AddListener((v) =>
        {
            bgmValueText.text = v.ToString("0");
            SoundManager.Instance.SetMusicVolume(v / 100f);
        });
    }
    private void OnEnable()
    {
        // PlayerPrefs 값 다시 불러오기
        LoadSensitivity();

        // 사운드 슬라이더 값 갱신
        masterSlider.value = SoundManager.Instance.masterVol * 100f;
        seSlider.value = SoundManager.Instance.sfxVol * 100f;
        bgmSlider.value = SoundManager.Instance.backgroundMusicVol * 100f;

        UpdateSoundTexts();
    }


    #region Sensitivity Control
    public void ChangeHipSensitivity(float delta)
    {
        hipSensitivity = Mathf.Clamp(hipSensitivity + delta, 0.1f, 9.9f);
        cachedHipSensitivity = hipSensitivity;  // 캐시된 값 갱신
        PlayerPrefs.SetFloat(HipSensitivityKey, hipSensitivity);
        UpdateSensitivityTexts();

        // FpsCamera의 감도 바로 업데이트
        var camera = FindObjectOfType<FpsCamera>();
        if (camera != null)
        {
            camera.SetSensitivity(hipSensitivity); // SetSensitivity 메서드를 사용하여 바로 적용
        }
    }

    public void ChangeADSSensitivity(float delta)//정조준 민감도 아직 구현x
    {
        adsSensitivity = Mathf.Clamp(adsSensitivity + delta, 0.1f, 9.9f);
        cachedAdsSensitivity = adsSensitivity;  // 캐시된 값 갱신
        PlayerPrefs.SetFloat(AdsSensitivityKey, adsSensitivity);
        UpdateSensitivityTexts();
    }

    private void UpdateSensitivityTexts()// 민감도 텍스트 갱신
    {
        hipSensitivityText.text = hipSensitivity.ToString("0.0");
        adsSensitivityText.text = adsSensitivity.ToString("0.0");
    }
    #endregion

    private void UpdateSoundTexts()
    {
        masterValueText.text = masterSlider.value.ToString("0");
        seValueText.text = seSlider.value.ToString("0");
        bgmValueText.text = bgmSlider.value.ToString("0");
    }

    private void LoadSensitivity()
    {
        // PlayerPrefs에서 감도 값 불러오기
        hipSensitivity = cachedHipSensitivity = PlayerPrefs.GetFloat(HipSensitivityKey, 1f);
        adsSensitivity = cachedAdsSensitivity = PlayerPrefs.GetFloat(AdsSensitivityKey, 1f);

        UpdateSensitivityTexts();
    }

}

 

전체 구조 요약

  • SoundManager: 실제로 사운드 재생과 볼륨 조절을 담당함. (싱글톤)
  • OptionUI: UI에서 마우스 감도와 사운드 볼륨 슬라이더를 조작하면 SoundManager의 볼륨 설정 함수를 호출함.

SoundManager.cs

기능 요약:

  • 배경음악/효과음 관리
  • 볼륨 저장 및 적용
  • 효과음 동적 로딩 가능

주요 함수 OptionUI.cs 와 연결된 부분

public void SetMasterVolume(float volume)
public void SetSFXVolume(float volume)
public void SetMusicVolume(float volume)

 

  • 각각 masterVol, sfxVol, backgroundMusicVol 값을 설정하고 PlayerPrefs로 저장.
  • 슬라이더 값이 바뀔 때 실시간으로 적용됨.

 

OptionUI.cs

기능 요약:

  • 감도 슬라이더 및 사운드 슬라이더 UI 연결
  • 슬라이더 변경 시 바로 SoundManager.Instance.XXXVolume() 호출
  • 옵션창 켜질 때 슬라이더와 텍스트 UI 값도 갱신
masterSlider.onValueChanged.AddListner((v) =>
{
	masterValueText.text = v.ToString("0");
    SoundManager.Instance.SetMasterVolume(v / 100f);
});

 

 

  • 위 구조는 효과음/배경음악 슬라이더에도 동일하게 적용됨.
  • OnEnable()에서 슬라이더의 초기 값도 SoundManager의 현재 값으로 설정함

흐름 예시

사용자가 옵션창을 열었을 때:

  1. OnEnable() 호출됨
  2. SoundManager.Instance에서 볼륨 값 가져옴
  3. 슬라이더와 텍스트 초기화됨

사용자가 슬라이더를 움직였을 때:

  1. 해당 슬라이더 리스너에서 값 전달 (v)
  2. SoundManager의 SetXXXVolume(v / 100f) 호출
  3. AudioSource에 바로 반영됨