2

In my game, there are tons of places where I need to play audios after functions complete, for example:

class Player{
    public AudioClip clip;
    void WalkToDestination()
    {
         //walk code here

         AudioManager.Play(clip);
    }
}

class GameManger{  
    public AudioClip clip;
    void AfterCompleteLevel()
    {
          //play level completion animation
           AudioManager.Play(clip);
    }
}

Since there are so many functions requiring playing sound, and every time I have to add public AduioSource clip into the class, and AudioManager.Play(clip); into the body, there are too much repetitive work. Is there any good design pattern for this?

Gasper
  • 2,752
  • 1
  • 12
  • 16
ywj7931
  • 135
  • 1
  • 3
  • 9

2 Answers2

2

Define a base class, and put shared functions therein:

public class PlayerBase 
{
     protected SomeClass clip;
     public void PlaySound()
     {
         AudioManager.Play(clip);
     }
}

class Player : PlayerBase {}
class GameManger : PlayerBase {}

The call PlaySound() directly in the derived Player or GameManager class.

Gasper
  • 2,752
  • 1
  • 12
  • 16
David
  • 15,894
  • 22
  • 55
  • 66
  • Yeah, that is a solution, but i feel they are not that similar, the only similar behavior is playing music – ywj7931 Oct 25 '16 at 07:23
2

What you're probably looking for is called a Singleton : they are very useful when using audio managers or such things.

You can declare one this way :

public class YourClassName: MonoBehaviour
{
    public static YourClassName instance;

    public void Awake()
    {
        if (!instance)
        {
            instance = this;
        }
    }

    public void YourMethodToCall()
    {
        //Do what you want here
    }
}

Then from another script you can access it using :

if (YourClassName.instance)
{
    YourClassName.instance.YourMethodToCall();
}
Kardux
  • 2,117
  • 1
  • 18
  • 20
  • 1
    Instead of a singleton class it is better to have a "pre-load" scene and load the audio manager there. You drop the static instance and you instead use a `Object.FindObjectOfType();`. See [this answer](http://stackoverflow.com/questions/35890932/unity-game-manager-script-works-only-one-time/35891919#35891919) for a full explination on how to do it. – Scott Chamberlain Oct 25 '16 at 13:15
  • @ScottChamberlain Agreed that this is another way to do so : I personally "always" use a kind of preload scene (usually the one containing custom splash screens, intro video, etc...) to set all my managers :) – Kardux Oct 25 '16 at 14:46
  • The preload scene should not be a splash screen IMHO. You want it to quickly run even when debugging, if you make it your splash screen then you have to wait for the splash to load before debugging every time. – Scott Chamberlain Oct 25 '16 at 15:37
  • @ScottChamberlain That's why on every piece of script that performs unnecessary (for the game) long actions such as video playing, using a defined symbol like _DEBUG_ allows for easy and fast debugging without having the pain to restore everything before final build ;) – Kardux Oct 26 '16 at 08:44