private void OnTemplatesAdd(ReorderableList _list)
        {
            if (templates.Count > 0)
            {
                SpriteTemplate _lastTemplate = templates[templates.Count - 1];
                SpriteTemplate _template     = new SpriteTemplate()
                {
                    DoBakeLights           = _lastTemplate.DoBakeLights,
                    DoUsePowerOfTwoTexture = _lastTemplate.DoUsePowerOfTwoTexture,

                    Layer        = _lastTemplate.Layer,
                    OrderInLayer = _lastTemplate.OrderInLayer,
                    Material     = _lastTemplate.Material,
                };

                templates.Add(_template);
            }
            else
            {
                templates.Add(new SpriteTemplate());
            }
        }
        // ----------------

        public void DrawSpriteScraper()
        {
            // GUIStyles initialization.
            if (!areGUIStylesInitialized)
            {
                areGUIStylesInitialized = true;

                headerInfoStyle           = new GUIStyle(EditorStyles.label);
                headerInfoStyle.alignment = TextAnchor.MiddleCenter;
            }

            // Sprite Scraper mode
            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            scraperMode = GUILayout.Toolbar(scraperMode, scraperModes, GUI.skin.button, GUI.ToolbarButtonSize.FitToContents, GUILayout.Height(25));
            EditorGUILayout.EndHorizontal();

            // Settings
            areSettingsUnfolded = EditorGUILayout.Foldout(areSettingsUnfolded, settingsGUI, true);
            if (areSettingsUnfolded)
            {
                EditorGUI.indentLevel++;

                // Save texture folder.
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.TextField(saveTextureFolderGUI, saveTextureFolder);

                Rect _rect = EditorGUILayout.GetControlRect(false, 16, GUILayout.Width(16));
                _rect.Set
                (
                    _rect.x - 2,
                    _rect.y - 1,
                    _rect.width + 2,
                    _rect.height + 1
                );
                if (GUI.Button(_rect, GUIContent.none))
                {
                    string _folder = EditorUtility.OpenFolderPanel(textureFolderPanel, string.Empty, string.Empty);
                    if (_folder.Contains(Application.dataPath))
                    {
                        doDisplayInvalidFolderMessage = false;
                        saveTextureFolder             = _folder.Remove(0, Application.dataPath.Length - 6) + Path.AltDirectorySeparatorChar;
                    }
                    else
                    {
                        doDisplayInvalidFolderMessage = true;
                    }
                }

                _rect.width = 30;
                _rect.x    -= (_rect.width / 2) - 2;
                _rect.y    += 1;
                EditorGUI.LabelField(_rect, EditorGUIUtility.IconContent(browseIconName));

                EditorGUILayout.EndHorizontal();
                if (doDisplayInvalidFolderMessage)
                {
                    EditorGUILayout.HelpBox(invalidFolderMessage, MessageType.Error);
                }

                // Unlit material.
                unlitMaterial = (Material)EditorGUILayout.ObjectField(unlitMaterialGUI, unlitMaterial, typeof(Material), false);


                EditorGUI.indentLevel--;
            }

            if (!unlitMaterial)
            {
                EditorGUILayout.HelpBox(noUnlitMessage, MessageType.Warning);
            }

            GUILayout.Space(5);
            EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.grey);
            GUILayout.Space(5);

            templatesList.DoLayoutList();

            // List cleaner buttons
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            if (GUILayout.Button(cleanButton) && EditorUtility.DisplayDialog(confirmDialogTitle, cleanMessage, confirmDialogOK, confirmDialogCancel))
            {
                templates.Clear();
            }
            if (GUILayout.Button(removeUnusedButton) && EditorUtility.DisplayDialog(confirmDialogTitle, removeUnusedMessage, confirmDialogOK, confirmDialogCancel))
            {
                for (int _i = 0; _i < templates.Count; _i++)
                {
                    if (!templates[_i].IsSelected)
                    {
                        templates.RemoveAt(_i);
                        _i--;
                    }
                }
            }

            GUILayout.EndHorizontal();

            // Merge scraps into beautiful artworks.
            if (GUILayout.Button(mergeScrapsGUI, GUILayout.MaxWidth(100), GUILayout.Height(25)))
            {
                #region Scraper
                if (templates.Count > 0)
                {
                    doDisplayNoTemplateMessage = false;

                    // Create and configure camera used to capture templates.
                    Camera _renderCamera = new GameObject().AddComponent <Camera>();
                    Rect   _viewport     = new Rect(0, 0, 1, 1);
                    _renderCamera.orthographic           = true;
                    _renderCamera.clearFlags             = CameraClearFlags.SolidColor;
                    _renderCamera.backgroundColor        = Color.clear;
                    _renderCamera.cullingMask            = ~2;
                    _renderCamera.allowDynamicResolution = true;

                    Renderer[]   _allRenderers  = FindObjectsOfType <Renderer>();
                    GameObject[] _artworks      = new GameObject[templates.Count];
                    int[]        _artworksLayer = new int[templates.Count];

                    for (int _n = 0; _n < templates.Count; _n++)
                    {
                        if (!templates[_n].IsSelected || !templates[_n].Root)
                        {
                            continue;
                        }

                        SpriteTemplate   _template = templates[_n];
                        SpriteRenderer[] _sprites  = _template.Root.GetComponentsInChildren <SpriteRenderer>();
                        SpriteMask[]     _masks    = _template.Root.GetComponentsInChildren <SpriteMask>();

                        // Set template bounds volume entirely in camera view.
                        Bounds _bounds = new Bounds(_sprites[0].bounds.center, _sprites[0].bounds.size);
                        for (int _i = 1; _i < _sprites.Length; _i++)
                        {
                            _bounds.Encapsulate(_sprites[_i].bounds);
                        }

                        _renderCamera.orthographicSize   = 5;
                        _renderCamera.transform.position = new Vector3(_bounds.center.x, _bounds.center.y, _bounds.center.z - 10);
                        while (!(_viewport.Contains(_renderCamera.WorldToViewportPoint(_bounds.min)) && _viewport.Contains(_renderCamera.WorldToViewportPoint(_bounds.max))))
                        {
                            _renderCamera.orthographicSize++;
                        }

                        // Set all visible renderers on a different layer (not visible anymore).
                        Plane[] _frustrumPlanes = GeometryUtility.CalculateFrustumPlanes(_renderCamera);
                        Dictionary <GameObject, int> _renderers = new Dictionary <GameObject, int>();
                        for (int _i = 0; _i < _allRenderers.Length; _i++)
                        {
                            if (GeometryUtility.TestPlanesAABB(_frustrumPlanes, _allRenderers[_i].bounds) &&
                                !_sprites.Contains(_allRenderers[_i]) && !_masks.Contains(_allRenderers[_i]) &&
                                !_renderers.ContainsKey(_allRenderers[_i].gameObject))
                            {
                                _renderers.Add(_allRenderers[_i].gameObject, _allRenderers[_i].gameObject.layer);
                                _allRenderers[_i].gameObject.layer = 1;
                            }
                        }

                        // Get artwork texture information and capture template.
                        Vector2    _offset     = _renderCamera.WorldToScreenPoint(_bounds.min);
                        Vector2    _boundsSize = (Vector2)_renderCamera.WorldToScreenPoint(_bounds.max) - _offset;
                        Vector2Int _size;
                        if (_template.DoUsePowerOfTwoTexture)
                        {
                            _size = new Vector2Int(Mathf.NextPowerOfTwo((int)_boundsSize.x), Mathf.NextPowerOfTwo((int)_boundsSize.y));
                        }
                        else
                        {
                            _size = new Vector2Int((int)_boundsSize.x, (int)_boundsSize.y);
                        }

                        RenderTexture _renderTexture = new RenderTexture(_renderCamera.pixelWidth, _renderCamera.pixelHeight, 32);
                        RenderTexture.active        = _renderTexture;
                        _renderCamera.targetTexture = _renderTexture;

                        // Set template sprites material to unlit if not baking light.
                        Material[] _spritesMaterial = null;
                        bool       _doNotBakeLight  = !_template.DoBakeLights && unlitMaterial;
                        if (_doNotBakeLight)
                        {
                            _spritesMaterial = new Material[_sprites.Length];
                            for (int _i = 0; _i < _sprites.Length; _i++)
                            {
                                _spritesMaterial[_i]  = _sprites[_i].sharedMaterial;
                                _sprites[_i].material = unlitMaterial;
                            }
                        }

                        _renderCamera.Render();

                        // Restore template sprites material.
                        if (_doNotBakeLight)
                        {
                            for (int _i = 0; _i < _sprites.Length; _i++)
                            {
                                _sprites[_i].material = _spritesMaterial[_i];
                            }
                        }

                        // Reset renderers layer.
                        foreach (KeyValuePair <GameObject, int> _renderer in _renderers)
                        {
                            _renderer.Key.layer = _renderer.Value;
                        }

                        // Create full transparent texture, then paint capture on it.
                        var     _capture = new Texture2D(_size.x, _size.y, TextureFormat.RGBA32, false);
                        Color[] _colors  = _capture.GetPixels();
                        for (int _i = 0; _i < _colors.Length; _i++)
                        {
                            _colors[_i] = Color.clear;
                        }
                        _capture.SetPixels(_colors);

                        // Reversed Y starting position
                        _capture.ReadPixels(new Rect(_offset.x, _renderCamera.pixelHeight - _offset.y - _boundsSize.y, _boundsSize.x, _boundsSize.y), 0, 0);
                        _capture.Apply();

                        // Create artwork based on template.
                        SpriteRenderer _artwork      = new GameObject(_template.Root.name).AddComponent <SpriteRenderer>();
                        Vector2        _pivot        = new Vector2((_boundsSize.x * .5f) / _size.x, 0);
                        float          _pixelPerUnit = _renderCamera.pixelHeight / (_renderCamera.orthographicSize * 2f);

                        _artwork.gameObject.layer   = 1;
                        _artwork.sortingOrder       = _template.OrderInLayer;
                        _artwork.transform.position = new Vector3(_bounds.min.x + _bounds.extents.x, _bounds.min.y, _bounds.center.z);

                        if (_template.Material)
                        {
                            _artwork.material = _template.Material;
                        }

                        _artworks[_n]      = _artwork.gameObject;
                        _artworksLayer[_n] = _template.Layer;

                        // Save texture according to selected mode.
                        if (scraperMode < 2)
                        {
                            string _path = Application.dataPath + saveTextureFolder.Remove(0, 6);
                            if (!Directory.Exists(_path))
                            {
                                Directory.CreateDirectory(_path);
                            }

                            // Get unique file path.
                            _path += _artwork.name + textureExtension;
                            if (File.Exists(_path))
                            {
                                string _originalPath = _path.Insert(_path.Length - 4, "_");
                                int    _number       = 0;

                                do
                                {
                                    _path = _originalPath.Insert(_originalPath.Length - 4, _number.ToString());
                                    _number++;
                                } while (File.Exists(_path));
                            }

                            // Save texture as PNG.
                            File.WriteAllBytes(_path, _capture.EncodeToPNG());

                            _path = _path.Remove(0, Application.dataPath.Length - 6);

                            AssetDatabase.ImportAsset(_path, ImportAssetOptions.ForceUpdate);

                            TextureImporter         _importer = (TextureImporter)AssetImporter.GetAtPath(_path);
                            TextureImporterSettings _settings = new TextureImporterSettings();

                            _importer.textureType         = TextureImporterType.Sprite;
                            _importer.spritePixelsPerUnit = _pixelPerUnit;

                            _importer.ReadTextureSettings(_settings);
                            _settings.spriteAlignment = (int)SpriteAlignment.Custom;
                            _importer.SetTextureSettings(_settings);

                            _importer.spritePivot = _pivot;
                            _importer.SaveAndReimport();

                            _artwork.sprite = AssetDatabase.LoadAssetAtPath <Sprite>(_path);
                        }
                        else
                        {
                            _artwork.sprite = Sprite.Create(_capture, new Rect(0, 0, _size.x, _size.y), _pivot, _pixelPerUnit);
                        }
                    }

                    // Replace templates by artworks on new scene mode.
                    if (scraperMode == 0)
                    {
                        for (int _i = 0; _i < _artworks.Length; _i++)
                        {
                            if (_artworks[_i] && templates[_i].Root)
                            {
                                _artworks[_i].transform.SetParent(templates[_i].Root.parent);

                                try
                                {
                                    DestroyImmediate(templates[_i].Root.gameObject);
                                }
                                catch (InvalidOperationException)
                                {
                                    GameObject _prefabRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(templates[_i].Root.gameObject);
                                    PrefabUtility.UnpackPrefabInstance(_prefabRoot, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);

                                    DestroyImmediate(templates[_i].Root.gameObject);
                                }
                            }
                        }

                        // Save scene as new one.
                        templates.Clear();
                        EditorApplication.ExecuteMenuItem(saveAsMenuPath);
                    }

                    // Set artowrks layer.
                    for (int _i = 0; _i < _artworks.Length; _i++)
                    {
                        if (_artworks[_i])
                        {
                            _artworks[_i].layer = _artworksLayer[_i];
                        }
                    }

                    // Clean capture tools.
                    DestroyImmediate(_renderCamera.gameObject);
                    RenderTexture.active = null;
                }
                else
                {
                    doDisplayNoTemplateMessage = true;
                }
                #endregion
            }

            if (doDisplayNoTemplateMessage)
            {
                EditorGUILayout.HelpBox(noTemplateMessage, MessageType.Error);
            }
        }