Ok so breakdown all this mess 
Master_GameManager.cs :
using UnityEngine;
using System.Collections;
using PoolSystem;
public class Master_GameManager : MonoBehaviour {
// For the singleton pattern
public static Master_GameManager gameManager;
public ObjectPoolingManager poolManager;
// To access others masters
public Master_PlayerDataManager playerDataManager;
// Properties
// Events
// Use this for initialization (singleton pattern)
public void Awake() {
if (gameManager == null) {
gameManager = this;
DontDestroyOnLoad(gameObject);
} else {
Destroy(gameObject);
}
// Init Managers /!\ Order is important /!\
poolManager = new ObjectPoolingManager();
// Create Fx, etc.. Pools.
playerDataManager = new Master_PlayerDataManager();
playerDataManager.Initialization();
}
}
This is the starting point of my application the only Awake() call. This monobehaviour is attached to a game object in my scene. It need to be the center for all my others manager that are not monobehaviours. Let’s take a look at these.
Master_PlayerDataManager.cs :
using UnityEngine;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Ability_System;
using PoolSystem;
public class Master_PlayerDataManager {
/*
* This class is sort of a base for every other "same" kind of class.
* TODO:
* - Change path system: Create string variable instead. √
*/
// Used for serialization and de-serialization and containing player datas.
// Should be accessible from the outside
public Data_Player dataPlayer = new Data_Player();
// Player Spells
[HideInInspector] public Ability_Spell playerMainSpell;
[HideInInspector] public Ability_Spell playerSecondarySpell;
private ObjectPoolingManager poolManager;
// Private Vars
string dataFilePath;
// Constructor
public void Initialization() {
dataFilePath = Application.persistentDataPath + "/Data_player.dat";
poolManager = Master_GameManager.gameManager.poolManager;
if (!PlayerDataLoad()) {
InitDefaultPlayerData();
}
ChangePlayerMainSpell(dataPlayer.mainSpell);
ChangePlayerSecondarySpell(dataPlayer.secondarySpell);
}
public void InitDefaultPlayerData() {
dataPlayer.maxHealth = 100;
dataPlayer.health = 100;
dataPlayer.maxMana = 200;
dataPlayer.mana = 200;
dataPlayer.speed = 1f;
dataPlayer.mainSpell = "Fireball";
dataPlayer.secondarySpell = "Firenova";
}
public void ChangePlayerMainSpell(string newSpellName) {
playerMainSpell = (Ability_Spell)Resources.Load("Abilities/" + newSpellName);
poolManager.CreatePool(playerMainSpell.prefab, 20, 50, true); // Create new ability pool
poolManager.DeletePool(dataPlayer.mainSpell); // Try to delete old ability pool
dataPlayer.mainSpell = newSpellName;
}
public void ChangePlayerSecondarySpell(string newSpellName) {
playerSecondarySpell = (Ability_Spell)Resources.Load("Abilities/" + newSpellName);
//poolManager.CreatePool(playerSecondarySpell.prefab, 20, 50, true); // Create new ability pool
//poolManager.DeletePool(dataPlayer.secondarySpell); // Try to delete old ability pool
dataPlayer.secondarySpell = newSpellName;
}
public bool PlayerDataLoad() {
if (File.Exists(dataFilePath)) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(dataFilePath, FileMode.Open);
dataPlayer = (Data_Player)bf.Deserialize(file);
file.Close();
return true;
}
return false;
}
public void PlayerDataSave() {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(dataFilePath);
bf.Serialize(file, dataPlayer);
file.Close();
}
}
a more complex script indeed. So no need of building an empty constructor because it won’t do nothing. I have the Initialization() function that will … initialize 
as I said I create my pools here. (one for each Spell of the player) In this script there is no error thrown by the compiler
Just to show you 
So let’s take my spell caster script.
using UnityEngine;
using System.Collections;
using Ability_System;
using PoolSystem;
public class Player_SpellCaster : MonoBehaviour {
// ref
Master_PlayerDataManager playerDataManager;
Data_Player playerData;
ObjectPoolingManager poolManager;
// vars
Ability_Spell mainSpell;
Ability_Spell secondarySpell;
GameObject instance;
float mainSpellNextFire;
float secondarySpellNextFire;
float time;
// init
void Start() {
playerDataManager = Master_GameManager.gameManager.playerDataManager;
playerData = playerDataManager.dataPlayer;
mainSpell = playerDataManager.playerMainSpell;
secondarySpell = playerDataManager.playerSecondarySpell;
poolManager = Master_GameManager.gameManager.poolManager;
}
// Update is called once per frame
void Update() {
// update refs if needed.
if (mainSpell.name != playerData.mainSpell) {
// Update ref
mainSpell = playerDataManager.playerMainSpell;
}
if (secondarySpell.name != playerData.secondarySpell) {
// Update ref
secondarySpell = playerDataManager.playerSecondarySpell;
}
time = Time.time;
if ((Input.GetMouseButton(0)) && (time > mainSpellNextFire)) { // Left click
mainSpellNextFire = Time.time + mainSpell.cooldown;
CastSpell(mainSpell);
} else if ((Input.GetMouseButton(1)) && (time > secondarySpellNextFire)) { // Right click
secondarySpellNextFire = Time.time + secondarySpell.cooldown;
CastSpell(secondarySpell);
}
}
void CastSpell(Ability_Spell spellToCast) {
/*
* TODO:
* -
*/
switch (spellToCast.type) {
case Ability_Types.PROJECTILE:
// Cast Projectile code
Vector2 target = Camera.main.ScreenToWorldPoint(new Vector2(Input.mousePosition.x, Input.mousePosition.y));
Vector2 myPos = new Vector2(transform.position.x, transform.position.y);
Vector2 direction = target - myPos;
direction.Normalize();
Quaternion rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg - 90);
instance = poolManager.GetObject(spellToCast.abilityName);
instance.transform.position = myPos;
instance.transform.rotation = rotation;
instance.GetComponent<Rigidbody2D>().velocity = direction * spellToCast.speed;
instance.SetActive(true);
break;
case Ability_Types.NOVA:
// Cast Nova code
break;
default:
break;
}
Debug.Log("Spell Casted Name :" + spellToCast.name);
}
}
Here everything start to get funny. When I set up my references here my poolManager have no pool in it. And when I trace I know that I create one. So let’s take a loot at the poolingManager.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace PoolSystem {
public class ObjectPoolingManager {
//look up list of various object pools.
private Dictionary<String, ObjectPool> objectPools;
public ObjectPoolingManager() {
//Ensure object pools exists.
objectPools = new Dictionary<String, ObjectPool>();
}
public bool CreatePool(GameObject objToPool, int initialPoolSize, int maxPoolSize, bool shouldShrink) {
//Check to see if the pool already exists.
if (objectPools.ContainsKey(objToPool.name)) {
//let the caller know it already exists, just use the pool out there.
return false;
} else {
//create a new pool using the properties
ObjectPool nPool = new ObjectPool(objToPool, initialPoolSize, maxPoolSize, shouldShrink);
//Add the pool to the dictionary of pools to manage
//using the object name as the key and the pool as the value.
objectPools.Add(objToPool.name, nPool);
//We created a new pool!
return true;
}
}
public bool DeletePool(string name) {
if (objectPools.ContainsKey(name)) {
objectPools.Remove(name);
return true;
}
return false;
}
public GameObject GetObject(string objName) {
//Find the right pool and ask it for an object.
return objectPools[objName].GetObject();
}
}
}
When I get the instance from my gameManager the private Dictionary objectPools is empty (count=0) but when I trace the creation of the pool for my player mainspell objectPools have count=1…
Is the problem here ? because the dictionary is private ? That make no sens to me. If somebody could find where I’m false, this will help a lot 
Thanks everybody 