Skip to content

Commit 8a09de0

Browse files
committed
Package creation
1 parent 751463d commit 8a09de0

13 files changed

+194
-1
lines changed
File renamed without changes.

LICENSE.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,43 @@
1-
# unity-scriptable-singletons
1+
# Scriptable Singletons
22
Easy to use singleton implementation for ScriptableObjects in Unity.
3+
4+
## Usage
5+
6+
7+
To make your ScriptableObject a singleton, place your asset instance in a _Resoures_ directory.
8+
9+
Then, make your ScrptableObject class inherit from `ScriptableSingleton` and add the `AssetPathAttribute` with the path to your asset relative to the Resources folder.
10+
11+
### Example
12+
13+
Let's say that you need to access a scriptableObject called _MyGameSettings_ as a singleton.
14+
15+
```c#
16+
public class MyGameSettings : ScriptableObject
17+
{
18+
// ...
19+
}
20+
```
21+
22+
Make sure only one asset for that object exists and place it in a valid Resources folder (e.g. `Assets/Resources/myGameSettingsAsset.asset`).
23+
24+
25+
Then, make a few changes to the class definition, as follows:
26+
```c#
27+
[AssetPath("myGameSettingsAsset")]
28+
public class MyGameSettings : ScriptableSingleton<MyGameSettings>
29+
{
30+
// ...
31+
}
32+
```
33+
34+
Note: if your asset is located in a subfolder within the Resources folder, the path specified in the AssetPath attribute should match with it. For example: an asset in `Assets/Resources/Foo/bar.asset` should have an attribute `[AssetPath("Foo/bar")]`.
35+
36+
All set! You can access your asset instance with the `Instance` property.
37+
```c#
38+
MyGameSettings.Instance.DoSomething();
39+
```
40+
41+
## Installation
42+
43+
This package is compatible with the Unity Package Manager (UPM). Please refer to the official Unity documentation to [install this package from a git repository](https://docs.unity3d.com/2020.1/Documentation/Manual/upm-ui-giturl.html).

README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "Abrusle.ScriptableSingleton",
3+
"references": [],
4+
"includePlatforms": [],
5+
"excludePlatforms": [],
6+
"allowUnsafeCode": false,
7+
"overrideReferences": false,
8+
"precompiledReferences": [],
9+
"autoReferenced": false,
10+
"defineConstraints": [],
11+
"versionDefines": [],
12+
"noEngineReferences": false
13+
}

Runtime/Abrusle.ScriptableSingletons.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/AssetPathAttribute.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
[AttributeUsage(AttributeTargets.Class)]
4+
public sealed class AssetPathAttribute : Attribute
5+
{
6+
public string Path { get; }
7+
8+
public AssetPathAttribute(string filePath)
9+
{
10+
Path = filePath;
11+
}
12+
}

Runtime/AssetPathAttribute.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/ScriptableSingleton.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using UnityEngine;
2+
3+
public abstract class ScriptableSingleton<TObject> : ScriptableObject where TObject : ScriptableObject
4+
{
5+
private static TObject _Instance;
6+
7+
public static TObject Instance
8+
{
9+
get
10+
{
11+
if (_Instance == null) CreateOrLoadInstance();
12+
return _Instance;
13+
}
14+
}
15+
16+
private static void CreateOrLoadInstance()
17+
{
18+
string filePath = GetResourcePath();
19+
if (!string.IsNullOrEmpty(filePath))
20+
_Instance = Resources.Load<TObject>(filePath);
21+
22+
#if UNITY_EDITOR
23+
if (_Instance != null) return;
24+
_Instance = CreateInstance<TObject>();
25+
UnityEditor.AssetDatabase.CreateAsset(_Instance, $"Assets/Resources/{filePath}.asset");
26+
#endif
27+
}
28+
29+
private static string GetResourcePath()
30+
{
31+
var attributes = typeof(TObject).GetCustomAttributes(true);
32+
33+
foreach (object attribute in attributes)
34+
{
35+
if (attribute is AssetPathAttribute pathAttribute)
36+
return pathAttribute.Path;
37+
}
38+
Debug.LogError($"{typeof(TObject)} does not have {nameof(AssetPathAttribute)}.");
39+
return string.Empty;
40+
}
41+
42+
protected virtual void Awake()
43+
{
44+
#if UNITY_EDITOR
45+
if (!Application.isPlaying)
46+
{
47+
if (_Instance != null && _Instance != this)
48+
{
49+
Debug.LogError($"An instance of {typeof(TObject)} already exist.");
50+
DestroyImmediate(this);
51+
}
52+
}
53+
#endif
54+
}
55+
}

0 commit comments

Comments
 (0)