Skip to content

Instantly share code, notes, and snippets.

@alt3d alt3d/AssetSingleton.cs
Last active Oct 7, 2019

Embed
What would you like to do?
Unity Singletons (MonoBehaviours and ScriptableObjects)
using System;
using System.Linq;
using UnityEngine;
public abstract class AssetSingleton<TAsset> : ScriptableObject where TAsset : ScriptableObject
{
private static TAsset _instance;
public static TAsset Instance
{
get
{
if (!_instance)
{
var attribute = Attribute.GetCustomAttribute(typeof(TAsset), typeof(AssetSingletonAttribute)) as AssetSingletonAttribute;
if (attribute == null || attribute.Folder == null || string.IsNullOrWhiteSpace(attribute.Folder))
{
_instance = Load(string.Empty);
}
else
{
_instance = Load(attribute.Folder);
}
Debug.Assert(_instance, typeof(TAsset).FullName);
}
return _instance;
}
}
private static TAsset Load(string folder)
{
Debug.Assert(Resources.LoadAll<TAsset>(folder).Length > 0,
$"{typeof(TAsset).FullName}: {Resources.LoadAll<TAsset>(folder).Length}");
return Resources.LoadAll<TAsset>(folder).First();
}
}
using System;
using UnityEngine;
public abstract class ClassSingleton<TClass> where TClass : class
{
private static TClass _instance;
public static TClass Instance
{
get
{
if (_instance == null)
{
_instance = Activator.CreateInstance<TClass>();
Debug.Assert(_instance != null);
}
return _instance;
}
}
}
using System;
using System.Linq;
using UnityEngine;
public abstract class MonoSingleton<TMono> : MonoBehaviour where TMono : MonoBehaviour
{
private static TMono _instance;
public static TMono Instance
{
get
{
if (!_instance)
{
var type = typeof(TMono);
var attribute = Attribute.GetCustomAttribute(type, typeof(MonoSingletonAttribute)) as MonoSingletonAttribute;
if (attribute == null)
{
_instance = Create(type);
}
else
{
_instance = attribute.IsAutoCreate ? Create(type) : Find();
if (_instance && _instance != null && attribute.IsDontDestroy)
{
DontDestroyOnLoad(_instance.gameObject);
}
}
Debug.Assert(_instance, type.FullName);
}
return _instance;
}
}
private static TMono Create(Type type)
{
var go = new GameObject(type.Name);
return go.AddComponent<TMono>();
}
private static TMono Find()
{
Debug.Assert(FindObjectsOfType<TMono>().Length == 1,
$"{typeof(TMono).FullName}: {FindObjectsOfType<TMono>().Length}");
return FindObjectsOfType<TMono>().First();
}
}
using System;
[AttributeUsage(AttributeTargets.Class)]
public class MonoSingletonAttribute : Attribute
{
public readonly bool IsAutoCreate;
public readonly bool IsDontDestroy;
public MonoSingletonAttribute(bool isAutoCreate = false, bool isDontDestroy = false)
{
IsAutoCreate = isAutoCreate;
IsDontDestroy = isDontDestroy;
}
}
[AttributeUsage(AttributeTargets.Class)]
public class AssetSingletonAttribute : Attribute
{
public readonly string Folder;
public AssetSingletonAttribute(string folder = null)
{
Folder = folder;
}
}
@alt3d

This comment has been minimized.

Copy link
Owner Author

alt3d commented Oct 7, 2019

Снимок экрана (135)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.