Event Systems in Unity3D

Good day!

Today I would like to briefly describe the use of events to get rid of garbage and provide complex and dynamic functionality to the code. It should be noted that this article is more focused on beginners who want to learn more about event systems.

We will analyze this whole thing on the example of a sound management system. This system will allow us to enable / disable music and sounds in the game settings.

Before we create a class manager that manages sound and music settings, we will create a simple serializable class. It will be used as a data model for saving to 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; // ,    } 

Now you can start writing a class manager. We will install it on the very first stage. This manager will be a global object and will not be deleted when going from scene to scene.

 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(); //    } } 

Now that the manager is ready, you can create an empty object on your starting scene and name it, for example "_AUDIO_MANAGER" , and then add our class manager to it. You can do this simply by calling the component's add-on menu on the object and selecting “Game Managers” => “Audio Manager” .

After that, we need to write a component that we will dock to each object with an 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; } } 

In this way we can control the sounds / music in the game. This example does not in any way tell how to do it correctly, but only demonstrates the work of the system of events and listeners in Unity3D.

And finally, I want to talk about what we have used now. In the example below, a delegate was declared from which the listener was created:

 public delegate void AudioSettingsChanged(); public event AudioSettingsChanged OnAudioSettingsChanged; 

You can set the listener to perform under certain conditions and cling to them certain methods that will be executed when these conditions are reached.

And with the help of delegates, on the basis of which we created a listener, you can create callback functions. This can be especially useful for asynchronous methods (for example, when sending asynchronous POST requests).

I hope you will benefit from my little experience in this matter and you can apply this example to your projects. Also I will be happy to answer your questions (if someone does not understand something).

Source: https://habr.com/ru/post/414155/


All Articles