private void CreateGameObjectCaches()
    {
        //performance optimization: create all possible gameobjecs once instead of creating when needing
        GameObject wallObject = GameObject.CreatePrimitive(PrimitiveType.Cube);

        SetGameObjectColor(wallObject, GlobalVariables.WallColor);
        GameObject coinObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);

        SetGameObjectColor(coinObject, GlobalVariables.CoinColor);
        coinObject.GetComponent <Collider>().isTrigger = true;
        GameObject bonusObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);

        SetGameObjectColor(bonusObject, GlobalVariables.BonusColor);
        bonusObject.GetComponent <Collider>().isTrigger = true;
        GameObject fenceObject = GameObject.CreatePrimitive(PrimitiveType.Cube);

        SetGameObjectColor(fenceObject, GlobalVariables.FenceColor);
        GameObject enemyObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);

        SetGameObjectColor(enemyObject, GlobalVariables.EnemyColor);
        for (int i = 0; i < GlobalVariables.CalMaxObjectsOneLevel(); i++)
        {
            var wall = Instantiate(wallObject);
            wall.transform.localScale = GlobalVariables.WallScale;
            wall.tag = GlobalVariables.TagWall;
            wall.SetActive(false);
            _wallsCache.Add(wall);

            var coin = Instantiate(coinObject);
            coin.transform.localScale = GlobalVariables.CoinScale;
            coin.tag = GlobalVariables.TagCoins;
            coin.SetActive(false);
            _coinsCache.Add(coin);
        }

        for (int i = 0; i < GlobalVariables.CalMaxBonusOneLevel(); i++)
        {
            var bonus = Instantiate(bonusObject);
            bonus.transform.localScale = GlobalVariables.BonusScale;
            bonus.tag = GlobalVariables.TagBonus;
            bonus.SetActive(false);
            _bonusCache.Add(bonus);
        }

        for (int i = 0; i < GlobalVariables.CalMaxFenceCell(); i++)
        {
            var fence = Instantiate(fenceObject);
            fence.transform.localScale = GlobalVariables.FenceScale;
            fence.tag = GlobalVariables.TagFence;
            fence.SetActive(false);
            _fenceCache.Add(fence);
        }

        for (int i = 0; i < GlobalVariables.CalMaxEnemy(); i++)
        {
            //TODO: create various enemies based on the number of level
            var enemyInstansiate = Instantiate(enemyObject);
            enemyInstansiate.tag = GlobalVariables.TagEnemy;
            enemyInstansiate.transform.localScale = GlobalVariables.EnemyScale;
            enemyInstansiate.SetActive(false);
            BasicEnemyCharacter enemyCharacter = (BasicEnemyCharacter)CharacterFactory.Create(enemyInstansiate);
            enemyCharacter.ResetCharacter();
            enemyCharacter.CharacterDead();
            _enemyCache.Add(enemyCharacter);
        }

        Destroy(wallObject);
        Destroy(coinObject);
        Destroy(bonusObject);
        Destroy(fenceObject);
        Destroy(enemyObject);
    }