using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; using UnityEngine.Audio; using UnityEngine.VFX; using System.Text.RegularExpressions; using System.Linq; using UnityEngine.InputSystem; //Thomas09. //This script is attached to the UI Manager gameObject inside the UI scene. public class SettingsMenu : MonoBehaviour { public bool settingsIsActive = false; [SerializeField] private InputActionReference holdAimAction; [SerializeField] private InputActionReference pressAimAction; public static SettingsMenu Instance; #region variables //aim Assist Toggle [SerializeField] private TMP_Text fps_Text; private float timer; [Header("Voice Chat Assignments")] [SerializeField] private TMP_Dropdown microphoneDropdown; [SerializeField] private Toggle pushToTalkToggle; [SerializeField] private Toggle muteVoiceToggle; [SerializeField] private Toggle deafenVoiceToggle; [SerializeField] private Slider voiceChatVolumeSlider; //cache const strings here private const string PREFS_MUSICAUDIO = "MusicAudio"; private const string PREFS_SFXAUDIO = "SFXaudio"; private const string PREFS_VOICEAUDIO = "VoiceChatAudio"; private const string PREFS_MUTEVOICE = "MuteVoice"; private const string PREFS_DEAFENVOICE = "DeafenVoice"; private const string PREFS_MICROPHONENAME_INDEX = "MicrophoneName"; private const string PREFS_TOGGLEVOICE = "ToggleVoice"; private const string PREFS_AIMASSIST = "AimAssist"; private const string PREFS_TOGGLEFPS = "fpsToggle"; private const string PREFS_TOGGLEPOSTPROCESSING = "PostProcessing"; private const string PREFS_TOGGLE_RAW_INPUT = "RawInput"; private const string PREFS_INVERT_Y = "InvertY"; private const string PREFS_TOGGLE_SPRINT = "ToggleSprint"; private const string PREFS_TOGGLE_ADS = "ToggleADS"; private const string PREFS_RESOLUTION = "Resolution"; private const string PREFS_QUALITY = "Quality"; private const string PREFS_FPS = "fps"; private const string PREFS_SENS = "Sensitivity"; [Header("DropDown assignments")] [SerializeField] private TMP_Dropdown resolutionDropdown; [SerializeField] private TMP_Dropdown qualityDropdown; [SerializeField] private TMP_Dropdown fpsDropdown; [SerializeField] private Slider sensitivitySlider; [Header("Audio Mixers")] [SerializeField] private AudioMixer musicMixer; [SerializeField] private AudioMixer voiceMixer; public AudioMixer sfxMixer; [Header("Volume Sliders")] [SerializeField] private Slider musicSlider; [SerializeField] private Slider sfxSlider; [Header("Toggles")] [SerializeField] private Toggle invertYToggle; [SerializeField] private Toggle aimAssistToggle; [SerializeField] private Toggle FPSCounterToggle; [SerializeField] private Toggle postProcessingToggle; [SerializeField] private Toggle rawInputToggle; [SerializeField] private Toggle sprintToggle; [SerializeField] private Toggle adsToggle; private const float defaultMusicVolume = 0.6f; private const float defaultSFXVolume = 0.6f; private const float defaultVoiceVolume = 1.0f; private const float defaultSensitivity = 5.0f; private const int defaultInvertY = 0; private const int defaultRawInput = 0; private const int defaultAimAssist = 1; // 1 == true, 0 == false; private const int defaultPushToTalk = 0; private const int defaultFPS_DropdownIndex = 2; //default 60 fps private const int defaultFPS_ToggleValue = 1; private const int defaultPostProcessing_ToggleValue = 1; private const int defaultMuteToggleValue = 1; private const int defaultDeafenToggleValue = 1; private const int defaultADSToggleValue = 0; private const int defaultSprintToggleValue = 0; //Grass Paintera private GrassComputeScript normalGrassPainter = null; private GrassComputeScript tallGrassPainter = null; private GrassComputeScript wheatPainter = null; private GrassComputeScript outOfMapPainter = null; #endregion private void Awake() { Instance = this; } // Start is called before the first frame update void Start() { //SetDesktopResolutionOnStart(); SetSettingsPrefsOnGameStart(); } private void SetDesktopResolutionOnStart() { int resolutionIndex = PlayerPrefs.GetInt(PREFS_RESOLUTION, 0); Resolution[] resolutions = Screen.resolutions; List options = new List(); int currentRefreshRate = Screen.currentResolution.refreshRate; int currentResIndex = 0; for (int i = 0; i < resolutions.Length; i++) { string option = resolutions[i].width + "x" + resolutions[i].height; if (resolutions[i].refreshRate >= currentRefreshRate - 1 && resolutions[i].refreshRate <= currentRefreshRate + 1) { options.Add(option); if (resolutions[i].width == Screen.width && resolutions[i].height == Screen.height) { resolutionDropdown.value = currentResIndex; } currentResIndex++; } } options.Reverse(); resolutionDropdown.ClearOptions(); resolutionDropdown.AddOptions(options); resolutionDropdown.RefreshShownValue(); //SetResolution(resolutionIndex); resolutionDropdown.value = PlayerPrefs.GetInt(PREFS_RESOLUTION, 0); //Debug.Log($"ResIndex: {resolutionIndex}"); } private void Update() { if (ToggleFPSCounter) { timer += Time.deltaTime; if (timer >= 0.75f) { int currentFPS = (int)(1f / Time.unscaledDeltaTime); fps_Text.SetText("{0}", currentFPS); timer = 0; } } } public void SetQuality(int qualityIndex) { QualitySettings.SetQualityLevel(qualityIndex); //add quality options to project settings, and input them into the Drop down IN ORDER. //if one of them is null, they all will be. we dont want to cycle through grass if we're not on FarmYard map. if (normalGrassPainter != null) { SwitchThroughGrassPainters(qualityIndex); } PlayerPrefs.SetInt(PREFS_QUALITY, qualityIndex); } private void SwitchThroughGrassPainters(int index) { static void LazyInit(ref GrassComputeScript variable, string name) { if (!variable) variable = GameObject.Find(name).GetComponent(); } LazyInit(ref normalGrassPainter, "NormalGrass_Painter"); LazyInit(ref tallGrassPainter, "TallGrass_Painter"); LazyInit(ref wheatPainter, "Wheat_GrassPainter"); LazyInit(ref outOfMapPainter, "OutOfMapGrass_Painter"); switch (index) { case 0://low Quality normalGrassPainter.gameObject.SetActive(false); tallGrassPainter.gameObject.SetActive(false); outOfMapPainter.gameObject.SetActive(false); wheatPainter.gameObject.SetActive(true); break; case 1: //Medium Quality normalGrassPainter.gameObject.SetActive(false); outOfMapPainter.gameObject.SetActive(false); tallGrassPainter.gameObject.SetActive(true); wheatPainter.gameObject.SetActive(true); break; case 2: //High Quality normalGrassPainter.gameObject.SetActive(true); tallGrassPainter.gameObject.SetActive(true); outOfMapPainter.gameObject.SetActive(true); wheatPainter.gameObject.SetActive(true); break; case 3://Ultra Quality normalGrassPainter.gameObject.SetActive(true); tallGrassPainter.gameObject.SetActive(true); outOfMapPainter.gameObject.SetActive(true); wheatPainter.gameObject.SetActive(true); break; } } private bool toggleRawInput = false; public bool ToggleRawInput { get => toggleRawInput; set { toggleRawInput = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_TOGGLE_RAW_INPUT, isOn); } } private bool toggleSprintInput = false; public bool ToggleSprintInput { get => toggleSprintInput; set { toggleSprintInput = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_TOGGLE_SPRINT, isOn); } } private bool toggleADS = false; public bool ToggleADS { get => toggleADS; set { toggleADS = value; int isOn = value ? 1 : 0; SetAimActionToUse(value); PlayerPrefs.SetInt(PREFS_TOGGLE_ADS, isOn); } } private void SetAimActionToUse(bool val) { if (val) { holdAimAction.action.Disable(); pressAimAction.action.Enable(); } else { holdAimAction.action.Enable(); pressAimAction.action.Disable(); } } private bool toggleInvertY = false; public bool ToggleInvertY { get => toggleInvertY; set { toggleInvertY = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_INVERT_Y, isOn); } } private bool toggleAimAssist = true; public bool ToggleAimAssist { get => toggleAimAssist; set { toggleAimAssist = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_AIMASSIST, isOn); } } private bool toggleFPSCounter = true; public bool ToggleFPSCounter { get => toggleFPSCounter; set { toggleFPSCounter = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_TOGGLEFPS, isOn); if (!toggleFPSCounter) { fps_Text.SetText(""); } } } private bool togglePostProcessing = false; public bool TogglePostProcessing { get => togglePostProcessing; set { togglePostProcessing = value; int isOn = value ? 1 : 0; PlayerPrefs.SetInt(PREFS_TOGGLEPOSTPROCESSING, isOn); Client.Instance.PostProcessingObject.SetActive(value); } } public void SetResolution(int resolutionIndex) { Resolution resolution = Screen.resolutions[Screen.resolutions.Length - 1 - resolutionIndex]; Screen.SetResolution(resolution.width, resolution.height, true, Screen.currentResolution.refreshRate); PlayerPrefs.SetInt(PREFS_RESOLUTION, resolutionIndex); } public void SetSensitivity(float sensitivity) { GameObject playerGO = FindObjectOfType().gameObject; if (playerGO != null) { CameraController cam = playerGO.GetComponentInChildren(); cam.sensitivity = sensitivity; } PlayerPrefs.SetFloat(PREFS_SENS, sensitivity); } public void SetFPS(int fpsIndex) { QualitySettings.vSyncCount = 0; switch (fpsIndex) { case 0: QualitySettings.vSyncCount = 1; break; case 1: Application.targetFrameRate = 30; break; case 2: Application.targetFrameRate = 60; break; case 3: Application.targetFrameRate = 120; break; case 4: Application.targetFrameRate = 144; break; case 5: Application.targetFrameRate = 240; break; case 6: Application.targetFrameRate = 1000; break; default: Application.targetFrameRate = 60; break; } PlayerPrefs.SetInt(PREFS_FPS, fpsIndex); } public void SetMusicVolume(float volume) { musicMixer.SetFloat("musicVol", Mathf.Log10(volume) * 20); PlayerPrefs.SetFloat(PREFS_MUSICAUDIO, volume); } public void SetSFXVolume(float volume) { sfxMixer.SetFloat("sfxVol", Mathf.Log10(volume) * 20); PlayerPrefs.SetFloat(PREFS_SFXAUDIO, volume); } public void SetVoiceVolume(float volume) { voiceMixer.SetFloat("voiceVol", Mathf.Log10(volume) * 20); PlayerPrefs.SetFloat(PREFS_VOICEAUDIO, volume); } public void SaveGraphicSettings() { //end param is "default" if not loaded / used before. to be used for Resetting settings also. //quality SetQuality(PlayerPrefs.GetInt(PREFS_QUALITY, 2)); qualityDropdown.value = PlayerPrefs.GetInt(PREFS_QUALITY, 2); //fps SetFPS(PlayerPrefs.GetInt(PREFS_FPS, defaultFPS_DropdownIndex)); fpsDropdown.value = PlayerPrefs.GetInt(PREFS_FPS, defaultFPS_DropdownIndex); TogglePostProcessing = PlayerPrefs.GetInt(PREFS_TOGGLEPOSTPROCESSING, defaultPostProcessing_ToggleValue) == 1; postProcessingToggle.isOn = PlayerPrefs.GetInt(PREFS_TOGGLEPOSTPROCESSING, defaultPostProcessing_ToggleValue) == 1; } public void SaveAudioSettings() { //music SetMusicVolume(PlayerPrefs.GetFloat(PREFS_MUSICAUDIO, defaultMusicVolume)); //max volume for both musicSlider.value = PlayerPrefs.GetFloat(PREFS_MUSICAUDIO, defaultMusicVolume); //sfx SetSFXVolume(PlayerPrefs.GetFloat(PREFS_SFXAUDIO, defaultSFXVolume)); sfxSlider.value = PlayerPrefs.GetFloat(PREFS_SFXAUDIO, defaultSFXVolume); SetVoiceVolume(PlayerPrefs.GetFloat(PREFS_VOICEAUDIO, defaultVoiceVolume)); voiceChatVolumeSlider.value = PlayerPrefs.GetFloat(PREFS_VOICEAUDIO, defaultVoiceVolume); } public void SaveGameplaySettings() { ToggleAimAssist = PlayerPrefs.GetInt(PREFS_AIMASSIST, defaultAimAssist) == 1; aimAssistToggle.isOn = PlayerPrefs.GetInt(PREFS_AIMASSIST, defaultAimAssist) == 1; ToggleFPSCounter = PlayerPrefs.GetInt(PREFS_TOGGLEFPS, defaultFPS_ToggleValue) == 1; FPSCounterToggle.isOn = PlayerPrefs.GetInt(PREFS_TOGGLEFPS, defaultFPS_ToggleValue) == 1; ToggleADS = PlayerPrefs.GetInt(PREFS_TOGGLE_ADS, defaultADSToggleValue) == 1; adsToggle.isOn = PlayerPrefs.GetInt(PREFS_TOGGLE_ADS, defaultADSToggleValue) == 1; } public void SaveControlSettings() { //keyboard //sensitivity SetSensitivity(PlayerPrefs.GetFloat(PREFS_SENS, defaultSensitivity)); sensitivitySlider.value = PlayerPrefs.GetFloat(PREFS_SENS, defaultSensitivity); //invert y ToggleInvertY = PlayerPrefs.GetInt(PREFS_INVERT_Y, defaultInvertY) == 1; invertYToggle.isOn = PlayerPrefs.GetInt(PREFS_INVERT_Y, defaultInvertY) == 1; ToggleRawInput = PlayerPrefs.GetInt(PREFS_TOGGLE_RAW_INPUT, defaultRawInput) == 1; rawInputToggle.isOn = PlayerPrefs.GetInt(PREFS_TOGGLE_RAW_INPUT, defaultRawInput) == 1; ToggleSprintInput = PlayerPrefs.GetInt(PREFS_TOGGLE_SPRINT, defaultSprintToggleValue) == 1; sprintToggle.isOn = PlayerPrefs.GetInt(PREFS_TOGGLE_SPRINT, defaultSprintToggleValue) == 1; //controller } private void SetSettingsPrefsOnGameStart() { SaveGraphicSettings(); SaveAudioSettings(); SaveGameplaySettings(); SaveControlSettings(); } public void ResetGraphicSettings() { //deleting keys will result in the default params being used. = reset as if first time login / play. PlayerPrefs.DeleteKey(PREFS_RESOLUTION); PlayerPrefs.DeleteKey(PREFS_QUALITY); PlayerPrefs.DeleteKey(PREFS_FPS); Screen.SetResolution(1920, 1080, true, Screen.currentResolution.refreshRate); SetFPS(1); // uses default case in switch fpsDropdown.value = PlayerPrefs.GetInt(PREFS_FPS, 1); SetQuality(2); //uses middle Quality qualityDropdown.value = PlayerPrefs.GetInt(PREFS_QUALITY, 2); } public void ResetAudioSettings() { PlayerPrefs.DeleteKey(PREFS_MUSICAUDIO); PlayerPrefs.DeleteKey(PREFS_SFXAUDIO); } public void ResetGameplaySettings() { PlayerPrefs.DeleteKey(PREFS_SENS); PlayerPrefs.DeleteKey(PREFS_AIMASSIST); PlayerPrefs.DeleteKey(PREFS_FPS); PlayerPrefs.SetFloat(PREFS_SENS, defaultSensitivity); PlayerPrefs.SetInt(PREFS_AIMASSIST, defaultAimAssist); PlayerPrefs.SetInt(PREFS_FPS, defaultFPS_DropdownIndex); } private void OnApplicationQuit() { PlayerPrefs.Save(); } }