Доброго времени суток!
Сегодня хотелось бы кратко рассказать об использовании событий для избавления от мусора и предоставления комплексной и динамической функциональности коду. Следует заметить, что данная статья ориентирована скорее на начинающих, которым хочется узнать больше о системах событий.
Разбирать все это дело мы будем на примере системы управления звуком. Данная система будет позволять нам включать/отключать музыку и звуки в настройках игры.
Прежде чем мы создадим класс-менеджер, который будет управлять настройками звука и музыки, мы создадим простой сериализуемый класс. Он будет использоваться в качестве модели данных для сохранения в JSON.
Теперь можно приступить к написанию класса-менеджера. Его мы будем устанавливать на самой первой сцене. Данный менеджер будет глобальным объектом и не будет удаляться при переходе со сцены на сцену.
Теперь, когда менеджер готов, вы можете создать на вашей начальной сцене пустой объект и назвать его, к примеру "_AUDIO_MANAGER", после чего добавить на него наш класс-менеджер. Сделать это можно просто вызвав меню добавления компонента на объекте и выбрав «Game Managers» => «Audio Manager».
После этого, нам необходимо написать компонент, который мы будем пристыковывать к каждому объекту с AudioSource.
Таким образом мы можем управлять звуками/музыкой в игре. Данный пример не в коем случае не говорит, как следует делать это правильно, а лишь демонстрирует работу системы событий и слушателей в Unity3D.
И напоследок хочется поговорить о том, что мы сейчас использовали. В примере ниже, был объявлен делегат, из которого был создан слушатель:
Вы можете установить выполнение слушателя при определенных условиях и цеплять к ним определенные методы, которые будут выполняться при достижении этих условий.
А при помощи делегатов, на основе которого мы создали слушатель, вы можете создавать Callback-функции. Особенно полезно это может быть для асинхронных методов (к примеру при отправке асинхронных POST-запросов).
Надеюсь, вам пригодится мой небольшой опыт в этом деле и вы сможете применить данный пример для своих проектов. Также буду рад ответить на ваши вопросы (если кому-то что-то непонятно).
Сегодня хотелось бы кратко рассказать об использовании событий для избавления от мусора и предоставления комплексной и динамической функциональности коду. Следует заметить, что данная статья ориентирована скорее на начинающих, которым хочется узнать больше о системах событий.
Разбирать все это дело мы будем на примере системы управления звуком. Данная система будет позволять нам включать/отключать музыку и звуки в настройках игры.
Прежде чем мы создадим класс-менеджер, который будет управлять настройками звука и музыки, мы создадим простой сериализуемый класс. Он будет использоваться в качестве модели данных для сохранения в JSON.
using System.Collections; using System.Collections.Generic; using UnityEngine; //============================================= // AudioSettingsModel // @usage model for audio settings // // Developed by CodeBits Interactive // https://cdbits.net/ //============================================= [System.Serializable] public class AudioSettingsModel { public bool music = true; // Флаг, отвечающий за музыку public bool sounds = true; // Флаг, отвечающий за звуки }
Теперь можно приступить к написанию класса-менеджера. Его мы будем устанавливать на самой первой сцене. Данный менеджер будет глобальным объектом и не будет удаляться при переходе со сцены на сцену.
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; //============================================= // Audio Manager // @usage works with audio settings // // Developed by CodeBits Interactive // https://cdbits.net/ //============================================= [AddComponentMenu("Game Managers/Audio Manager")] public class AudioManager : MonoBehaviour{ // Публичные параметры public static AudioManager instance = null; // Инстанс менеджера public static AudioSettingsModel settings = null; // Модель аудио настроек private static string _settings_path = ""; // Путь к файлу настроек аудио // Инициализация менеджера void Awake(){ // Устанавливаем путь для сохранения настроек _settings_path = Application.persistentDataPath + "/audioSettings.gdf"; // Проверяем, задан ли инстанс нашего менеджера if (instance == null){ // Инстанс не задан instance = this; // Установить в инстанс текущий объект } // Устанавливаем параметр, который указывает на то, // что данный объект не должен удаляться при выгрузке // уровня DontDestroyOnLoad(gameObject); // Инициализируем настройки нашего менеджера InitializeSettings(); } // Инициализация менеджера private void InitializeSettings(){ // Если модель настроек не задана if (settings == null) settings = new AudioSettingsModel(); // Создаем новую модель if (File.Exists(_settings_path)){ // Если существует файл с настройками loadSettings(); // Загружаем файл настроек звука } } // Загрузить аудио настройки public void loadSettings(){ string _data = File.ReadAllText(_settings_path); // Считываем весь текст из файла settings = JsonUtility.FromJson<AudioSettingsModel>(_data); // Десериализуем его в текущую модель } // Сохранить аудио настройки public void saveSettings(){ string _json_data = JsonUtility.ToJson(settings); // Сериализуем текущие настройки из модели File.WriteAllText(_settings_path, _json_data); // Сохраняем в наш файл } // Создаем делегаты для нашего события, которое в дальнейшем // будет использоваться для отслеживания изменений настроек аудио public delegate void AudioSettingsChanged(); // Добавить новый делегат public event AudioSettingsChanged OnAudioSettingsChanged; // Создать на его основе событие // Включить/выключить звуки public void toggleSounds(bool enabled){ settings.sounds = enabled; // Изменить настройки звуков в текущей модели saveSettings(_settings_path, settings); // Сохранить настройки if (OnAudioSettingsChanged != null) OnAudioSettingsChanged(); // Вызвать наше событие } // Включить/выключить музыку public void toggleMusic(bool enabled){ settings.music = enabled; // Изменить настройки музыки в текущей модели saveSettings(_settings_path, settings); // Сохранить настройки if (OnAudioSettingsChanged != null) OnAudioSettingsChanged(); // Вызвать наше событие } }
Теперь, когда менеджер готов, вы можете создать на вашей начальной сцене пустой объект и назвать его, к примеру "_AUDIO_MANAGER", после чего добавить на него наш класс-менеджер. Сделать это можно просто вызвав меню добавления компонента на объекте и выбрав «Game Managers» => «Audio Manager».
После этого, нам необходимо написать компонент, который мы будем пристыковывать к каждому объекту с AudioSource.
using System.Collections; using System.Collections.Generic; using UnityEngine; //============================================= // Audio Muter // @usage on/off audio sources on objects // // Developed by CodeBits Interactive // https://cdbits.net/ //============================================= [AddComponentMenu("Audio/Audio Muter Component")] public class AudioMuter : MonoBehaviour { // Публичные параметры компонента public bool is_music = false; // Данный флаг дает понять нашему классу, является ли AudioSource звуком или музыкой. // Приватные параметры private AudioSource _as; // AudioSource private float _base_volume = 1F; // Базовая громкость AudioSource // Инициализация объекта void Start(){ // Получаем компонент AudioSource и его изначальную громкость _as = this.gameObject.GetComponent<AudioSource>(); // Получить компонент _base_volume = _as.volume; // Получить базовую громкость // Здесь мы добавляем слушатель, который будет выполнять метод _audioSettingsChanged, // когда настройки музыки/звуков были изменены AudioManager.instance.OnAudioSettingsChanged += _audioSettingsChanged; // Установить // Ну и на старте мы должны проверить текущее состояние звуков/музыки _audioSettingsChanged(); } // При уничтожении объекта void OnDestroy(){ AudioManager.instance.OnAudioSettingsChanged -= _audioSettingsChanged; // Уничтожаем слушатель } // Данный метод служит для включения/отключения громкости AudioSource private void _audioSettingsChanged(){ if (is_music) _as.volume = (AudioManager.settings.music) ? _base_volume : 0F; if (!is_music) _as.volume = (AudioManager.settings.sounds) ? _base_volume : 0F; } }
Таким образом мы можем управлять звуками/музыкой в игре. Данный пример не в коем случае не говорит, как следует делать это правильно, а лишь демонстрирует работу системы событий и слушателей в Unity3D.
И напоследок хочется поговорить о том, что мы сейчас использовали. В примере ниже, был объявлен делегат, из которого был создан слушатель:
public delegate void AudioSettingsChanged(); public event AudioSettingsChanged OnAudioSettingsChanged;
Вы можете установить выполнение слушателя при определенных условиях и цеплять к ним определенные методы, которые будут выполняться при достижении этих условий.
А при помощи делегатов, на основе которого мы создали слушатель, вы можете создавать Callback-функции. Особенно полезно это может быть для асинхронных методов (к примеру при отправке асинхронных POST-запросов).
Надеюсь, вам пригодится мой небольшой опыт в этом деле и вы сможете применить данный пример для своих проектов. Также буду рад ответить на ваши вопросы (если кому-то что-то непонятно).