public override void OnInspectorGUI()
        {
            Undo.RecordObject(mTarget, "XFur System Editor Target " + mTarget.GetInstanceID());
            SceneView.RepaintAll();

            if (!pidiSkin)
            {
                PDEditor_GetCustomGUI(  );
            }

            var tSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);

            GUI.skin = pidiSkin;

            var buffDatabase = mTarget.database;

            GUILayout.BeginHorizontal(); GUILayout.BeginVertical(pidiSkin.box);
            GUILayout.Space(8);
            PDEditor_ObjectField <XFur_DatabaseModule>(new GUIContent("XFur Database Asset", "The XFur Database asset, required for LOD management, mesh handling and most other internal features"), ref mTarget.database, false);
            GUILayout.Space(8);

            if (buffDatabase != mTarget.database && mTarget.database != null)
            {
                mTarget.XFur_UpdateMeshData();
            }

            if (!mTarget.database)
            {
                GUILayout.BeginHorizontal(); GUILayout.Space(12);
                EditorGUILayout.HelpBox("Please assign the XFur Database Asset to this component. It is required for internal functions and its absence can make this software unstable", MessageType.Error);
                GUILayout.Space(12); GUILayout.EndHorizontal();
                GUILayout.Space(8);
            }
            else
            {
                if (mTarget.database.XFur_ContainsMeshData(mTarget.OriginalMesh) != -1)
                {
                    if (mTarget.database.meshData[mTarget.database.XFur_ContainsMeshData(mTarget.OriginalMesh)].XFurVersion != mTarget.Version)
                    {
                        GUILayout.BeginHorizontal(); GUILayout.Space(12);
                        EditorGUILayout.HelpBox("The current XFur version you are using does not match the version of the data stored in the database asset. You need to rebuild this data", MessageType.Error);
                        GUILayout.Space(12); GUILayout.EndHorizontal();
                        GUILayout.Space(8);

                        GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
                        if (GUILayout.Button("Rebuild Data", GUILayout.Width(200)))
                        {
                            mTarget.database.XFur_DeleteMeshData(mTarget.database.XFur_ContainsMeshData(mTarget.OriginalMesh));
                            mTarget.XFur_UpdateMeshData();
                        }
                        GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();

                        GUILayout.Space(8);
                    }
                    else
                    {
                        GUILayout.Space(8);
                        GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
                        if (GUILayout.Button(new GUIContent("Rebuild Data", "Forcefully rebuild all mesh data for this model. Use it if you have made changes to the original model (modified UV coordinates, skinning weights, topology, etc)"), GUILayout.Width(200)))
                        {
                            mTarget.database.XFur_DeleteMeshData(mTarget.database.XFur_ContainsMeshData(mTarget.OriginalMesh));
                            mTarget.XFur_UpdateMeshData();
                        }
                        GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();

                        GUILayout.Space(8);
                    }
                }

                if (PDEditor_BeginFold("XFur - Main Settings", ref folds[0]))
                {
                    PDEditor_Popup(new GUIContent("Material Slot", "The material we are currently editing"), ref mTarget.materialProfileIndex, mTarget.FurMatGUIS);

                    GUILayout.Space(8);
                    PDEditor_ObjectField <Material>(new GUIContent("Base Fur Material", "The fur material that will be used as a reference by this instance"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat, false);
                    GUILayout.Space(8);

                    if (mTarget.materialProfiles[mTarget.materialProfileIndex].buffOriginalMat != mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat)
                    {
                        mTarget.UpdateSharedData(mTarget.materialProfiles[mTarget.materialProfileIndex]);
                        mTarget.materialProfiles[mTarget.materialProfileIndex].SynchToOriginalMat();
                        mTarget.XFur_UpdateMeshData();
                    }

                    GUILayout.Space(4);
                    if (mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat && mTarget.materialProfiles[mTarget.materialProfileIndex].furmatType == 2)
                    {
                        if ((!Application.isPlaying || !mTarget.instancedMode) && mTarget.materialProfiles[mTarget.materialProfileIndex].furmatShadowsMode == 0)
                        {
                            if (XFur_System.materialReferences.ContainsKey(mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat))
                            {
                                var samples = new List <GUIContent>();


                                for (int i = 0; i < mTarget.database.highQualityShaders.Length; i++)
                                {
                                    var shaderName = XFur_System.materialReferences[mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat][i].shader.name;
                                    samples.Add(new GUIContent(shaderName.Split("/"[0])[shaderName.Split("/"[0]).Length - 1]));
                                }

                                if (mTarget.lodModule.State == XFurModuleState.Enabled)
                                {
                                    samples.Clear();
                                    samples.Add(new GUIContent("LOD Driven"));
                                    var n = 0;
                                    PDEditor_Popup(new GUIContent("Fur Samples", "The amount of samples to use on this shader"), ref n, new GUIContent[] { new GUIContent("LOD Driven") });

                                    if (!Application.isPlaying)
                                    {
                                        mTarget.materialProfiles[mTarget.materialProfileIndex].furmatSamples = 2;
                                    }
                                }
                                else
                                {
                                    PDEditor_Popup(new GUIContent("Fur Samples", "The amount of samples to use on this shader"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatSamples, samples.ToArray());
                                }
                                //PDEditor_Popup( new GUIContent("Fur Alpha Mode", "Controls the way the alpha is handled by the fur"), ref mTarget.furAlphaMode, new GUIContent[]{new GUIContent("Standard","The standard basic alpha handling used by older versions of XFur"), new GUIContent("Soft (BETA)", "Softer alpha handling with higher percision than in older versions, currently in BETA")} );
                                //PDEditor_Popup( new GUIContent("Fur Color Mode", "Controls the way the color is handled by the fur"), ref mTarget.furColorMode, new GUIContent[]{new GUIContent("Standard","The standard basic color handling used by older versions of XFur"), new GUIContent("Coating Module (BETA)", "The color of the fur of this instance will be controlled by the coating module")} );
                            }
                        }
                        else
                        {
                            if ((mTarget.lodModule == null || (mTarget.lodModule != null && mTarget.lodModule.State != XFurModuleState.Enabled)) && mTarget.runMaterialReferences.ContainsKey(mTarget.materialProfiles[mTarget.materialProfileIndex].originalMat))
                            {
                                var samples = new List <GUIContent>();


                                if (mTarget.lodModule.State == XFurModuleState.Enabled)
                                {
                                    samples.Clear();
                                    samples.Add(new GUIContent("LOD Driven"));
                                }

                                PDEditor_Popup(new GUIContent("Fur Samples", "The amount of samples to use on this shader"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatSamples, samples.ToArray());
                                //PDEditor_Popup( new GUIContent("Fur Alpha Mode", "Controls the way the alpha is handled by the fur"), ref mTarget.furAlphaMode, new GUIContent[]{new GUIContent("Standard","The standard basic alpha handling used by older versions of XFur"), new GUIContent("Soft (BETA)", "Softer alpha handling with higher percision than in older versions, currently in BETA")} );
                                //PDEditor_Popup( new GUIContent("Fur Color Mode", "Controls the way the color is handled by the fur"), ref mTarget.furColorMode, new GUIContent[]{new GUIContent("Standard","The standard basic color handling used by older versions of XFur"), new GUIContent("Coating Module (BETA)", "The color of the fur of this instance will be controlled by the coating module")} );
                            }
                            else
                            {
                                var n = 0;
                                PDEditor_Popup(new GUIContent("Fur Samples", "The amount of samples to use on this shader"), ref n, new GUIContent[] { new GUIContent("LOD Driven") });
                            }
                        }

                        var s = mTarget.materialProfiles[mTarget.materialProfileIndex].furmatShadowsMode;

                        PDEditor_Popup(new GUIContent("Shadows Mode", "Switches between the different shadow modes for the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatShadowsMode, new GUIContent[] { new GUIContent("Standard Shadows", "Simple shadow casting on forward and deferred with full shadow reception enabled only for deferred rendering"), new GUIContent("Full Shadows", "Expensive method of full shadowing in forward and deferred that adds accurate shadows in casting and receiving mode based on each fur strand and layer") });

                        if (s == 1)
                        {
                            GUILayout.BeginHorizontal(); GUILayout.Space(12);
                            EditorGUILayout.HelpBox("Full shadows generate additional geometry and sub renderers, making it VERY expensive to compute. Do not use them on scenes with more than a couple characters nor in models with more than 6-10k polygons", MessageType.Warning);
                            GUILayout.Space(12); GUILayout.EndHorizontal();
                            GUILayout.Space(8);
                        }

                        if (s != mTarget.materialProfiles[mTarget.materialProfileIndex].furmatShadowsMode && mTarget.materialProfiles[mTarget.materialProfileIndex].furmatShadowsMode == 1)
                        {
                            mTarget.XFur_GenerateShadowMesh(mTarget.materialProfiles[mTarget.materialProfileIndex]);
                        }


                        if (mTarget.FurMaterials == 1
                    #if UNITY_2018_1_OR_NEWER
                            || true
                    #endif
                            )
                        {
                            GUILayout.Space(8);

                            //PDEditor_Toggle( new GUIContent("Static Material", "If this fur material will not change its length, thickness, color, etc. at runtime it is recommended to toggle this value to handle the material as a static instance for better performance" ), ref mTarget.instancedMode );
                            mTarget.materialProfiles[mTarget.materialProfileIndex].furmatCollision = PDEditor_Toggle(new GUIContent("Basic Self-Collision", "Performs a basic self-collision algorithm on the shader to avoid (with a low precision) the fur from going inside the mesh"), mTarget.materialProfiles[mTarget.materialProfileIndex].furmatCollision == 1)?1:0;
                            mTarget.materialProfiles[mTarget.materialProfileIndex].furmatTriplanar = PDEditor_Toggle(new GUIContent("Triplanar Mode", "Render fur using triplanar coordinates generated at runtime instead of the secondary UV channel of this mesh"), mTarget.materialProfiles[mTarget.materialProfileIndex].furmatTriplanar == 1)?1:0;
                            GUILayout.Space(2);
                            mTarget.materialProfiles[mTarget.materialProfileIndex].furmatForceUV2Grooming = PDEditor_Toggle(new GUIContent("Force Grooming on UV2", "Forces triplanar coordinates to be used for fur projection, using the secondary UV map as coordinates for grooming instead"), mTarget.materialProfiles[mTarget.materialProfileIndex].furmatForceUV2Grooming == 1)?1:0;

                            if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatForceUV2Grooming == 1)
                            {
                                mTarget.materialProfiles[mTarget.materialProfileIndex].furmatTriplanar = 1;
                            }

                            GUILayout.Space(8);

                            if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatTriplanar == 1)
                            {
                                PDEditor_Slider(new GUIContent("Triplanar Scale", "The scale used for the triplanar projection of the fur, multiplied by the fur UV1 and UV2 channels' sizes"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatTriplanarScale, 0.0f, 1.0f);
                            }


                            GUILayout.Space(8);

                            PDEditor_Popup(new GUIContent("Base Skin Mode", "The mode in which the skin color and specularity are controlled for this instance"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadBaseSkin, new GUIContent[] { new GUIContent("From Material"), new GUIContent("From Instance") });
                            PDEditor_Popup(new GUIContent("Fur Settings Mode", "The mode in which the fur parameters are controlled for this instance"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadBaseFur, new GUIContent[] { new GUIContent("From Material"), new GUIContent("From Instance") });
                            PDEditor_Popup(new GUIContent("Fur Gen Map", "The mode in which the fur noise map is controlled for this instance"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadFurNoise, new GUIContent[] { new GUIContent("From Material"), new GUIContent("From Instance") });

                            GUILayout.Space(8);

                            XFur_CoatingProfile t = null;
                            PDEditor_ObjectField <XFur_CoatingProfile>(new GUIContent("Load Fur Profile", "Allows you to assign a pre-made fur profile to easily load existing settings, colors, etc"), ref t, false);

                            if (t != null)
                            {
                                mTarget.XFur_LoadFurProfile(t, mTarget.materialProfileIndex);
                            }

                            GUILayout.Space(8);
                            GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
                            if (GUILayout.Button("Export Fur Settings", GUILayout.MaxWidth(200)))
                            {
                                var k = mTarget.XFur_ExportMaterialProfile(mTarget.materialProfiles[mTarget.materialProfileIndex]);
                                if (k)
                                {
                                    var path = EditorUtility.SaveFilePanelInProject("Save Fur Profile", "New Fur Profile", "asset", "");
                                    AssetDatabase.CreateAsset(k, path);
                                    AssetDatabase.SaveAssets();
                                    AssetDatabase.Refresh();
                                }
                            }
                            GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
                            GUILayout.Space(8);

                            if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadBaseSkin != 0)
                            {
                                GUILayout.Space(4);
                                PDEditor_BeginGroupingBox("Base Skin");
                                PDEditor_Color(new GUIContent("Main Color", "Final tint to be applied to the skin under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatBaseColor);

                                if (!mTarget.materialProfiles[mTarget.materialProfileIndex].furmatGlossSpecular)
                                {
                                    PDEditor_Color(new GUIContent("Specular Color", "Specular color to be applied to the skin under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatSpecular);
                                }
                                PDEditor_ObjectField <Texture2D>(new GUIContent("Main Texture", "Texture to be applied to the mesh under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatBaseTex, false);
                                PDEditor_ObjectField <Texture2D>(new GUIContent("Specular Map", "Base Specular (RGB) and Smoothness (A) map to be used under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatGlossSpecular, false);
                                GUILayout.Space(4);

                                if (!mTarget.materialProfiles[mTarget.materialProfileIndex].furmatGlossSpecular)
                                {
                                    PDEditor_Slider(new GUIContent("Smoothness", "Smoothness to be applied to the skin under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatSmoothness, 0.0f, 1.0f);
                                }

                                GUILayout.Space(4);

                                PDEditor_ObjectField <Texture2D>(new GUIContent("Normalmap", "The normalmap to be applied to the skin under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatNormalmap, false);
                                PDEditor_ObjectField <Texture2D>(new GUIContent("Occlusion Map", "The occlusion map to be applied to the skin under the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatOcclusion, false);
                                GUILayout.Space(8);
                                PDEditor_EndGroupingBox();
                            }

                            GUILayout.Space(8);

                            if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadBaseFur != 0)
                            {
                                GUILayout.Space(4);
                                PDEditor_BeginGroupingBox("Fur Settings");
                                PDEditor_Color(new GUIContent("Fur Color A", "Main tint to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurColorA);
                                PDEditor_Color(new GUIContent("Fur Color B", "Main tint to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurColorB);
                                PDEditor_Color(new GUIContent("Fur Rim Color", "Main tint to be applied to the fur's rim"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurRim);

                                PDEditor_Color(new GUIContent("Specular Color", "Specular color to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurSpecular);

                                PDEditor_ObjectField <Texture2D>(new GUIContent("Fur Color Map", "Texture to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurColorMap, false);
                                PDEditor_ObjectField <Texture2D>(new GUIContent("Fur Data 0", "Main fur Data map (fur mask, length, thickness and occlusion)"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatData0, false);
                                PDEditor_ObjectField <Texture2D>(new GUIContent("Fur Data 1", "Secondary fur Data map (grooming and stiffness)"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatData1, false);

                                if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatReadFurNoise > 0)
                                {
                                    PDEditor_ObjectField <Texture2D>(new GUIContent("Fur Noise Gen", "Multi-layer noise map used as reference to generate the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurNoiseMap, false);
                                }
                                GUILayout.Space(4);

                                PDEditor_Slider(new GUIContent("Fur Occlusion", "Shadowing and Occlusion to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurOcclusion, 0.0f, 1.0f);
                                PDEditor_Slider(new GUIContent("Fur Smoothness", "Smoothness to be applied to the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurSmoothness, 0.0f, 1.0f);
                                PDEditor_Slider(new GUIContent("Fur Length", "Length of the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurLength, 0.0f, 4.0f);
                                PDEditor_Slider(new GUIContent("Fur Thickness", "Thickness of the fur"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurThickness, 0.0f, 1.0f);
                                PDEditor_Slider(new GUIContent("Fur Rim Power", "The power of the rim lighting effect"), ref mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurRimPower, 0.0f, 1.0f);
                                GUILayout.Space(4);

                                mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurUV1 = PDEditor_FloatField(new GUIContent("Fur UV 0 Scale", "Scale of the first fur specific UV channel"), mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurUV1);
                                mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurUV2 = PDEditor_FloatField(new GUIContent("Fur UV 1 Scale", "Scale of the second fur specific UV channel"), mTarget.materialProfiles[mTarget.materialProfileIndex].furmatFurUV2);

                                Vector3 furDir         = mTarget.materialProfiles[mTarget.materialProfileIndex].furmatDirection;
                                int     groomAlgorithm = (int)mTarget.materialProfiles[mTarget.materialProfileIndex].furmatDirection.w;

                                PDEditor_Popup(new GUIContent("Grooming Algorithm", "The grooming algorithm to use when adding fur direction to this model"), ref groomAlgorithm, new GUIContent[] { new GUIContent("Original", "The original grooming algorithm adds a bit of length to the fur as you groom allowing more creativity. Please use small fur direction values for best results"), new GUIContent("Accurate", "The new algorithm for grooming is more accurate, bending the fur without adding any length. It allows for a more controlled, predictable grooming. Please make sure to use high fur direction values for best results") });
                                PDEditor_Vector3(new GUIContent("Fur Direction"), ref furDir);

                                mTarget.materialProfiles[mTarget.materialProfileIndex].furmatDirection = new Vector4(furDir.x, furDir.y, furDir.z, groomAlgorithm);



                                GUILayout.Space(8);
                                PDEditor_EndGroupingBox();

                                GUILayout.Space(8);
                            }
                        }
                        else
                        {
                            GUILayout.Space(6);

                            GUILayout.BeginHorizontal(); GUILayout.Space(12);
                            EditorGUILayout.HelpBox("Per Instance parameters are not supported on models with more than 1 fur based material on Unity versions older than Unity 2018.1", MessageType.Warning);
                            GUILayout.Space(12); GUILayout.EndHorizontal();

                            GUILayout.Space(6);
                        }
                    }
                    else if (mTarget.materialProfiles[mTarget.materialProfileIndex].furmatType == 1)
                    {
                        GUILayout.BeginHorizontal(); GUILayout.Space(12);
                        EditorGUILayout.HelpBox("This is a legacy XFur material. It must be upgraded. Please be warned that upgrading a material is a one time operation. It won't change any of the textures but will modify the material's properties", MessageType.Warning);
                        GUILayout.Space(12); GUILayout.EndHorizontal();

                        GUILayout.Space(12);

                        GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
                        if (GUILayout.Button("Auto-Upgrade Material", GUILayout.MaxWidth(200)))
                        {
                            mTarget.AutoUpgradeMaterial(mTarget.materialProfiles[mTarget.materialProfileIndex]);
                        }
                        GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
                    }
                    else
                    {
                        GUILayout.BeginHorizontal(); GUILayout.Space(12);
                        EditorGUILayout.HelpBox("This material is not a fur enabled material, no settings will be available for it.", MessageType.Warning);
                        GUILayout.Space(12); GUILayout.EndHorizontal();
                    }
                    GUILayout.Space(8);
                }
                PDEditor_EndFold();


                if (PDEditor_BeginFold(mTarget.coatingModule != null?"XFur - " + mTarget.coatingModule.ModuleName:"XFur - Coating Module (ERROR)", ref folds[1]))
                {
                    mTarget.coatingModule.Module_UI( );
                }
                PDEditor_EndFold();


                if (PDEditor_BeginFold(mTarget.lodModule != null?"XFur - " + mTarget.lodModule.ModuleName:"XFur - Lod Module (ERROR)", ref folds[2]))
                {
                    mTarget.lodModule.Module_UI( );
                }
                PDEditor_EndFold();


                if (PDEditor_BeginFold(mTarget.physicsModule != null?"XFur - " + mTarget.physicsModule.ModuleName:"XFur - Physics Module (ERROR)", ref folds[3]))
                {
                    mTarget.physicsModule.Module_UI( );
                }
                PDEditor_EndFold();


                if (PDEditor_BeginFold(mTarget.fxModule != null?"XFur - " + mTarget.fxModule.ModuleName:"XFur - FX Module (ERROR)", ref folds[4]))
                {
                    mTarget.fxModule.Module_UI( );
                }
                PDEditor_EndFold();

                GUILayout.Space(8);
            }

            var tempStyle = new GUIStyle();
            tempStyle.normal.textColor = new Color(0.75f, 0.75f, 0.75f);
            tempStyle.fontSize         = 9;
            tempStyle.fontStyle        = FontStyle.Italic;
            GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
            GUILayout.Label("PIDI - XFur Studio™. Version 1.4", tempStyle);
            GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();

            GUILayout.Space(8);
            GUILayout.EndVertical(); GUILayout.Space(8); GUILayout.EndHorizontal();


            GUI.skin = tSkin;
        }
Exemplo n.º 2
0
        public override void OnInspectorGUI()
        {
            xFur = (XFur_System)target;



            if (xFur.coatingModule != null)
            {
                xFur.coatingModule.Module_StartUI(pidiSkin2);
            }


            if (xFur.lodModule != null)
            {
                xFur.lodModule.Module_StartUI(pidiSkin2);
            }


            if (xFur.physicsModule != null)
            {
                xFur.physicsModule.Module_StartUI(pidiSkin2);
            }


            if (xFur.fxModule != null)
            {
                xFur.fxModule.Module_StartUI(pidiSkin2);
            }

            Undo.RecordObject(xFur, "XFUR_" + xFur.GetInstanceID());



            var tSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);

            GUI.skin = pidiSkin;



            var buffDatabase = xFur.database;

            GUILayout.BeginHorizontal(); GUILayout.BeginVertical(pidiSkin2.box);
            AssetLogoAndVersion();
            GUILayout.Space(8);
            GUILayout.BeginHorizontal(); GUILayout.Space(12); GUILayout.BeginVertical();
            xFur.database = ObjectField <XFur_DatabaseModule>(new GUIContent("XFUR DATABASE ASSET", "The XFur Database asset, required for LOD management, mesh handling and most other internal features"), xFur.database, false);
            GUILayout.Space(8);

            if (buffDatabase != xFur.database && xFur.database != null)
            {
                xFur.XFur_UpdateMeshData();
                xFur.XFur_Start();
            }

            var tempTarget = xFur.manualMeshIndex;

            xFur.manualMeshIndex = EnableDisableToggle(new GUIContent("EXPLICIT MODEL INDEX", "Use an explicit index on the database to get the mesh data from instead of automatically linking XFur to the database through Mesh ID. In most cases, you should leave this toggle disabled"), xFur.manualMeshIndex != -1)?Mathf.Max(xFur.manualMeshIndex, 0):-1;

            if (xFur.manualMeshIndex != -1)
            {
                if (xFur.database.meshData.Length < 1)
                {
                    xFur.manualMeshIndex = -1;
                }
                xFur.manualMeshIndex = PopupField(new GUIContent("EXPLICIT DATABASE INDEX"), xFur.manualMeshIndex, xFur.database.GetMeshNames());
                xFur.manualMeshIndex = Mathf.Clamp(xFur.manualMeshIndex, 0, xFur.database.meshData.Length - 1);
            }

            if (tempTarget != xFur.manualMeshIndex)
            {
                xFur.XFur_UpdateMeshData();
            }

            if (!xFur.database)
            {
                GUILayout.BeginHorizontal(); GUILayout.Space(12);
                EditorGUILayout.HelpBox("Please assign the XFur Database Asset to this component. It is required for internal functions and its absence can make this software unstable", MessageType.Error);
                GUILayout.Space(12); GUILayout.EndHorizontal();
                GUILayout.Space(8);

                GUILayout.EndVertical(); GUILayout.Space(12);
                GUILayout.EndHorizontal();
            }
            else
            {
                if (xFur.database.XFur_ContainsMeshData(xFur.OriginalMesh) != -1)
                {
                    if (xFur.database.meshData[xFur.database.XFur_ContainsMeshData(xFur.OriginalMesh)].XFurVersion != xFur.Version)
                    {
                        GUILayout.BeginHorizontal(); GUILayout.Space(12);
                        EditorGUILayout.HelpBox("The current XFur version you are using does not match the version of the data stored in the database asset. You need to rebuild this data", MessageType.Error);
                        GUILayout.Space(12); GUILayout.EndHorizontal();
                        GUILayout.Space(8);

                        if (CenteredButton("REBUILD DATA", 200))
                        {
                            xFur.database.XFur_DeleteMeshData(xFur.database.XFur_ContainsMeshData(xFur.OriginalMesh));
                            xFur.XFur_UpdateMeshData();
                        }

                        GUILayout.Space(8);
                    }
                    else
                    {
                        GUILayout.Space(8);
                        if (CenteredButton("REBUILD DATA", 200))
                        {
                            xFur.database.XFur_DeleteMeshData(xFur.database.XFur_ContainsMeshData(xFur.OriginalMesh));
                            xFur.XFur_UpdateMeshData();
                        }

                        GUILayout.Space(8);
                    }
                }

                GUILayout.EndVertical(); GUILayout.Space(12);
                GUILayout.EndHorizontal();

                if (BeginCenteredGroup("XFUR - MAIN SETTINGS", ref xFur.folds[0]))
                {
                    GUILayout.Space(16);

                    xFur.updateDynamically = EnableDisableToggle(new GUIContent("DYNAMIC UPDATES", "Enable this if you plan on making dynamic changes to the fur at runtime. If you are using the FX or Physics module, disable it for better performance."), xFur.updateDynamically);

                    xFur.materialProfileIndex = PopupField(new GUIContent("MATERIAL SLOT", "The material we are currently editing"), xFur.materialProfileIndex, xFur.FurMatGUIS);

                    GUILayout.Space(8);
                    xFur.materialProfiles[xFur.materialProfileIndex].originalMat = ObjectField <Material>(new GUIContent("BASE FUR MATERIAL", "The fur material that will be used as a reference by this instance"), xFur.materialProfiles[xFur.materialProfileIndex].originalMat, false);
                    GUILayout.Space(8);

                    if (xFur.materialProfiles[xFur.materialProfileIndex].buffOriginalMat != xFur.materialProfiles[xFur.materialProfileIndex].originalMat || xFur.GetComponent <Renderer>().sharedMaterials[xFur.materialProfileIndex] == null || !xFur.GetComponent <Renderer>().sharedMaterials[xFur.materialProfileIndex].name.Contains(xFur.materialProfiles[xFur.materialProfileIndex].originalMat.name) || !xFur.GetComponent <Renderer>().sharedMaterials[xFur.materialProfileIndex].shader.name.Contains("XFUR"))
                    {
                        xFur.UpdateSharedData(xFur.materialProfiles[xFur.materialProfileIndex]);
                        xFur.materialProfiles[xFur.materialProfileIndex].SynchToOriginalMat();
                        xFur.XFur_UpdateMeshData();
                    }

                    GUILayout.Space(4);
                    if (xFur.materialProfiles[xFur.materialProfileIndex].originalMat && xFur.materialProfiles[xFur.materialProfileIndex].furmatType == 2)
                    {
                        if ((!Application.isPlaying || !xFur.instancedMode) && xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode == 0)
                        {
                            if (XFur_System.materialReferences.ContainsKey(xFur.materialProfiles[xFur.materialProfileIndex].originalMat))
                            {
                                var samples = new List <GUIContent>();


                                for (int i = 0; i < xFur.database.highQualityShaders.Length; i++)
                                {
                                    var shaderName = XFur_System.materialReferences[xFur.materialProfiles[xFur.materialProfileIndex].originalMat][i].shader.name.ToUpper();
                                    samples.Add(new GUIContent(shaderName.Split("/"[0])[shaderName.Split("/"[0]).Length - 1]));
                                }

                                if (xFur.lodModule.State == XFurModuleState.Enabled)
                                {
                                    samples.Clear();
                                    samples.Add(new GUIContent("LOD DRIVEN"));
                                    var n = 0;
                                    n = PopupField(new GUIContent("FUR SAMPLES", "The amount of samples to use on this shader"), n, new GUIContent[] { new GUIContent("LOD Driven") });

                                    if (!Application.isPlaying)
                                    {
                                        xFur.materialProfiles[xFur.materialProfileIndex].furmatSamples = 2;
                                    }
                                }
                                else
                                {
                                    xFur.materialProfiles[xFur.materialProfileIndex].furmatSamples = PopupField(new GUIContent("FUR SAMPLES", "The amount of samples to use on this shader"), xFur.materialProfiles[xFur.materialProfileIndex].furmatSamples, samples.ToArray());
                                }
                            }
                        }
                        else
                        {
                            if ((xFur.lodModule == null || (xFur.lodModule != null && xFur.lodModule.State != XFurModuleState.Enabled)) && xFur.runMaterialReferences.ContainsKey(xFur.materialProfiles[xFur.materialProfileIndex].originalMat))
                            {
                                var samples = new List <GUIContent>();


                                if (xFur.lodModule.State == XFurModuleState.Enabled)
                                {
                                    samples.Clear();
                                    samples.Add(new GUIContent("LOD DRIVEN"));
                                }

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatSamples = PopupField(new GUIContent("FUR SAMPLES", "The amount of samples to use on this shader"), xFur.materialProfiles[xFur.materialProfileIndex].furmatSamples, samples.ToArray());
                            }
                            else
                            {
                                var n = 0;
                                n = PopupField(new GUIContent("FUR SAMPLES", "The amount of samples to use on this shader"), n, new GUIContent[] { new GUIContent("LOD Driven") });
                            }
                        }

                        var s = xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode;

                        xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode = PopupField(new GUIContent("SHADOWS MODE", "Switches between the different shadow modes for the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode, new GUIContent[] { new GUIContent("STANDARD SHADOWS", "Simple shadow casting on forward and deferred with full shadow reception enabled only for deferred rendering"), new GUIContent("(BETA) FULL SHADOWS", "Expensive method of full shadowing in forward and deferred that adds accurate shadows in casting and receiving mode based on each fur strand and layer") });

                        if (s == 1)
                        {
                            GUILayout.BeginHorizontal(); GUILayout.Space(12);
                            EditorGUILayout.HelpBox("Full shadows generate additional geometry and sub renderers, making it VERY expensive to compute. DO NOT use them on scenes with more than a couple characters nor in models with more than 6-10k polygons", MessageType.Warning);
                            GUILayout.Space(12); GUILayout.EndHorizontal();
                            GUILayout.Space(8);

                            var tempF = (int)xFur.materialProfiles[xFur.materialProfileIndex].fullShadowLayers;
                            tempF = IntSliderField(new GUIContent("FUR SAMPLES"), tempF, 6, 32);
                            xFur.materialProfiles[xFur.materialProfileIndex].fullShadowLayers = tempF;
                        }

                        if (s != xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode && xFur.materialProfiles[xFur.materialProfileIndex].furmatShadowsMode == 1)
                        {
                            xFur.XFur_GenerateShadowMesh(xFur.materialProfiles[xFur.materialProfileIndex]);
                        }


                        if (xFur.FurMaterials == 1
#if UNITY_2018_1_OR_NEWER
                            || true
#endif
                            )
                        {
                            GUILayout.Space(8);

                            //EnableDisableToggle( new GUIContent("Static Material", "If this fur material will not change its length, thickness, color, etc. at runtime it is recommended to toggle this value to handle the material as a static instance for better performance" ), ref xFur.instancedMode );
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatCollision        = EnableDisableToggle(new GUIContent("BASIC SELF-COLLISION", "Performs a basic self-collision algorithm on the shader to avoid (with a low precision) the fur from going inside the mesh"), xFur.materialProfiles[xFur.materialProfileIndex].furmatCollision == 1) ? 1 : 0;
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatRenderSkin       = EnableDisableToggle(new GUIContent("BASE SKIN PASS", "Render the skin layer under the fur for this material"), xFur.materialProfiles[xFur.materialProfileIndex].furmatRenderSkin == 1) ? 1 : 0;
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanar        = EnableDisableToggle(new GUIContent("TRIPLANAR MODE", "Render fur using triplanar coordinates generated at runtime instead of the secondary UV channel of this mesh"), xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanar == 1) ? 1 : 0;
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatForceUV2Grooming = EnableDisableToggle(new GUIContent("GROOM MAP ON UV2", "Forces triplanar coordinates to be used for fur projection, using the secondary UV map as coordinates for grooming instead"), xFur.materialProfiles[xFur.materialProfileIndex].furmatForceUV2Grooming == 1) ? 1 : 0;

                            if (xFur.materialProfiles[xFur.materialProfileIndex].furmatForceUV2Grooming == 1)
                            {
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanar = 1;
                            }

                            GUILayout.Space(8);

                            if (xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanar == 1)
                            {
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanarScale = SliderField(new GUIContent("TRIPLANAR SCALE", "The scale used for the triplanar projection of the fur, multiplied by the fur UV1 and UV2 channels' sizes"), xFur.materialProfiles[xFur.materialProfileIndex].furmatTriplanarScale, 0.0f, 1.0f);
                            }


                            GUILayout.Space(8);

                            xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseSkin = PopupField(new GUIContent("BASE SKIN MODE", "The mode in which the skin color and specularity are controlled for this instance"), xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseSkin, new GUIContent[] { new GUIContent("FROM MATERIAL"), new GUIContent("FROM INSTANCE") });
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseFur  = PopupField(new GUIContent("FUR SETTINGS MODE", "The mode in which the fur parameters are controlled for this instance"), xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseFur, new GUIContent[] { new GUIContent("FROM MATERIAL"), new GUIContent("FROM INSTANCE") });
                            xFur.materialProfiles[xFur.materialProfileIndex].furmatReadFurNoise = PopupField(new GUIContent("FUR GEN MAP", "The mode in which the fur noise map is controlled for this instance"), xFur.materialProfiles[xFur.materialProfileIndex].furmatReadFurNoise, new GUIContent[] { new GUIContent("FROM MATERIAL"), new GUIContent("FROM INSTANCE") });

                            GUILayout.Space(8);

                            XFur_CoatingProfile t = null;
                            t = ObjectField <XFur_CoatingProfile>(new GUIContent("LOAD FUR PROFILE", "Allows you to assign a pre-made fur profile to easily load existing settings, colors, etc"), t, false);

                            if (t != null)
                            {
                                xFur.LoadXFurProfileAsset(t, xFur.materialProfileIndex);
                            }

                            GUILayout.Space(16);
                            if (CenteredButton("EXPORT FUR SETTINGS", 200))
                            {
                                var k = xFur.XFur_ExportMaterialProfile(xFur.materialProfiles[xFur.materialProfileIndex]);
                                if (k)
                                {
                                    var path = EditorUtility.SaveFilePanelInProject("Save Fur Profile", "New Fur Profile", "asset", "");
                                    AssetDatabase.CreateAsset(k, path);
                                    AssetDatabase.SaveAssets();
                                    AssetDatabase.Refresh();
                                }
                            }
                            GUILayout.Space(16);

                            if (xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseSkin != 0)
                            {
                                GUILayout.Space(4);
                                SmallGroup("BASE SKIN");
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatBaseColor = ColorField(new GUIContent("MAIN COLOR", "Final tint to be applied to the skin under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatBaseColor);

                                if (!xFur.materialProfiles[xFur.materialProfileIndex].furmatGlossSpecular)
                                {
                                    xFur.materialProfiles[xFur.materialProfileIndex].furmatSpecular = ColorField(new GUIContent("SPECULAR COLOR", "Specular color to be applied to the skin under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatSpecular);
                                }

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatBaseTex = ObjectField <Texture2D>(new GUIContent("MAIN TEXTURE", "Texture to be applied to the mesh under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatBaseTex, false);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatGlossSpecular = ObjectField <Texture2D>(new GUIContent("SPECULAR MAP", "Base Specular (RGB) and Smoothness (A) map to be used under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatGlossSpecular, false);
                                GUILayout.Space(4);

                                if (!xFur.materialProfiles[xFur.materialProfileIndex].furmatGlossSpecular)
                                {
                                    xFur.materialProfiles[xFur.materialProfileIndex].furmatSmoothness = SliderField(new GUIContent("SMOOTHNESS", "Smoothness to be applied to the skin under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatSmoothness, 0.0f, 1.0f);
                                }

                                GUILayout.Space(4);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatNormalmap = ObjectField <Texture2D>(new GUIContent("NORMALMAP", "The normalmap to be applied to the skin under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatNormalmap, false);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatOcclusion = ObjectField <Texture2D>(new GUIContent("OCCLUSION MAP", "The occlusion map to be applied to the skin under the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatOcclusion, false);

                                GUILayout.Space(8);
                                EndSmallGroup();
                            }

                            GUILayout.Space(16);

                            if (xFur.materialProfiles[xFur.materialProfileIndex].furmatReadBaseFur != 0)
                            {
                                GUILayout.Space(4);
                                SmallGroup("FUR SETTINGS");
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorA = ColorField(new GUIContent("FUR COLOR A", "Main tint to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorA);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorB = ColorField(new GUIContent("FUR COLOR B", "Main tint to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorB);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurRim    = ColorField(new GUIContent("FUR RIM COLOR", "Main tint to be applied to the fur's rim"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurRim);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurSpecular = ColorField(new GUIContent("SPECULAR COLOR", "Specular color to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurSpecular);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorMap = ObjectField <Texture2D>(new GUIContent("FUR COLOR MAP", "Texture to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurColorMap, false);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatData0       = ObjectField <Texture2D>(new GUIContent("FUR DATA 0", "Main fur Data map (fur mask, length, thickness and occlusion)"), xFur.materialProfiles[xFur.materialProfileIndex].furmatData0, false);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatData1       = ObjectField <Texture2D>(new GUIContent("FUR DATA 1", "Secondary fur Data map (grooming and stiffness)"), xFur.materialProfiles[xFur.materialProfileIndex].furmatData1, false);

                                if (xFur.materialProfiles[xFur.materialProfileIndex].furmatReadFurNoise > 0)
                                {
                                    xFur.materialProfiles[xFur.materialProfileIndex].furmatFurNoiseMap = ObjectField <Texture2D>(new GUIContent("FUR NOISE GEN", "Multi-layer noise map used as reference to generate the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurNoiseMap, false);
                                }
                                GUILayout.Space(4);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurOcclusion  = SliderField(new GUIContent("FUR OCCLUSION", "Shadowing and Occlusion to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurOcclusion, 0.0f, 1.0f);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurSmoothness = SliderField(new GUIContent("FUR SMOOTHNESS", "Smoothness to be applied to the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurSmoothness, 0.0f, 1.0f);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurLength     = SliderField(new GUIContent("FUR LENGTH", "Length of the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurLength, 0.0f, 4.0f);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurThickness  = SliderField(new GUIContent("FUR THICKNESS", "Thickness of the fur"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurThickness, 0.0f, 1.0f);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurRimPower   = SliderField(new GUIContent("FUR RIM POWER", "The power of the rim lighting effect"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurRimPower, 0.0f, 1.0f);
                                GUILayout.Space(4);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurUV1 = FloatField(new GUIContent("FUR UV 0 SCALE", "Scale of the first fur specific UV channel"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurUV1);
                                xFur.materialProfiles[xFur.materialProfileIndex].furmatFurUV2 = FloatField(new GUIContent("FUR UV 1 SCALE", "Scale of the second fur specific UV channel"), xFur.materialProfiles[xFur.materialProfileIndex].furmatFurUV2);

                                Vector3 furDir         = xFur.materialProfiles[xFur.materialProfileIndex].furmatDirection;
                                int     groomAlgorithm = (int)xFur.materialProfiles[xFur.materialProfileIndex].furmatDirection.w;

                                groomAlgorithm = PopupField(new GUIContent("GROOMING ALGORITHM", "The grooming algorithm to use when adding fur direction to this model"), groomAlgorithm, new GUIContent[] { new GUIContent("Original", "The original grooming algorithm adds a bit of length to the fur as you groom allowing more creativity. Please use small fur direction values for best results"), new GUIContent("Accurate", "The new algorithm for grooming is more accurate, bending the fur without adding any length. It allows for a more controlled, predictable grooming. Please make sure to use high fur direction values for best results") });
                                furDir         = Vector3Field(new GUIContent("FUR DIRECTION"), furDir);

                                xFur.materialProfiles[xFur.materialProfileIndex].furmatDirection = new Vector4(furDir.x, furDir.y, furDir.z, groomAlgorithm);



                                GUILayout.Space(8);
                                EndSmallGroup();

                                GUILayout.Space(8);
                            }
                        }
                        else
                        {
                            GUILayout.Space(6);

                            GUILayout.BeginHorizontal(); GUILayout.Space(12);
                            EditorGUILayout.HelpBox("Per Instance parameters are not supported on models with more than 1 fur based material on Unity versions older than Unity 2018.1", MessageType.Warning);
                            GUILayout.Space(12); GUILayout.EndHorizontal();

                            GUILayout.Space(6);
                        }
                    }
                    else
                    {
                        GUILayout.BeginHorizontal(); GUILayout.Space(12);
                        EditorGUILayout.HelpBox("This material is not a fur enabled material, no settings will be available for it.", MessageType.Warning);
                        GUILayout.Space(12); GUILayout.EndHorizontal();
                    }
                    GUILayout.Space(16);
                }
                EndCenteredGroup();


                if (BeginCenteredGroup(xFur.coatingModule != null ? "XFUR - " + xFur.coatingModule.ModuleName : "XFur - Coating Module (ERROR)", ref xFur.folds[1]))
                {
                    GUILayout.Space(16);
                    xFur.coatingModule.Module_UI(xFur);
                    GUILayout.Space(16);
                }
                EndCenteredGroup();


                if (BeginCenteredGroup(xFur.lodModule != null ? "XFUR - " + xFur.lodModule.ModuleName : "XFur - Lod Module (ERROR)", ref xFur.folds[2]))
                {
                    GUILayout.Space(16);
                    xFur.lodModule.Module_UI(xFur);
                    GUILayout.Space(16);
                }
                EndCenteredGroup();


                if (BeginCenteredGroup(xFur.physicsModule != null ? "XFUR - " + xFur.physicsModule.ModuleName : "XFur - Physics Module (ERROR)", ref xFur.folds[3]))
                {
                    GUILayout.Space(16);
                    xFur.physicsModule.Module_UI(xFur);
                    GUILayout.Space(16);
                }
                EndCenteredGroup();


                if (BeginCenteredGroup(xFur.fxModule != null ? "XFUR - " + xFur.fxModule.ModuleName : "XFur - FX Module (ERROR)", ref xFur.folds[4]))
                {
                    GUILayout.Space(16);
                    xFur.fxModule.Module_UI(xFur);
                    GUILayout.Space(16);
                }
                EndCenteredGroup();

                if (BeginCenteredGroup("HELP & SUPPORT", ref xFur.folds[6]))
                {
                    GUILayout.Space(16);
                    CenteredLabel("SUPPORT AND ASSISTANCE");
                    GUILayout.Space(10);

                    EditorGUILayout.HelpBox("Please make sure to include the following information with your request :\n - Invoice number\n - Screenshots of the XFur_System component and its settings\n - Steps to reproduce the issue.\n\nOur support service usually takes 2-4 business days to reply, so please be patient. We always reply to all emails.", MessageType.Info);

                    GUILayout.Space(8);
                    GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
                    GUILayout.Label("For support, contact us at : [email protected]", pidiSkin2.label);
                    GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();

                    GUILayout.Space(8);

                    GUILayout.Space(16);
                    CenteredLabel("ONLINE TUTORIALS");
                    GUILayout.Space(10);
                    if (CenteredButton("QUICK START GUIDE", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#quick_start_guide");
                    }
                    if (CenteredButton("PREPARING YOUR 3D MODELS", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#preparing_your_3d_models");
                    }
                    if (CenteredButton("XFUR PAINTER", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#xfur_painter");
                    }
                    if (CenteredButton("XFUR SYSTEM COMPONENTS", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#xfur_studio_-_components");
                    }
                    if (CenteredButton("XFUR SYSTEM MODULES", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#xfur_studio_-_system_modules");
                    }

                    if (CenteredButton("XFUR STUDIO API", 200))
                    {
                        Help.BrowseURL("https://pidiwiki.irreverent-software.com/wiki/doku.php?id=xfur_studio_legacy#xfur_studio_api");
                    }

                    GUILayout.Space(24);
                    CenteredLabel("ABOUT PIDI : XFUR STUDIO™");
                    GUILayout.Space(12);

                    EditorGUILayout.HelpBox("PIDI : XFur Studio™ has been integrated in dozens of projects by hundreds of users.\nYour use and support to this tool is what keeps it growing, evolving and adapting to better suit your needs and keep providing you with the best quality fur for Unity.\n\nIf this tool has been useful for your project, please consider taking a minute to rate and review it, to help us to continue its development for a long time.", MessageType.Info);

                    GUILayout.Space(8);
                    if (CenteredButton("REVIEW XFUR STUDIO™", 200))
                    {
                        Help.BrowseURL("https://assetstore.unity.com/packages/vfx/shaders/pidi-xfur-studio-113361");
                    }
                    GUILayout.Space(8);
                    if (CenteredButton("ABOUT THIS VERSION", 200))
                    {
                        Help.BrowseURL("https://assetstore.unity.com/packages/vfx/shaders/pidi-xfur-studio-113361");
                    }
                    GUILayout.Space(8);
                }
                EndCenteredGroup();
            }

            GUILayout.Space(16);

            var tempStyle = new GUIStyle();
            tempStyle.normal.textColor = new Color(0.75f, 0.75f, 0.75f);
            tempStyle.fontSize         = 9;
            tempStyle.fontStyle        = FontStyle.Italic;
            GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
            GUILayout.Label("Copyright© 2018-2019, Jorge Pinal N.", tempStyle);
            GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();

            GUILayout.Space(16);
            GUILayout.EndVertical(); GUILayout.Space(8); GUILayout.EndHorizontal();


            GUI.skin = tSkin;
        }