Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

2 newbie questions (about a button with an audio-sfx)

Discussion in 'Scripting' started by Napoleonite, Apr 1, 2015.

  1. Napoleonite

    Napoleonite

    Joined:
    Mar 15, 2015
    Posts:
    27
    I'm having some design-problems when it comes to my 'global class'.

    1. I can't assign anything to the AudioClip property from the inspector because it's static. So I have no choice but to use the resources folder. Is there no way around this other than singletons? The problem with a singleton is that I get this extra ".Instance" call in my code. Like: GameSettings.Instance.MyClip instead of GameSettings.MyClip.
    2. I don't want to use the resources folder. Because I just keep messing around with dragging objects from the "Audio/SFX/" folder to the "Resources/Audio/SFX/" folder. I basically need all of my folder-structures duplicated and move any asset from the regular tree to the Resources-folder-tree if I want to use it through code... Is there no better solution? Like why can't I just add a reference to an asset on design-time?

    Code (CSharp):
    1. public static class GameSettings
    2. {
    3.   public const string ButtonClickSFX = ""; // A string is nice but then I must still load the audioclip from the resources folder at some point...
    4.   public static readonly AudioClip ButtonClipSFX;// = ??? Can't set through the inspector... Don't want to use the Resources folder either... Also prefer not to use a singleton.
    5. }

    I quickly tried to make a generic script to automatically play my audioclip when I press a button (is this not build-in into Unity??) if the button has this script attached. This way I don't have to edit every single button if I ever change the audioclip's filename in the future.
    However, I remember from C# that attaching something to an event (like: button.onClick +=...) must also have the -= operator called on it when the object is destroyed, otherwise a memory leak is created. Is this handled automatically in Unity5 or must I add it to the monobehaviour's-destructor somehow?
    Though I did notice that the += and -= aren't even supported for some reason. It requires .AddListener(). Is this not an event? I'm slightly confused here.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. [RequireComponent(typeof(AudioSource))] // Probably need only 1 global audiosource for all buttons?
    6. [RequireComponent(typeof(Button))]
    7. public class ButtonAudio : MonoBehaviour {
    8.  
    9.    #region Members
    10.   AudioSource audioSource;
    11.   Button button;
    12.    #endregion
    13.  
    14.   void Awake()
    15.   {
    16.   audioSource = GetComponent<AudioSource>();
    17.   if (audioSource == null) { Debug.LogError("No Audiosource found."); }
    18.  
    19.   button = GetComponent<Button>();
    20.   if (button == null) { Debug.LogError("No Button found."); }
    21.   //button.onClick += new Button.ButtonClickedEvent(); // Erm...
    22.   button.onClick.AddListener(() => PlayAudio());
    23.   }
    24.  
    25.   void PlayAudio(object sender)
    26.   {
    27.   // Play audio here. Get it from the GameSettings.
    28.   }
    29. }
     
  2. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    A good way that i use a litle bit is to have a Database object, with a public array on it that you can drag and drop those sound files into.

    Then at runtime, your static script reads that database and puts references to those clips into static variables.

    That said, i do not know what implications this has for memory costs, and whether or not deleting the database after loading will help
     
  3. Napoleonite

    Napoleonite

    Joined:
    Mar 15, 2015
    Posts:
    27
    So 1 empty scene with an empty gameobject. Then drag a custom database script (full with public variables) on it deriving from monobehaviour and with that 'dont-destroy-on-load-tag'. And then have the GameSettingsclass read those?

    Mmm this database must be located in the first scene that is loaded then. Also the gamesettings can not be (fully) initialized until the scene&database have been fully initialized. This is gonna bite me in the behind sooner or later. The overall idea sounds good though.

    What I/we miss is indeed something like a global database that is present as soon as the game loads and that can have references set on design time.

    Yeah they will probably be in memory for as long as the game runs (static). Not really a problem for a PC. Might be a problem for a mobile phone though. Ideally you just want the reference without instantiating the object and then create it only when needed. But then we are back at the "resource folder" design again.
     
  4. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    I'd say put it in every scene. make it a prefab so you can update i centrally, if possible?

    Also, use public arrays, you can make them an arbitrary size. use one for sounds, one for materials, etc
     
  5. Napoleonite

    Napoleonite

    Joined:
    Mar 15, 2015
    Posts:
    27
    It's really too bad that we don't have the dynamic expando in mono :/. Also no stable sqlite, no build-in functionality to control the gui buttons with the keyboard, no crossplatform inifile support and now this... Live is hard :p.

    Placing one in every scene is a no-go. Then a singleton is better.
    Or... whatever... I just go lazy and take the last singleton from here: http://unitypatterns.com/singletons/. At least it just works. It's not perfect but whatever, it's all about compromises. At least I don't have to add it to every single scene. I just have to make sure that the first scene in the game does have an object with the singleton script attached.
     
    Last edited: Apr 1, 2015
unityunity