I have to say this question doesn't demonstrate much research. If you plug "unity singleton" into a search engine, the very first result is the Unify Community Wiki where they show how to make a reusable Singleton via the Curiously Recurring Template Pattern.
Here's a simplified version closer to the Awake style you're describing:
public abstract class Singleton<T> : MonoBehaviour where T :Singleton<T>
{
public static T Instance { get; private set; }
private void Awake() {
if(Instance != null) {
Debug.LogErrorFormat("Two copies of singleton {0} in the scene: ({1}, {2}). Please ensure only one is present.",
(typeof(T)).FullName, Instance.name, name);
Destroy(gameObject);
return;
}
Instance = (T)this;
}
}
You can then apply this singleton behaviour to any MonoBehaviour type by deriving from the template:
public class SomeManager : Singleton<SomeManager>
{
}
Then access its instance with SomeManager.Instance
That said, as Vaillancourt points out, you can skip having many singletons by just having one overall manager that holds references to the others. In this way it behaves like a version of the Service Locator pattern, giving you a common place to re-hook the references if you ever need to change the sub-managers or have more than one:
public class GameManager : Singleton<GameManager> {
public AudioManager audioManager;
public PuzzleManager puzzleManager;
// ...
}
This can help you avoid a common problem we run into with Singletons, where we add multiplayer and suddenly all the systems that used to be globally unique for the only player, now need multiple instances, one for each player. The "manager of managers" gives you a convenient place to parcel out which references to use for each player, and you can look them up with something like GameManager.Instance.GetInventoryForPlayer(2)
.