Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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.

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

Generic MonoBehaviour with nested class serialization issue 1 Answer

How can I return a GameObject? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges