├── Editor.meta
├── Editor
├── F10.Multipool.Editor.asmdef
├── F10.Multipool.Editor.asmdef.meta
├── Icons.meta
├── Icons
│ ├── MultipoolEmitterEditor_Icon64.png
│ ├── MultipoolEmitterEditor_Icon64.png.meta
│ ├── MultipoolEmmiter_Icon64.png
│ ├── MultipoolEmmiter_Icon64.png.meta
│ ├── MultipoolManagerEditor_Icon64.png
│ ├── MultipoolManagerEditor_Icon64.png.meta
│ ├── MultipoolManager_Icon64.png
│ ├── MultipoolManager_Icon64.png.meta
│ ├── MultipoolReset_Icon64.png
│ └── MultipoolReset_Icon64.png.meta
├── MultipoolEmitterEditor.cs
├── MultipoolEmitterEditor.cs.meta
├── MultipoolManagerEditor.cs
└── MultipoolManagerEditor.cs.meta
├── LICENSE
├── LICENSE.meta
├── README.md
├── README.md.meta
├── Runtime.meta
├── Runtime
├── F10.Multipool.asmdef
├── F10.Multipool.asmdef.meta
├── MultipoolEmitter.cs
├── MultipoolEmitter.cs.meta
├── MultipoolManager.cs
├── MultipoolManager.cs.meta
├── MultipoolPool.cs
├── MultipoolPool.cs.meta
├── MultipoolReset.cs
└── MultipoolReset.cs.meta
├── Samples~
├── Ball Demo.meta
└── Ball Demo
│ ├── Materials.meta
│ ├── Materials
│ ├── Blue.mat
│ ├── Blue.mat.meta
│ ├── Green.mat
│ ├── Green.mat.meta
│ ├── Red.mat
│ └── Red.mat.meta
│ ├── MultipoolDemo.meta
│ ├── MultipoolDemo.unity
│ ├── MultipoolDemo.unity.meta
│ ├── MultipoolDemo
│ ├── LightingData.asset
│ ├── LightingData.asset.meta
│ ├── ReflectionProbe-0.exr
│ └── ReflectionProbe-0.exr.meta
│ ├── Prefabs.meta
│ ├── Prefabs
│ ├── Blue_Bullet.prefab
│ ├── Blue_Bullet.prefab.meta
│ ├── Green_Bullet.prefab
│ ├── Green_Bullet.prefab.meta
│ ├── Red_Bullet.prefab
│ └── Red_Bullet.prefab.meta
│ ├── Scripts.meta
│ └── Scripts
│ ├── BulletStartDemo.cs
│ └── BulletStartDemo.cs.meta
├── package.json
└── package.json.meta
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4ba0151638ffbb2438e56bd758bec9a7
3 | folderAsset: yes
4 | timeCreated: 1477699146
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Editor/F10.Multipool.Editor.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "F10.Multipool.Editor",
3 | "rootNamespace": "",
4 | "references": [
5 | "GUID:8ceef2819eb8ee94eb93ba11a0c3fcff"
6 | ],
7 | "includePlatforms": [
8 | "Editor"
9 | ],
10 | "excludePlatforms": [],
11 | "allowUnsafeCode": false,
12 | "overrideReferences": false,
13 | "precompiledReferences": [],
14 | "autoReferenced": true,
15 | "defineConstraints": [],
16 | "versionDefines": [],
17 | "noEngineReferences": false
18 | }
--------------------------------------------------------------------------------
/Editor/F10.Multipool.Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e8662dff7d9b05e478598db3ac4c203d
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Editor/Icons.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bb92bdb2dc130064aacded5b6c0124de
3 | folderAsset: yes
4 | timeCreated: 1492233681
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolEmitterEditor_Icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AdamCarballo/Unity-MultiPool/f8e2c2c1a9cc40a4e1b0934d7ac6ba7d9e833ce8/Editor/Icons/MultipoolEmitterEditor_Icon64.png
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolEmitterEditor_Icon64.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e2afd78b6b2ec8b44817525c939a5bab
3 | timeCreated: 1492234167
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 4
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 0
11 | sRGBTexture: 0
12 | linearTexture: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 6
25 | cubemapConvolution: 0
26 | seamlessCubemap: 0
27 | textureFormat: 1
28 | maxTextureSize: 2048
29 | textureSettings:
30 | filterMode: -1
31 | aniso: -1
32 | mipBias: -1
33 | wrapMode: 1
34 | nPOTScale: 1
35 | lightmap: 0
36 | compressionQuality: 50
37 | spriteMode: 0
38 | spriteExtrude: 1
39 | spriteMeshType: 1
40 | alignment: 0
41 | spritePivot: {x: 0.5, y: 0.5}
42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
43 | spritePixelsToUnits: 100
44 | alphaUsage: 1
45 | alphaIsTransparency: 1
46 | spriteTessellationDetail: -1
47 | textureType: 2
48 | textureShape: 1
49 | maxTextureSizeSet: 0
50 | compressionQualitySet: 0
51 | textureFormatSet: 0
52 | platformSettings:
53 | - buildTarget: DefaultTexturePlatform
54 | maxTextureSize: 64
55 | textureFormat: -1
56 | textureCompression: 0
57 | compressionQuality: 50
58 | crunchedCompression: 0
59 | allowsAlphaSplitting: 0
60 | overridden: 0
61 | - buildTarget: Standalone
62 | maxTextureSize: 64
63 | textureFormat: -1
64 | textureCompression: 0
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | spriteSheet:
70 | serializedVersion: 2
71 | sprites: []
72 | outline: []
73 | spritePackingTag:
74 | userData:
75 | assetBundleName:
76 | assetBundleVariant:
77 |
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolEmmiter_Icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AdamCarballo/Unity-MultiPool/f8e2c2c1a9cc40a4e1b0934d7ac6ba7d9e833ce8/Editor/Icons/MultipoolEmmiter_Icon64.png
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolEmmiter_Icon64.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 46d23c4574ef76348baf96dd7e9d3fcc
3 | timeCreated: 1492233931
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 4
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 0
11 | sRGBTexture: 0
12 | linearTexture: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 6
25 | cubemapConvolution: 0
26 | seamlessCubemap: 0
27 | textureFormat: 1
28 | maxTextureSize: 2048
29 | textureSettings:
30 | filterMode: -1
31 | aniso: -1
32 | mipBias: -1
33 | wrapMode: 1
34 | nPOTScale: 1
35 | lightmap: 0
36 | compressionQuality: 50
37 | spriteMode: 0
38 | spriteExtrude: 1
39 | spriteMeshType: 1
40 | alignment: 0
41 | spritePivot: {x: 0.5, y: 0.5}
42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
43 | spritePixelsToUnits: 100
44 | alphaUsage: 1
45 | alphaIsTransparency: 1
46 | spriteTessellationDetail: -1
47 | textureType: 2
48 | textureShape: 1
49 | maxTextureSizeSet: 0
50 | compressionQualitySet: 0
51 | textureFormatSet: 0
52 | platformSettings:
53 | - buildTarget: DefaultTexturePlatform
54 | maxTextureSize: 64
55 | textureFormat: -1
56 | textureCompression: 0
57 | compressionQuality: 50
58 | crunchedCompression: 0
59 | allowsAlphaSplitting: 0
60 | overridden: 0
61 | - buildTarget: Standalone
62 | maxTextureSize: 64
63 | textureFormat: -1
64 | textureCompression: 0
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | spriteSheet:
70 | serializedVersion: 2
71 | sprites: []
72 | outline: []
73 | spritePackingTag:
74 | userData:
75 | assetBundleName:
76 | assetBundleVariant:
77 |
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolManagerEditor_Icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AdamCarballo/Unity-MultiPool/f8e2c2c1a9cc40a4e1b0934d7ac6ba7d9e833ce8/Editor/Icons/MultipoolManagerEditor_Icon64.png
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolManagerEditor_Icon64.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3e9b6b6b46f4b7247a00d4da845c0c61
3 | timeCreated: 1492234240
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 4
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 0
11 | sRGBTexture: 0
12 | linearTexture: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 6
25 | cubemapConvolution: 0
26 | seamlessCubemap: 0
27 | textureFormat: 1
28 | maxTextureSize: 2048
29 | textureSettings:
30 | filterMode: -1
31 | aniso: -1
32 | mipBias: -1
33 | wrapMode: 1
34 | nPOTScale: 1
35 | lightmap: 0
36 | compressionQuality: 50
37 | spriteMode: 0
38 | spriteExtrude: 1
39 | spriteMeshType: 1
40 | alignment: 0
41 | spritePivot: {x: 0.5, y: 0.5}
42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
43 | spritePixelsToUnits: 100
44 | alphaUsage: 1
45 | alphaIsTransparency: 1
46 | spriteTessellationDetail: -1
47 | textureType: 2
48 | textureShape: 1
49 | maxTextureSizeSet: 0
50 | compressionQualitySet: 0
51 | textureFormatSet: 0
52 | platformSettings:
53 | - buildTarget: DefaultTexturePlatform
54 | maxTextureSize: 64
55 | textureFormat: -1
56 | textureCompression: 0
57 | compressionQuality: 50
58 | crunchedCompression: 0
59 | allowsAlphaSplitting: 0
60 | overridden: 0
61 | - buildTarget: Standalone
62 | maxTextureSize: 64
63 | textureFormat: -1
64 | textureCompression: 0
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | spriteSheet:
70 | serializedVersion: 2
71 | sprites: []
72 | outline: []
73 | spritePackingTag:
74 | userData:
75 | assetBundleName:
76 | assetBundleVariant:
77 |
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolManager_Icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AdamCarballo/Unity-MultiPool/f8e2c2c1a9cc40a4e1b0934d7ac6ba7d9e833ce8/Editor/Icons/MultipoolManager_Icon64.png
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolManager_Icon64.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4b0bd43a99554d447a29a8b5b564c668
3 | timeCreated: 1492233828
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 4
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 0
11 | sRGBTexture: 0
12 | linearTexture: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 6
25 | cubemapConvolution: 0
26 | seamlessCubemap: 0
27 | textureFormat: 1
28 | maxTextureSize: 2048
29 | textureSettings:
30 | filterMode: 1
31 | aniso: -1
32 | mipBias: -1
33 | wrapMode: 1
34 | nPOTScale: 1
35 | lightmap: 0
36 | compressionQuality: 50
37 | spriteMode: 0
38 | spriteExtrude: 1
39 | spriteMeshType: 1
40 | alignment: 0
41 | spritePivot: {x: 0.5, y: 0.5}
42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
43 | spritePixelsToUnits: 100
44 | alphaUsage: 1
45 | alphaIsTransparency: 1
46 | spriteTessellationDetail: -1
47 | textureType: 2
48 | textureShape: 1
49 | maxTextureSizeSet: 0
50 | compressionQualitySet: 0
51 | textureFormatSet: 0
52 | platformSettings:
53 | - buildTarget: DefaultTexturePlatform
54 | maxTextureSize: 64
55 | textureFormat: -1
56 | textureCompression: 0
57 | compressionQuality: 50
58 | crunchedCompression: 0
59 | allowsAlphaSplitting: 0
60 | overridden: 0
61 | - buildTarget: Standalone
62 | maxTextureSize: 64
63 | textureFormat: -1
64 | textureCompression: 0
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | spriteSheet:
70 | serializedVersion: 2
71 | sprites: []
72 | outline: []
73 | spritePackingTag:
74 | userData:
75 | assetBundleName:
76 | assetBundleVariant:
77 |
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolReset_Icon64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AdamCarballo/Unity-MultiPool/f8e2c2c1a9cc40a4e1b0934d7ac6ba7d9e833ce8/Editor/Icons/MultipoolReset_Icon64.png
--------------------------------------------------------------------------------
/Editor/Icons/MultipoolReset_Icon64.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 31f059655d0698e469ce7cceb368ce6b
3 | timeCreated: 1492234313
4 | licenseType: Pro
5 | TextureImporter:
6 | fileIDToRecycleName: {}
7 | serializedVersion: 4
8 | mipmaps:
9 | mipMapMode: 0
10 | enableMipMap: 0
11 | sRGBTexture: 0
12 | linearTexture: 0
13 | fadeOut: 0
14 | borderMipMap: 0
15 | mipMapFadeDistanceStart: 1
16 | mipMapFadeDistanceEnd: 3
17 | bumpmap:
18 | convertToNormalMap: 0
19 | externalNormalMap: 0
20 | heightScale: 0.25
21 | normalMapFilter: 0
22 | isReadable: 0
23 | grayScaleToAlpha: 0
24 | generateCubemap: 6
25 | cubemapConvolution: 0
26 | seamlessCubemap: 0
27 | textureFormat: 1
28 | maxTextureSize: 2048
29 | textureSettings:
30 | filterMode: -1
31 | aniso: -1
32 | mipBias: -1
33 | wrapMode: 1
34 | nPOTScale: 1
35 | lightmap: 0
36 | compressionQuality: 50
37 | spriteMode: 0
38 | spriteExtrude: 1
39 | spriteMeshType: 1
40 | alignment: 0
41 | spritePivot: {x: 0.5, y: 0.5}
42 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
43 | spritePixelsToUnits: 100
44 | alphaUsage: 1
45 | alphaIsTransparency: 1
46 | spriteTessellationDetail: -1
47 | textureType: 2
48 | textureShape: 1
49 | maxTextureSizeSet: 0
50 | compressionQualitySet: 0
51 | textureFormatSet: 0
52 | platformSettings:
53 | - buildTarget: DefaultTexturePlatform
54 | maxTextureSize: 64
55 | textureFormat: -1
56 | textureCompression: 0
57 | compressionQuality: 50
58 | crunchedCompression: 0
59 | allowsAlphaSplitting: 0
60 | overridden: 0
61 | - buildTarget: Standalone
62 | maxTextureSize: 64
63 | textureFormat: -1
64 | textureCompression: 0
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | spriteSheet:
70 | serializedVersion: 2
71 | sprites: []
72 | outline: []
73 | spritePackingTag:
74 | userData:
75 | assetBundleName:
76 | assetBundleVariant:
77 |
--------------------------------------------------------------------------------
/Editor/MultipoolEmitterEditor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * MultipoolEmitterEditor.cs
3 | * Editor Script. Generates the popup list from ObjectPooling.generatedEnum.
4 | *
5 | * by Adam Carballo under MIT license.
6 | * https://github.com/AdamCarballo/Unity-MultiPool
7 | */
8 |
9 | using System.Linq;
10 | using UnityEditor;
11 |
12 | namespace F10.Multipool.Editor {
13 | [CustomEditor(typeof(MultipoolEmitter))]
14 | public class MultipoolEmitterEditor : UnityEditor.Editor {
15 |
16 | private SerializedProperty _index; // int
17 |
18 | ///
19 | /// Set MultipoolEmitter and configure the popup index.
20 | ///
21 | private void OnEnable() {
22 | serializedObject.Update();
23 |
24 | _index = serializedObject.FindProperty("_index");
25 | }
26 |
27 | ///
28 | /// Draw the popup on the inspector and save a copy locally.
29 | ///
30 | public override void OnInspectorGUI() {
31 | serializedObject.Update();
32 |
33 | EditorGUILayout.HelpBox(
34 | "Remember to index the object pools to make them appear on the Emitter list.",
35 | MessageType.Info
36 | );
37 |
38 | var poolNames = MultipoolManagerEditor.PoolNames.ToArray();
39 | _index.intValue = EditorGUILayout.Popup("Selected Pool", _index.intValue, poolNames);
40 |
41 | serializedObject.ApplyModifiedProperties();
42 | }
43 |
44 | }
45 | }
--------------------------------------------------------------------------------
/Editor/MultipoolEmitterEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fc928df0a13f61649b6aafa5e5880a59
3 | timeCreated: 1492234202
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {fileID: 2800000, guid: e2afd78b6b2ec8b44817525c939a5bab, type: 3}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Editor/MultipoolManagerEditor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * MultipoolEditor.cs
3 | * Editor Script. Draws Button and HelpBox on the inspector.
4 | *
5 | * by Adam Carballo under MIT license.
6 | * https://github.com/AdamCarballo/Unity-MultiPool
7 | */
8 |
9 | using System.Collections.Generic;
10 | using System.Linq;
11 | using System.Text;
12 | using UnityEditor;
13 | using UnityEngine;
14 |
15 | namespace F10.Multipool.Editor {
16 | [CustomEditor(typeof(MultipoolManager))]
17 | public class MultipoolManagerEditor : UnityEditor.Editor {
18 |
19 | private const string PoolNamePrefName = "Multipool_PoolNames";
20 |
21 | private static List poolNames = null;
22 |
23 | public static IEnumerable PoolNames {
24 | get {
25 | if (poolNames == null) {
26 | GenerateEmitterEnum();
27 | }
28 |
29 | return poolNames;
30 | }
31 | }
32 |
33 | private static readonly string[] _excludeList = {"m_Script"};
34 |
35 | private MultipoolManager _multipool;
36 |
37 | private GUIStyle _runtimeHelpBoxStyle = null;
38 |
39 | private GUIStyle RuntimeHelpBoxStyle =>
40 | _runtimeHelpBoxStyle ??= new GUIStyle(GUI.skin.GetStyle("HelpBox")) {
41 | richText = true,
42 | alignment = TextAnchor.UpperCenter,
43 | contentOffset = new Vector2(0, 3)
44 | };
45 |
46 | private GUIStyle _runtimeHelpBoxPlayingStyle = null;
47 |
48 | private GUIStyle RuntimeHelpBoxPlayingStyle =>
49 | _runtimeHelpBoxPlayingStyle ??= new GUIStyle(_runtimeHelpBoxStyle) {
50 | richText = true,
51 | alignment = TextAnchor.UpperLeft,
52 | contentOffset = new Vector2(10, 8)
53 | };
54 |
55 | ///
56 | /// Set the script reference.
57 | ///
58 | private void OnEnable() {
59 | _multipool = (MultipoolManager) target;
60 | }
61 |
62 | ///
63 | /// Draw a Button with a call action to GenerateEnum(), draw a HelpBox and hide the MonoBehaviour script.
64 | ///
65 | public override void OnInspectorGUI() {
66 | EditorGUILayout.TextArea(
67 | "MultiPool v1.3\n" +
68 | "https://github.com/AdamCarballo/Unity-MultiPool\n"
69 | , RuntimeHelpBoxStyle);
70 |
71 | if (Application.isPlaying) {
72 | EditorGUILayout.TextArea(
73 | $"Runtime Stats\n\n{GetRuntimeInformation()}",
74 | RuntimeHelpBoxPlayingStyle);
75 | } else {
76 | EditorGUILayout.HelpBox(
77 | "Remember to index the object pools to make them appear on the Emitter list.",
78 | MessageType.Info
79 | );
80 | if (GUILayout.Button("Index Object Pools")) {
81 | SaveEmitterEnum();
82 | GenerateEmitterEnum();
83 | }
84 | }
85 |
86 | EditorGUILayout.Space();
87 |
88 | serializedObject.Update();
89 | DrawPropertiesExcluding(serializedObject, _excludeList);
90 | serializedObject.ApplyModifiedProperties();
91 |
92 | EditorUtility.SetDirty(target);
93 | }
94 |
95 | ///
96 | /// Returns current pool information, including active objects and objects created during runtime.
97 | ///
98 | /// Formatted string.
99 | private string GetRuntimeInformation() {
100 | var info = new StringBuilder();
101 | var allPools = _multipool.AllPools;
102 |
103 | foreach (var pool in allPools) {
104 | var activeAmount = pool.ActiveObjectAmount;
105 | var color = GetStatColor(pool, activeAmount);
106 | var extraAmount = pool.CurrentSize - pool.StartAmount;
107 |
108 | info.AppendLine($"{pool.Name} " +
109 | $"({activeAmount}/{pool.CurrentSize}) " +
110 | $"+ [{extraAmount}]");
111 | }
112 |
113 | return info.ToString();
114 | }
115 |
116 | ///
117 | /// Calculate the pool name color on the editor based on the current usage.
118 | ///
119 | /// Pool to check.
120 | /// Objects active from the pool.
121 | /// String with color name
122 | private static string GetStatColor(MultipoolPool pool, int activeObj) {
123 | float percentage = (float) activeObj / pool.CurrentSize;
124 |
125 | if (percentage < 0.75f) {
126 | return "green";
127 | }
128 |
129 | if (percentage < 0.95f) {
130 | return "orange";
131 | }
132 |
133 | if (pool.CanGrow) {
134 | return "maroon";
135 | }
136 |
137 | return "red";
138 | }
139 |
140 | private void SaveEmitterEnum() {
141 | var poolNamesFormatted = string.Join(",", _multipool.AllPools.Select(pool => pool.Name));
142 | EditorPrefs.SetString(PoolNamePrefName, poolNamesFormatted);
143 | }
144 |
145 | ///
146 | /// Generates a list of all the object pools names to be shown on an emitter's enum.
147 | ///
148 | private static void GenerateEmitterEnum() {
149 | poolNames = new List();
150 |
151 | // Load saved names for editor config
152 | var savedPoolNames = EditorPrefs.GetString(PoolNamePrefName);
153 | if (string.IsNullOrEmpty(savedPoolNames)) {
154 | // If no data is saved, try to find the manager in the scene
155 | var multipool = FindObjectOfType();
156 | if (multipool == null) {
157 | Debug.LogWarning("[MultiPool] Couldn't find any MultiPool data! Please re-index the pools.");
158 | return;
159 | }
160 |
161 | foreach (var pool in multipool.AllPools) {
162 | poolNames.Add(pool.Name);
163 | }
164 | } else {
165 | poolNames = savedPoolNames.Split(',').ToList();
166 | }
167 | }
168 |
169 | }
170 | }
--------------------------------------------------------------------------------
/Editor/MultipoolManagerEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6de03e42ddee046458f281786db15391
3 | timeCreated: 1492234266
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {fileID: 2800000, guid: 3e9b6b6b46f4b7247a00d4da845c0c61, type: 3}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Àdam Carballo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9a6c01e12e03c314989a08104eecd2ba
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Unity MultiPool
2 | =================
3 | 🗄 MultiPool - Expandable Object Pooling for Unity
4 |
5 | Overview
6 | ----
7 | Using object pooling to replace `Instantiate()` and `Destroy()` can help the CPU on games with multiple instances of the same object, like *bullet hell* games or *shooters*. It also helps enormously on mobile platforms with reduced CPU capabilities.
8 |
9 | Object pools will trade a little of memory footprint for a lower CPU usage. This is crucial for maintaining consistent framerates.
10 |
11 | This Object Pooling solution can be used for multiple objects and pools without the need of duplicating scripts or GameObjects.
12 |
13 | Install
14 | ----
15 | The source code is available directly from the repository.
16 | Though, it's recommended to add this code as a **Unity Package**, as it contains all required configurations.
17 |
18 | The original version of MultiPool (anything under v2) will work with any version of Unity 5. Newer versions (v2 and higher) haven't been tested in any version lower than Unity 2019.
19 |
20 | Usage
21 | ----
22 | Object Polling consists of two main scripts, `MultipoolManager.cs`and `MultipoolEmitter.cs`.
23 | Though, there are other optional scripts, like `MultipoolReset.cs` that allow quick setups for simple deployments.
24 |
25 | All scripts include the *`F10.Multipool`* namespace to avoid issues with existing scripts. Remember to use it.
26 |
27 | Add `MultipoolManager` to any GameObject to start using pools.
28 |
29 | #### MultipoolManager.cs
30 | Holds all the current object pools and handles internal calls for new objects.
31 | At `Start()` all the object pools will generate the amount of desired objects ready to be called.
32 |
33 | During runtime will display relevant information of how your object pools are performing.
34 |
35 | 
36 | ___
37 |
38 | #### MultipoolEmitter.cs
39 | Receives the amount of object pools available and displays them on a popup in the Inspector.
40 | Use this script to call an specific pool from the list of available pools using `Generate()`.
41 | ___
42 |
43 | ### Creating Object Pools:
44 | Change the size of `MultipoolManager._pools[]`in the inspector to generate more or less object pools.
45 |
46 | ```csharp
47 | Name; // Name of the object pool. Will appear on the generated popup.
48 | ObjectReference; // Object to pool.
49 | StartAmount; // Number of objects that will be generated on Start().
50 | CanGrow; // If true, the pool will generate more items than startAmount if needed.
51 | MaxGrow; // Limit of pool grow. 0 = unlimited.
52 | CustomParent; // Optional. Sets the object inside a parent for a cleaner Hierarchy.
53 | DisableIfGameObject; // Disable the available objects after generation if they are GameObjects.
54 | ```
55 |
56 | After finishing editing the pools, remember to press **Index Object Pools** button to display them correctly.
57 |
58 | ### Extracting objects from Object Pools:
59 | Define the pool to be used with the `MultipoolEmitter` popup in the inspector.
60 | Keep in mind that you first need to **Index Object Pools** if the popup appears empty.
61 |
62 | Using `MultipoolEmitter.Generate()` will return an object from the desired pool.
63 | `Generate()`can also return `null` if the pool is empty and `CanGrow` is set to false, or `MaxGrow` has reached the limit.
64 |
65 | Example using `BulletStartDemo.cs`:
66 |
67 | ```csharp
68 | [Range(0.1f, 2f)]
69 | [SerializeField]
70 | private float _fireTime;
71 | private MultipoolEmitter _emitter;
72 |
73 | ///
74 | /// Reference the Emitter.
75 | ///
76 | private void Awake() {
77 | _emitter = GetComponent();
78 | }
79 |
80 | ///
81 | /// Start generating each fireTime.
82 | ///
83 | private void Start() {
84 | StartCoroutine(SpawnNew());
85 | }
86 |
87 | ///
88 | /// Retrieve from the object pool, check if null, reset position, rotation and set active.
89 | ///
90 | private IEnumerator SpawnNew() {
91 | while (true) {
92 | var obj = _emitter.GenerateGameObject();
93 |
94 | if (obj != null) {
95 | var thisTransform = transform;
96 | obj.transform.position = thisTransform.position;
97 | obj.transform.rotation = thisTransform.rotation;
98 | }
99 |
100 | yield return new WaitForSeconds(_fireTime);
101 | }
102 | }
103 | ```
104 |
105 | If using the `MultipoolEmitter` is not a good idea in your case (for example, you need multiple objects from different pools in one script), you can access `MultipoolManager` directly using the singleton instance `MultipoolManager.Instance`.
106 | To get an object from a pool, use the function `MultipoolManager.GetPooledObject(int index)` where `index` is the id of the list (position on the inspector).
107 | There is also `MultipoolManager.GetPooledObject(string poolName)` where `poolName` is the name of the pool, although this method is more performance intensive.
108 |
109 |
110 | Feel free to inspect all functions inside `MultipoolManager` to make it work with your code.
111 |
112 | ### Returning objects to Object Pools:
113 | The source already includes `MultipoolReset.cs` as an example.
114 | The only requirement is to call `MultipoolEmitter.Return()` (when using the provided emitter), or `MultipoolManager.ReturnPooledObject(T obj, int index / string poolName)` to return an object to the pool.
115 |
116 | If you use the object on other lists or arrays, remember to also remove it.
117 | It's also recommended to reset `Rigidbody.velocity`if the object uses physics.
118 |
119 | Demo
120 | ----
121 | The `Samples~` folder in the source code (included in the Unity Package as a sample) includes a demo scene to understand how everything works.
122 |
123 | History
124 | ----
125 | Created by Àdam Carballo
126 | Check other works on *[F10.DEV](https://f10.dev)*
127 |
128 | License
129 | ---
130 | MIT License
131 | Script icons by [Game-Icons.net](https://game-icons.net/)
132 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 68f2f0b27bb0e904ea5dfb0c573ff2fb
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 093fe50dcfb8ef04ba9e14be41fd668a
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/F10.Multipool.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "F10.Multipool"
3 | }
4 |
--------------------------------------------------------------------------------
/Runtime/F10.Multipool.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8ceef2819eb8ee94eb93ba11a0c3fcff
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime/MultipoolEmitter.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * MultipoolEmitter.cs
3 | * Emitter Configurator. Extract objects with MultipoolEmitter.Generate();
4 | *
5 | * This emitter has a helper class that supports GameObjects by default, and works best with a MultipoolReset attached to the pooled objects.
6 | * This script is not required to interact with the MultipoolManager, but the custom inspector may be useful when configuring multiple pools.
7 | *
8 | * by Adam Carballo under MIT license.
9 | * https://github.com/AdamCarballo/Unity-MultiPool
10 | */
11 |
12 | using UnityEngine;
13 | using JetBrains.Annotations;
14 |
15 | namespace F10.Multipool {
16 | public class MultipoolEmitter : MonoBehaviour {
17 |
18 | [HideInInspector]
19 | public int _index;
20 |
21 | ///
22 | /// Retrieve from the index GameObject pool, check if null, and return the object already activated to the caller.
23 | ///
24 | /// Pooled GameObject or null.
25 | [CanBeNull]
26 | public GameObject GenerateGameObject() {
27 | var obj = MultipoolManager.Instance.GetPooledObject(_index);
28 | if (obj == null) return null;
29 |
30 | var reset = obj.GetComponent();
31 | if (reset != null) {
32 | reset.Emitter = this;
33 | }
34 |
35 | obj.SetActive(true);
36 | return obj;
37 | }
38 |
39 | ///
40 | /// Retrieve from the index object pool, check if null, and return the object already activated to the caller.
41 | ///
42 | /// This method does not support MultipoolReset by default.
43 | ///
44 | /// Pooled object or null.
45 | [CanBeNull]
46 | public T Generate() where T : Object {
47 | return MultipoolManager.Instance.GetPooledObject(_index);
48 | }
49 |
50 | ///
51 | /// Disable the passed GameObject and send it back into the pool.
52 | ///
53 | /// GameObject to return.
54 | public void ReturnGameObject(GameObject @object) {
55 | @object.SetActive(false);
56 | MultipoolManager.Instance.ReturnPooledObject(@object, _index);
57 | }
58 |
59 | ///
60 | /// Send the passed object back into the pool.
61 | ///
62 | /// Object to return.
63 | public void Return(T @object) where T : Object {
64 | MultipoolManager.Instance.ReturnPooledObject(@object, _index);
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/Runtime/MultipoolEmitter.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 309382c06730cc74ea23dea13141b45b
3 | timeCreated: 1492233968
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {fileID: 2800000, guid: 46d23c4574ef76348baf96dd7e9d3fcc, type: 3}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Runtime/MultipoolManager.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Multipool.cs
3 | * Manage the pooling of any object and calls to retrieve them.
4 | *
5 | * by Adam Carballo under MIT license.
6 | * https://github.com/AdamCarballo/Unity-MultiPool
7 | */
8 |
9 | using System;
10 | using UnityEngine;
11 | using System.Collections.Generic;
12 | using JetBrains.Annotations;
13 | using Object = UnityEngine.Object;
14 |
15 | namespace F10.Multipool {
16 | [HelpURL("https://github.com/AdamCarballo/Unity-MultiPool")]
17 | [DefaultExecutionOrder(-100)]
18 | public class MultipoolManager : MonoBehaviour {
19 |
20 | public static MultipoolManager Instance { get; private set; } = null;
21 |
22 | [SerializeField]
23 | private MultipoolPool[] _pools;
24 |
25 | public IEnumerable AllPools => _pools;
26 |
27 | ///
28 | /// Define instance and check for duplicated pools.
29 | ///
30 | private void Awake() {
31 | if (Instance != null) {
32 | Debug.LogError("[MultiPool] MultiPool can only exist once in the scene!");
33 | #if UNITY_EDITOR
34 | UnityEditor.EditorApplication.isPaused = true;
35 | #endif
36 | }
37 |
38 | Instance = this;
39 | }
40 |
41 | ///
42 | /// Instantiate the startAmount of poolObject and deactivate them.
43 | ///
44 | private void Start() {
45 | foreach (var pool in _pools) {
46 | pool.StartPool();
47 | }
48 | }
49 |
50 | ///
51 | /// Returns an available object. If there isn't one, and canGrow, will create a new one.
52 | ///
53 | /// It is recommended to use an emitter or use the overload of GetPooledObject() that uses a pools index for better performance.
54 | ///
55 | /// Name of the pool.
56 | /// Available object marked as active, or null if the pool is empty.
57 | [CanBeNull]
58 | public T GetPooledObject(string poolName) where T : Object {
59 | for (int i = 0; i < _pools.Length; i++) {
60 | if (_pools[i].Name == poolName) {
61 | return GetPooledObject(i);
62 | }
63 | }
64 |
65 | throw new ArgumentException($"[MultiPool] There is no pool with the name {poolName}");
66 | }
67 |
68 | ///
69 | /// Returns an available object. If there isn't one, and canGrow, will create a new one.
70 | ///
71 | /// Index of the pool.
72 | /// Available object marked as active, or null if the pool is empty.
73 | [CanBeNull]
74 | public T GetPooledObject(int index) where T : Object {
75 | var pool = _pools[index];
76 | return pool.GetPooledObject() as T;
77 | }
78 |
79 | ///
80 | /// Marks the passed object as available to the pool to be re-used.
81 | ///
82 | /// Name of the pool.
83 | /// Object to return.
84 | public void ReturnPooledObject(T obj, string poolName) where T : Object {
85 | for (int i = 0; i < _pools.Length; i++) {
86 | if (_pools[i].Name == poolName) {
87 | ReturnPooledObject(obj, i);
88 | }
89 | }
90 |
91 | throw new ArgumentException($"[MultiPool] There is no pool with the name {poolName}");
92 | }
93 |
94 | ///
95 | /// Marks the passed object as available to the pool to be re-used.
96 | ///
97 | /// Index of the pool.
98 | /// Object to return.
99 | public void ReturnPooledObject(T obj, int index) where T : Object {
100 | var pool = _pools[index];
101 | pool.ReturnPooledObject(obj.GetInstanceID());
102 | }
103 |
104 | }
105 | }
--------------------------------------------------------------------------------
/Runtime/MultipoolManager.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7d7f04dff4ef2da4595c21655fb1b01a
3 | timeCreated: 1492233847
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {fileID: 2800000, guid: 4b0bd43a99554d447a29a8b5b564c668, type: 3}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Runtime/MultipoolPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 | using UnityEngine;
5 | using Object = UnityEngine.Object;
6 |
7 | namespace F10.Multipool {
8 | [Serializable]
9 | public class MultipoolPool {
10 |
11 | [Tooltip("Name of this pool as it will appear on the dropdown of the emitters.")]
12 | [SerializeField]
13 | private string _name;
14 |
15 | public string Name => _name;
16 |
17 | [Tooltip("Object to be pooled.")]
18 | [SerializeField]
19 | private Object _objectReference;
20 |
21 | [Tooltip("How many objects will get pre-spawned before the scene starts (pool size).")]
22 | [SerializeField]
23 | private int _startAmount;
24 |
25 | public int StartAmount => _startAmount;
26 |
27 | [Tooltip("Can this pool grow if the requested items are higher than the start amount.")]
28 | [SerializeField]
29 | private bool _canGrow = true;
30 |
31 | public bool CanGrow {
32 | get => _canGrow;
33 | set => _canGrow = value;
34 | }
35 |
36 | [Tooltip("Limit of pool grow. 0 = unlimited.")]
37 | [SerializeField]
38 | private int _maxGrow = 0;
39 |
40 | public int MaxGrow {
41 | get => _maxGrow;
42 | set => _maxGrow = value;
43 | }
44 |
45 | [Tooltip("Will this pool spawn objects inside a custom parent, or use the default one.")]
46 | [SerializeField]
47 | private Transform _customParent;
48 |
49 | public Transform CustomParent {
50 | get => _customParent;
51 | set => _customParent = value;
52 | }
53 |
54 | [Tooltip("Disable the available objects after generation if they are GameObjects.")]
55 | [SerializeField]
56 | private bool _disableIfGameObject = true;
57 |
58 | private Stack