• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by chirhotec · Apr 04, 2014 at 08:38 AM · inheritancemonobehavioursingletongenerics

MonoBehaviour Inheritance, Singletons and Generics

I'm trying to set up an AudioManager that can be reused across projects without having to rewrite the key pieces each time. The problem I'm having is that if I extend this AudioManager (ie, MyProjectAudioManager), other classes are unable to access additional features added in the subclass.

Here are the implementation details:

First, I have a generic Singleton class that I use for Managers like this:

 public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
 { 
     // ... singleton implementation
     // similar to http://wiki.unity3d.com/index.php?title=Singleton#Generic_Based_Singleton_for_MonoBehaviours

     public static T instance;
 }

Then I subclass that for my generic audio manager, where T is an enum of the available audio files. (actually I have a subclass, PersistentSingleton, in between, which makes the singleton persist across scenes).

 public abstract class AudioManager<T> : Singleton<AudioManager<T>>
 {
     public abstract IAudioLoader<T> audioFiles { get; }
 
     public void PlayAudio(T audioType)
     {
         AudioClip clip = audioFiles.GetAudioClip(audioType);
         // play the clip!
     }
 }

I'm trying to use the generic here so that I can use an enum to specify which audio files are available on a given project, ie

 public enum MyProjectAudioType
 {
     Blip,
     Bloop,
     ...
 }

And the same type is supplied to the generic loader class, so that it is in charge of loading the audio file from Resources:

 public class MyProjectAudioLoader : IAudioLoader<MyProjectAudioType>
 {
     public AudioClip GetAudioClip(MyProjectAudioType type)
     {
         // check for cached version, otherwise load from Resources
     }
 }

Finally, I have my specific project implementation of the AudioManager, which ends up being pretty simple, as it just ties together the specific project audio type and allows me to attach the manager to a GameObject to be used in the scene. (The actual implementation has another subclass in between that differentiates between a Music Manager or Sound Effects Manager, but that doesn't seem related to my problem)

 public class MyProjectAudioManager : AudioManager<MyProjectAudioType>
 {        
     public MyProjectAudioLoader myAudioFilesLoader;
     public override IAudioLoader<MyProjectAudioType> audioFiles { get { return myAudioFilesLoader; } }

     public void MyCustomFunction() { ... } // any sort of custom functionality
 }

Then for each project, its just a matter of defining the available audio clips, and calling MyProjectAudioManager.instance.PlayAudio(MyProjectAudioType.Blip); The system manages caching clips, pooling audio sources, unloading unused resources under heavy load, etc.

Now, the problem is, if I define a custom function within the specific MyProjectAudioManager, I can't seem to access it through the singleton instance. (ie, MyProjectAudioManager.instance.MyCustomFunction(); ). Maybe it has to do with the fact that the AudioManager base class is inheriting from the Singleton, and not the project specific audio manager. But I don't understand why that would affect it like this, and I'm not really sure how to resolve the issue. Any suggestions on whats going on and how to fix it? Alternative solutions that would still allow me to reuse base classes without having to rewrite it on every project?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by chirhotec · Apr 08, 2014 at 08:45 AM

Finally solved this by changing some of the class defintions:

 public abstract class AudioManager<M, T> : Singleton<M> where M : MonoBehaviour { ... }

 public class MyProjectAudioManager : AudioManager<MyProjectAudioManager,MyProjectAudioType> { ... }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

C# Inheriting from MonoBehaviour but still be able to instantiate with new()? How should I do this? 2 Answers

Extending a Singleton base class (UJS) (?) 2 Answers

MonoBehaviour pseudo-singleton with C# generics 1 Answer

How to call a function on all scripts which are derived from monobehaviour on awake and ondisable? 1 Answer

What is the most elegant solution to replace multiple inheritance for this? 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges