Esempio n. 1
0
        public void Initialise(LBLighting lightingScript)
        {
            lighting = lightingScript;

            // Only add celestials camera if it doesn't already exist
            Transform celestialTrm = transform.Find("Celestials Camera");

            if (celestialTrm == null)
            {
                GameObject celestialsCameraObject = new GameObject("Celestials Camera");
                celestialsCameraObject.transform.parent        = transform;
                celestialsCameraObject.transform.localPosition = Vector3.zero;
                celestialsCamera = celestialsCameraObject.AddComponent <Camera>();
            }

            celestialsCamera.nearClipPlane = 0.1f;
            celestialsCamera.farClipPlane  = 10f;
            celestialsCamera.depth         = -100f;
            celestialsCamera.clearFlags    = CameraClearFlags.Skybox;
            if (lighting.mainCamera != null)
            {
                celestialsCamera.fieldOfView = lighting.mainCamera.fieldOfView;
            }
            else
            {
                Debug.LogWarning("WARNING: Celestials Main Camera is null. Some celestials may not work correctly.");
            }
        }
Esempio n. 2
0
 public LBWaterParameters()
 {
     // Defaults
     landscape               = null;
     landscapeGameObject     = null;
     waterTransform          = null;
     waterPosition           = Vector3.zero;
     waterSize               = Vector2.one * 100f;
     waterIsPrimary          = false;
     waterHeight             = 1000f;
     waterPrefab             = null;
     keepPrefabAspectRatio   = true;
     waterResizingMode       = LBWater.WaterResizingMode.StandardAssets;
     waterMeshResizingMode   = LBWater.WaterMeshResizingMode.StandardAssets;
     waterMaxMeshThreshold   = 5000;
     waterMainCamera         = null;
     waterCameraList         = new List <Camera>();
     waterCausticsPrefabList = null;
     isRiver                 = false;
     riverMaterial           = null;
     waterMaterial           = null;
     flowMapTexture          = null;
     riverFlowSpeed          = 1.5f;
     isUnderWaterFXEnabled   = false;
     underWaterFXPrefab      = null;
     underWaterFXPrefabName  = "unknown";
     underWaterFXPrefabPath  = string.Empty;
     reflectionProbePosition = Vector3.zero;
     lbLighting              = null;
 }
Esempio n. 3
0
 public void BuildCelestrials(LBLighting lightingScript)
 {
     if (lighting == null)
     {
         Initialise(lightingScript);
     }
     DestroyStarGameObject();
     DestroyMoonGameObject();
     CreateStars(lightingScript.numberOfStars, lightingScript.starSize);
     CreateMoon(lightingScript.moonSize);
 }
Esempio n. 4
0
    // Use this for initialization
    void Awake()
    {
        lbLighting = GameObject.FindObjectOfType <LBLighting>();
        if (lbLighting == null)
        {
            Debug.LogWarning("ERROR: Cannot find LBLighting in the scene");
        }

        if (isFadeOnWake)
        {
            lbLighting.fadeInDuration = fadeInDuration;
            lbLighting.StartScreenFade(true);
            isFadingInStarted = true;
        }
    }
Esempio n. 5
0
        /// <summary>
        /// Verify that the stars and moon have been created
        /// If camera and/or light script isn't linked correctly,
        /// rebuild everything.
        /// </summary>
        public void CheckCelestials(LBLighting lightingScript)
        {
            if (celestialsCamera == null && lighting == null)
            {
                BuildCelestrials(lightingScript);
            }
            else
            {
                if (transform.Find("Stars") == null)
                {
                    CreateStars(lightingScript.numberOfStars, lightingScript.starSize);
                }

                if (transform.Find("Moon") == null)
                {
                    CreateMoon(lightingScript.moonSize);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Load a template but delay short period of time after updating
        /// the infoPanel text to force it to be displayed
        /// For URP/LWRP/HDRP all trees will be forced to be billboarded
        /// as currently we are only using built-in SRP trees.
        /// </summary>
        /// <param name="templateNumber"></param>
        /// <returns></returns>
        IEnumerator LoadTemplateWithUIDelay(int templateNumber)
        {
            bool showSRPWarning = false;

            if (lbTemplates != null)
            {
                int numTemplates = lbTemplates.Length;

                if (templateNumber < numTemplates)
                {
                    LBTemplate lbTemplate = lbTemplates[templateNumber];

                    if (lbTemplate != null)
                    {
                        // Disable buttons
                        EnableButton(quality1Button, false);
                        EnableButton(quality2Button, false);
                        EnableButton(quality3Button, false);
                        EnableButton(quality4Button, false);
                        EnableButton(infoButton, false);
                        EnableButton(gpuButton, false);
                        DisplayBackgroundPanel(true);

                        currentTemplateName = lbTemplate.name;

                        SetInfoTitle("Loading Template... PLEASE WAIT");

                        string infoText = "Applying template... ";

                        SetInfoText(infoText);
                        DisplayInfoPanel(true);
                        yield return(new WaitForSeconds(0.1f));

                        // Remove any camera animators
                        LBCameraAnimator.RemoveCameraAnimatorsFromScene(lbLandscape, false);
                        yield return(new WaitForSeconds(0.1f));

                        // if LBLighting is in the scene, remove all references to terrains to
                        // prevent errors when the current landscape is deleted.
                        LBLighting lbLighting = GameObject.FindObjectOfType <LBLighting>();
                        if (lbLighting != null)
                        {
                            lbLighting.ClearAllTerrains();
                        }

                        if (lbLandscape != null)
                        {
                            DestroyImmediate(lbLandscape.gameObject);
                        }
                        lbLandscape = lbTemplate.CreateLandscapeFromTemplate("DemoLandscape");
                        Camera mainCamera = Camera.main;

                        if (mainCamera != null)
                        {
                            mainCamera.transform.position = new Vector3(2000f, 2000f, 0f);
                            mainCamera.transform.LookAt(lbLandscape.transform);
                        }

                        // Currently, when applying template ignore water if LWRP, URP or HDRP are enabled
                        // This could be updated if we had a LWRP/HDRP-compatible water asset
                        if (lbTemplate.ApplyTemplateToLandscape(lbLandscape, ignoreStartPosition, true, (isURP || isLWRP || isHDRP) ? null : waterPrefab, true))
                        {
                            infoText += "DONE\n\n";
                            SetInfoText(infoText);
                            yield return(new WaitForSeconds(0.1f));

                            lbLandscape.showTiming = false;
                            lbLandscape.SetLandscapeTerrains(true);

                            // Build the landscape
                            int numTerrains = (lbLandscape.landscapeTerrains == null ? 0 : lbLandscape.landscapeTerrains.Length);
                            if (numTerrains > 0)
                            {
                                // Our older templates don't use GPU for Topography and Path. If it is fully capable
                                // of using the GPU, list it here.
                                bool isModernTemplate = lbTemplate.name.StartsWith("DemoStoneCottage");

                                // Override the template GPU settings
                                lbLandscape.useGPUTopography = isModernTemplate ? enableGPU : false;
                                lbLandscape.useGPUTexturing  = enableGPU;
                                lbLandscape.useGPUGrass      = enableGPU;
                                lbLandscape.useGPUPath       = isModernTemplate ? enableGPU : false;

                                // Check for URP/LWRP/HDRP or do we need to create a default material for U2019.2.0 or newer
                                if (isURP || isLWRP || isHDRP || is201920Plus)
                                {
                                    float   pixelError = 0f;
                                    Terrain terrain    = null;
                                    LBLandscape.TerrainMaterialType terrainMaterialType = isURP ? LBLandscape.TerrainMaterialType.URP : (isLWRP ? LBLandscape.TerrainMaterialType.LWRP : (terrainMaterialType = isHDRP ? LBLandscape.TerrainMaterialType.HDRP : LBLandscape.TerrainMaterialType.BuiltInStandard));

                                    for (int tIdx = 0; tIdx < numTerrains; tIdx++)
                                    {
                                        terrain = lbLandscape.landscapeTerrains[tIdx];
                                        lbLandscape.SetTerrainMaterial(terrain, tIdx, (tIdx == numTerrains - 1), terrain.terrainData.size.x, ref pixelError, terrainMaterialType);

                                        // For URP/LWRP/HDRP all trees will be forced to be billboarded
                                        // as currently we are only using built-in SRP trees.
                                        if (isURP || isLWRP || isHDRP)
                                        {
                                            // Force all trees to be billboards
                                            terrain.treeBillboardDistance   = 0f;
                                            terrain.treeMaximumFullLODCount = 0;
                                            showSRPWarning = true;
                                        }
                                    }
                                }

                                // These are the cut-down versions without progress bars and minimal validation
                                infoText += "Building Topography" + (lbLandscape.useGPUTopography ? " (GPU)..." : "...");
                                SetInfoText(infoText);
                                yield return(new WaitForSeconds(0.1f));

                                lbLandscape.ApplyTopography(true, true);
                                infoText += "DONE\n\n";
                                infoText += "Adding Textures" + (lbLandscape.useGPUTexturing ? " (GPU)..." : "...");
                                SetInfoText(infoText);
                                yield return(new WaitForSeconds(0.1f));

                                lbLandscape.ApplyTextures(true, true);
                                infoText += "DONE\n\n";
                                infoText += "Placing Trees... ";
                                SetInfoText(infoText);
                                yield return(new WaitForSeconds(0.1f));

                                lbLandscape.ApplyTrees(true, true);
                                infoText += "DONE\n\n";
                                infoText += "Placing Grass" + (lbLandscape.useGPUGrass ? " (GPU)..." : "...");
                                SetInfoText(infoText);
                                yield return(new WaitForSeconds(0.1f));

                                lbLandscape.ApplyGrass(true, true);
                                infoText += "DONE\n\n";
                                SetInfoText(infoText);
                                yield return(new WaitForSeconds(0.1f));

                                if (lbLandscape.lbGroupList != null && lbLandscape.lbGroupList.Count > 0)
                                {
                                    infoText += "Placing Groups" + (lbLandscape.useGPUTopography ? " (GPU)..." : "...");
                                    SetInfoText(infoText);
                                    yield return(new WaitForSeconds(0.1f));

                                    lbLandscape.ApplyGroups(false, false);
                                }

                                // Apply lighting last as it needs the Camera Paths (and Animator camera to set up WeatherFX)
                                if (lbTemplate.isLBLightingIncluded)
                                {
                                    infoText += "Applying lighting... ";
                                    SetInfoText(infoText);
                                    yield return(new WaitForSeconds(0.1f));

                                    //if (lbLighting != null) { DestroyImmediate(lbLighting.gameObject); }

                                    if (lbLighting == null)
                                    {
                                        // If LBLighting isn't already in the scene, add it.
                                        lbLighting = LBLighting.AddLightingToScene(true);
                                    }

                                    if (lbLighting != null)
                                    {
                                        // Restore the lighting settings from the template
                                        lbTemplate.ApplyLBLightingSettings(lbLandscape, ref lbLighting, mainCamera, true);
                                    }
                                    infoText += "DONE\n\n";
                                    SetInfoText(infoText);
                                    yield return(new WaitForSeconds(0.1f));

                                    // Prior to Unity 5.4, ImageFX and/or camera clear flags are not updated correctly
                                    // when the WeatherFX with celestials is added to the scene after a configuration without
                                    // celestials. The workaround, is to force the GameView to repaint or be re-initalised.
                                    // To be effective, a "reasonable" delay is required between switching away from Game view
                                    // and back. The exact cause of the issue is unknown...
                                    #if !UNITY_5_4_OR_NEWER && UNITY_EDITOR
                                    if (lbLighting.useCelestials)
                                    {
                                        bool wasMaximized = LBEditorHelper.GameViewMaximize(this.GetType(), false);
                                        LBEditorHelper.ShowSceneView(this.GetType(), true);
                                        yield return(new WaitForSeconds(0.5f));

                                        LBEditorHelper.GameViewMaximize(this.GetType(), wasMaximized);
                                    }
                                    #endif
                                }

                                // Find the first animation and start it (there should be only one in a demo template)
                                LBCameraAnimator lbCameraAnimator = LBCameraAnimator.GetFirstCameraAnimatorInLandscape(lbLandscape);
                                if (lbCameraAnimator != null)
                                {
                                    if (lbTemplate.name.StartsWith("FPS Forest Demo"))
                                    {
                                        // This uses the old Unity 4 trees which don't work so well with anti-aliasing
                                        QualitySettings.antiAliasing = 0;

                                        if (lbCameraAnimator.animatorCamera != null)
                                        {
                                            lbCameraAnimator.SetMoveSpeed(2f);
                                            lbCameraAnimator.animatorCamera.renderingPath = RenderingPath.Forward;
                                            lbCameraAnimator.animateSpeed = false;
                                        }
                                    }
                                    else if (lbTemplate.name.StartsWith("DemoStoneCottage"))
                                    {
                                        lbCameraAnimator.minMoveSpeed = 1f;
                                        lbCameraAnimator.maxMoveSpeed = 3f;
                                        lbCameraAnimator.animateSpeed = true;
                                    }
                                    else
                                    {
                                        lbCameraAnimator.animateSpeed = true;
                                    }

                                    // Reset LBImageFX timing so clouds always appear the same
                                    if (lbCameraAnimator.animatorCamera != null)
                                    {
                                        LBImageFX lbImageFX = lbCameraAnimator.animatorCamera.GetComponent <LBImageFX>();
                                        if (lbImageFX != null)
                                        {
                                            //Debug.Log("LBDemoLoader.LoadTemplateWithUIDelay - Resetting LBImageFX cloud positions");
                                            lbImageFX.ResetCloudPosition();
                                        }
                                    }

                                    //Debug.Log("LBDemoLoader " + lbTemplate.name + " renderpath: " + lbCameraAnimator.animatorCamera.renderingPath);

                                    lbCameraAnimator.pauseAtEndDuration = 999f;
                                    lbCameraAnimator.BeginAnimation(true, 0f);
                                }
                                else
                                {
                                    Debug.LogWarning("LBDemoLoader.LoadTemplateWithUIDelay - Couldn't find a camera animator in the demo template");
                                }
                            }
                        }

                        // Re-enable buttons
                        EnableButton(quality1Button, true);
                        EnableButton(quality2Button, true);
                        EnableButton(quality3Button, true);
                        EnableButton(quality4Button, true);
                        EnableButton(infoButton, true);
                        EnableButton(gpuButton, true);
                        UpdateInfoButtonText("Show Info");
                    }
                }
            }

            if (showSRPWarning)
            {
                SetInfoTitle("SRP WARNING");
                SetInfoText("This demo scene is designed for the built-in RP.\n\nSee SRP folder for into on URP and HDRP");
            }
            else
            {
                DisplayInfoPanel(false);
            }

            DisplayBackgroundPanel(false);
        }
Esempio n. 7
0
        public override void OnInspectorGUI()
        {
            // If the base command is called, all public fields not hidden, will be displayed
            //base.OnInspectorGUI();

            EditorGUIUtility.labelWidth = 150f;

            if (labelFieldRichText == null)
            {
                labelFieldRichText          = new GUIStyle("Label");
                labelFieldRichText.richText = true;
            }

            EditorGUILayout.BeginVertical(EditorStyles.helpBox);

            // Read in all the properties
            serializedObject.Update();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Landscape Name</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            EditorGUILayout.PropertyField(landscapeNameProp, GUIContent.none);
            EditorGUILayout.EndHorizontal();

            // This is the installed version of LB when the template was created
            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Landscape Version</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + lastUpdatedVersionProp.stringValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            // This is the installed version of LB when the template was created
            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>LB Version</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + lbVersionProp.stringValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            // This is the installed version of Unity when the template was created
            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Unity Version</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + templateUnityVersionProp.stringValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Landscape Size</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + sizeProp.vector2Value + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Start Position</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">X: " + startProp.vector3Value.x + " Y: " + startProp.vector3Value.y + " Z: " + startProp.vector3Value.z + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Heightmap Resolution</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + heightmapResolutionProp.intValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Terrain Width</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + terrainWidthProp.floatValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Terrain Height</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + terrainHeightProp.floatValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Alphamap Resolution</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + alphaMapResolutionProp.intValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Terrain Material Type</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            EditorGUILayout.PropertyField(terrainMaterialTypeProp, GUIContent.none);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Legacy Noise Offset</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + useLegacyNoiseOffsetProp.boolValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            labelText = "<color=" + txtColourName + "><b>GPU Acceleration</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>  Topography</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + useGPUTopographyProp.boolValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>  Texturing</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + useGPUTexturingProp.boolValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>  Grass</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + useGPUGrassProp.boolValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>  Path</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            labelText = "<color=" + txtColourName + ">" + useGPUPathProp.boolValue + "</color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Populate Landscape</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            EditorGUILayout.PropertyField(isPopulateLandscapeProp, new GUIContent(""), GUILayout.Width(30));
            EditorGUILayout.EndHorizontal();

            if (GUILayout.Button("Create New unpopulated Landscape from Template"))
            {
                if (lbTemplate == null)
                {
                    Debug.LogWarning("LBTemplateEditor - create landscape - template not defined. Please Report");
                }
                else if (string.IsNullOrEmpty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().name))
                {
                    EditorUtility.DisplayDialog("Generate Landscape", "Please save the scene before adding a landscape.", "Got it!");
                }
                else
                {
                    LBLandscape lbLandscape = lbTemplate.CreateLandscapeFromTemplate(lbTemplate.landscapeName);
                    UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
                    if (lbLandscape != null)
                    {
                        lbTemplate.ApplyTemplateToLandscape(lbLandscape, false, true, null, true);
                        if (isPopulateLandscapeProp.boolValue)
                        {
                            lbLandscape.ApplyTopography(false, true);
                            lbLandscape.ApplyTextures(false, true);
                            lbLandscape.ApplyTrees(false, true);
                            lbLandscape.ApplyGrass(false, true);
                            lbLandscape.ApplyGroups(false, true);
                            lbLandscape.ApplyMeshes(false, true);
                        }

                        if (lbTemplate.isLBLightingIncluded)
                        {
                            LBLighting lbLighting = GameObject.FindObjectOfType <LBLighting>();
                            if (lbLighting == null)
                            {
                                // If LBLighting isn't already in the scene, add it.
                                lbLighting = LBLighting.AddLightingToScene(true);
                            }

                            if (lbLighting != null)
                            {
                                // Restore the lighting settings from the template
                                lbTemplate.ApplyLBLightingSettings(lbLandscape, ref lbLighting, Camera.main, true);
                            }
                        }

                        LandscapeBuilderWindow.SetLandscape(lbLandscape, true);
                        // Prevent errors in editor for U2017
                        //EditorGUILayout.EndVertical();
                        //return;
                    }
                }
            }

            EditorGUILayout.BeginHorizontal();
            labelText = "<color=" + txtColourName + "><b>Debug Mode</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText, GUILayout.Width(EditorGUIUtility.labelWidth));
            EditorGUILayout.PropertyField(debugModeProp, new GUIContent(""), GUILayout.Width(30));
            labelText = "<color=" + txtColourName + "><b>INTERNAL USE ONLY</b></color>";
            EditorGUILayout.LabelField(labelText, labelFieldRichText);
            EditorGUILayout.EndHorizontal();

            serializedObject.ApplyModifiedProperties();

            if (debugModeProp.boolValue)
            {
                // Display unhidden public variables in LBTemplate.cs
                DrawDefaultInspector();
            }

            EditorGUILayout.EndVertical();
        }
        public static bool SaveTemplate
        (
            LBLandscape landscape,
            string LBEditorVersion,
            string landscapeTemplateName,
            ref bool isSceneSaveRequired,
            bool createTemplatePackage,
            bool addMapTexturesToTemplatePackage,
            bool addLayerHeightmapTexturesToTemplatePackage,
            bool addLBLightingToTemplate,
            bool addPathsToTemplate,
            bool addStencilsToTemplate,
            bool addPathMeshMaterialsToTemplate
        )
        {
            bool isSuccessful = false;

            string landscapeName = landscape.name;

            // Create a new gameobject in the scene hierarchy that we can turn into a prefab
            GameObject newTemplateObj = new GameObject(landscapeName + " template");

            if (newTemplateObj == null)
            {
                Debug.LogWarning("Landscape Builder - could not create temporary gameobject for " + landscapeName + " template");
            }
            else
            {
                LBTemplate lbTemplate = newTemplateObj.AddComponent <LBTemplate>();
                if (lbTemplate == null)
                {
                    Debug.LogWarning("Landscape Builder - could not add LBTemplate component " + landscapeName + " template");
                    GameObject.DestroyImmediate(newTemplateObj);
                }
                else
                {
                    // This is the installed version of LB when the template was created
                    lbTemplate.LBVersion = LBEditorVersion;
                    // This is the version of the landscape when the template was created
                    lbTemplate.LastUpdatedVersion = landscape.LastUpdatedVersion;

                    // The version of Unity that created this template
                    lbTemplate.templateUnityVersion = Application.unityVersion;

                    lbTemplate.useLegacyNoiseOffset = landscape.useLegacyNoiseOffset;

                    // Name of the landscape game object
                    lbTemplate.landscapeName = landscapeName;
                    lbTemplate.size          = landscape.size;
                    lbTemplate.start         = landscape.start;

                    // Landscape terrain settings
                    Vector3 terrainSize3D = landscape.GetLandscapeTerrainSize();
                    lbTemplate.heightmapResolution       = landscape.GetLandscapeTerrainHeightmapResolution();
                    lbTemplate.terrainWidth              = terrainSize3D.x;
                    lbTemplate.terrainHeight             = terrainSize3D.y;
                    lbTemplate.pixelError                = landscape.GetLandscapeTerrainPixelError();
                    lbTemplate.baseMapDistance           = landscape.GetLandscapeTerrainBaseMapDist();
                    lbTemplate.alphaMapResolution        = landscape.GetLandscapeTerrainAlphaMapResolution();
                    lbTemplate.baseTextureResolution     = landscape.GetLandscapeTerrainBaseTextureResolution();
                    lbTemplate.treeDistance              = landscape.GetLandscapeTerrainTreeDistance();
                    lbTemplate.treeBillboardDistance     = landscape.GetLandscapeTerrainTreeBillboardStart();
                    lbTemplate.detailDistance            = landscape.GetLandscapeTerrainDetailDistance();
                    lbTemplate.detailDensity             = landscape.GetLandscapeTerrainDetailDensity();
                    lbTemplate.detailResolution          = landscape.GetLandscapeTerrainDetailResolution();
                    lbTemplate.treeFadeDistance          = landscape.GetLandscapeTerrainTreeFadeLength();
                    lbTemplate.grassWindSpeed            = landscape.GetLandscapeTerrainGrassWindSpeed();
                    lbTemplate.grassWindRippleSize       = landscape.GetLandscapeTerrainGrassWindRippleSize();
                    lbTemplate.grassWindBending          = landscape.GetLandscapeTerrainGrassWindBending();
                    lbTemplate.grassWindTint             = landscape.GetLandscapeTerrainGrassWindTint();
                    lbTemplate.terrainLegacySpecular     = landscape.GetLandscapeTerrainLegacySpecular();
                    lbTemplate.terrainLegacyShininess    = landscape.GetLandscapeTerrainLegacyShininess();
                    lbTemplate.useTerrainDrawInstanced   = landscape.GetLandscapeTerrainDrawInstanced();
                    lbTemplate.useTerrainPerPixelNormals = GetTerrainPerPixelNormals(landscape);
                    lbTemplate.terrainGroupingID         = landscape.GetLandscapeTerrainGroupingID();
                    lbTemplate.terrainAutoConnect        = landscape.GetLandscapeTerrainAutoConnect();

                    // Synchronize with a duplicate enum in lbTemplate
                    lbTemplate.terrainMaterialType = (LBTemplate.TerrainMaterialType)landscape.GetTerrainMaterialType();

                    // Check if any lists are null
                    if (landscape.topographyLayersList == null)
                    {
                        landscape.topographyLayersList = new List <LBLayer>();
                    }
                    if (landscape.terrainTexturesList == null)
                    {
                        landscape.terrainTexturesList = new List <LBTerrainTexture>();
                    }
                    if (landscape.terrainTreesList == null)
                    {
                        landscape.terrainTreesList = new List <LBTerrainTree>();
                    }
                    if (landscape.terrainGrassList == null)
                    {
                        landscape.terrainGrassList = new List <LBTerrainGrass>();
                    }
                    if (landscape.lbGroupList == null)
                    {
                        landscape.lbGroupList = new List <LBGroup>();
                    }
                    if (landscape.landscapeMeshList == null)
                    {
                        landscape.landscapeMeshList = new List <LBLandscapeMesh>();
                    }
                    if (landscape.landscapeWaterList == null)
                    {
                        landscape.landscapeWaterList = new List <LBWater>();
                    }

                    // Update texture names to help detect missing textures when importing templates into another project
                    for (int txIdx = 0; txIdx < landscape.terrainTexturesList.Count; txIdx++)
                    {
                        // Only attempt to update the textureName if it is null or an empty string.
                        // This avoids loosing details about an already missing texture
                        if (string.IsNullOrEmpty(landscape.terrainTexturesList[txIdx].textureName))
                        {
                            if (landscape.terrainTexturesList[txIdx].texture != null)
                            {
                                landscape.terrainTexturesList[txIdx].textureName = landscape.terrainTexturesList[txIdx].texture.name;
                                isSceneSaveRequired = true;
                            }
                        }

                        // Only attempt to update the normalMapName if it is null or an empty string.
                        // This avoids loosing details about an already missing normalMap
                        if (string.IsNullOrEmpty(landscape.terrainTexturesList[txIdx].normalMapName))
                        {
                            if (landscape.terrainTexturesList[txIdx].normalMap != null)
                            {
                                landscape.terrainTexturesList[txIdx].normalMapName = landscape.terrainTexturesList[txIdx].normalMap.name;
                                isSceneSaveRequired = true;
                            }
                        }
                    }

                    // Update Grass texture names to help detect missing textures when importing templates into another project
                    for (int grIdx = 0; grIdx < landscape.terrainGrassList.Count; grIdx++)
                    {
                        // Only attempt to update the grass textureName if it is null or an empty string.
                        // This avoids loosing details about an already missing grass texture
                        if (string.IsNullOrEmpty(landscape.terrainGrassList[grIdx].textureName))
                        {
                            if (landscape.terrainGrassList[grIdx].texture != null)
                            {
                                landscape.terrainGrassList[grIdx].textureName = landscape.terrainGrassList[grIdx].texture.name;
                                isSceneSaveRequired = true;
                            }
                        }

                        // Only attempt to update the grass meshPrefName if it is null or an empty string.
                        // This avoids loosing details about an already missing grass mesh prefab
                        if (string.IsNullOrEmpty(landscape.terrainGrassList[grIdx].meshPrefabName))
                        {
                            if (landscape.terrainGrassList[grIdx].meshPrefab != null)
                            {
                                landscape.terrainGrassList[grIdx].meshPrefabName = landscape.terrainGrassList[grIdx].meshPrefab.name;
                                isSceneSaveRequired = true;
                            }
                        }
                    }

                    // Update Tree prefab names to help detect missing prefabs when importing templates into another project
                    for (int trIdx = 0; trIdx < landscape.terrainTreesList.Count; trIdx++)
                    {
                        // Only attempt to update the tree prefabName if it is null or an empty string.
                        // This avoids loosing details about an already missing tree prefab
                        if (string.IsNullOrEmpty(landscape.terrainTreesList[trIdx].prefabName))
                        {
                            if (landscape.terrainTreesList[trIdx].prefab != null)
                            {
                                landscape.terrainTreesList[trIdx].prefabName = landscape.terrainTreesList[trIdx].prefab.name;
                                isSceneSaveRequired = true;
                            }
                        }
                    }

                    // Update Mesh prefab names to help detect missing prefabs when importing templates into another project
                    for (int meshIdx = 0; meshIdx < landscape.landscapeMeshList.Count; meshIdx++)
                    {
                        // Only attempt to update the mesh prefabName if it is null or an empty string.
                        // This avoids loosing details about an already missing mesh prefab
                        if (string.IsNullOrEmpty(landscape.landscapeMeshList[meshIdx].prefabName))
                        {
                            if (landscape.landscapeMeshList[meshIdx].prefab != null)
                            {
                                landscape.landscapeMeshList[meshIdx].prefabName = landscape.landscapeMeshList[meshIdx].prefab.name;
                                isSceneSaveRequired = true;
                            }
                        }
                    }

                    int numGroups = landscape.lbGroupList == null ? 0 : landscape.lbGroupList.Count;

                    // Update Group Member prefab names to help detect missing prefabs when importing templates into another project
                    for (int grpIdx = 0; grpIdx < numGroups; grpIdx++)
                    {
                        if (landscape.lbGroupList[grpIdx].groupMemberList != null)
                        {
                            List <LBGroupMember> groupMemberList = landscape.lbGroupList[grpIdx].groupMemberList;
                            for (int grpMbrIdx = 0; grpMbrIdx < groupMemberList.Count; grpMbrIdx++)
                            {
                                // Only attempt to update the prefab prefabName if it is null or an empty string.
                                // This avoids loosing details about an already missing prefab
                                if (string.IsNullOrEmpty(groupMemberList[grpMbrIdx].prefabName))
                                {
                                    if (groupMemberList[grpMbrIdx].prefab != null)
                                    {
                                        groupMemberList[grpMbrIdx].prefabName = groupMemberList[grpMbrIdx].prefab.name;
                                        isSceneSaveRequired = true;
                                    }
                                }
                            }
                        }
                    }

                    // Landscape class lists - perform deep copy (#SMS 2.0.6 Beta 6f)
                    // Attempts to avoid issue where a template prefab is created (and later deleted) which could delete data
                    // from the landscape meta-data in the scene.
                    lbTemplate.topographyLayersList = landscape.topographyLayersList.ConvertAll(lyr => new LBLayer(lyr));
                    lbTemplate.terrainTexturesList  = landscape.terrainTexturesList.ConvertAll(tt => new LBTerrainTexture(tt));
                    lbTemplate.terrainTreesList     = landscape.terrainTreesList.ConvertAll(tt => new LBTerrainTree(tt));
                    lbTemplate.terrainGrassList     = landscape.terrainGrassList.ConvertAll(tg => new LBTerrainGrass(tg));
                    lbTemplate.lbGroupList          = landscape.lbGroupList.ConvertAll(grp => new LBGroup(grp));
                    lbTemplate.landscapeMeshList    = landscape.landscapeMeshList.ConvertAll(msh => new LBLandscapeMesh(msh));
                    lbTemplate.landscapeWaterList   = landscape.landscapeWaterList.ConvertAll(wtr => new LBWater(wtr, false));

                    // Check for surface and/or base mesh materials in Group Object Paths
                    for (int grpIdx = 0; grpIdx < numGroups; grpIdx++)
                    {
                        int numGrpMembers = landscape.lbGroupList[grpIdx].groupMemberList == null ? 0 : landscape.lbGroupList[grpIdx].groupMemberList.Count;

                        for (int grpMbrIdx = 0; grpMbrIdx < numGrpMembers; grpMbrIdx++)
                        {
                            LBGroupMember _lbGroupMember = landscape.lbGroupList[grpIdx].groupMemberList[grpMbrIdx];
                            // A deep copy will attempt create a new instance of the material using our LBGroupMember clone constructor
                            // In this case we need to reference the actual material in the project folder.
                            // If the Object Path was a duplicate of an existing Object Path, then this may also fail.
                            if (_lbGroupMember != null && _lbGroupMember.lbMemberType == LBGroupMember.LBMemberType.ObjPath && _lbGroupMember.lbObjPath != null)
                            {
                                lbTemplate.lbGroupList[grpIdx].groupMemberList[grpMbrIdx].lbObjPath.surfaceMeshMaterial = _lbGroupMember.lbObjPath.surfaceMeshMaterial;
                                lbTemplate.lbGroupList[grpIdx].groupMemberList[grpMbrIdx].lbObjPath.baseMeshMaterial    = _lbGroupMember.lbObjPath.baseMeshMaterial;
                            }
                        }
                    }

                    // Final Pass varibles
                    lbTemplate.useFinalPassSmoothing        = landscape.useFinalPassSmoothing;
                    lbTemplate.finalPassSmoothingIterations = landscape.finalPassSmoothingIterations;
                    lbTemplate.finalPassPixelRange          = landscape.finalPassPixelRange;
                    lbTemplate.fPassSmoothStencilGUID       = landscape.fPassSmoothStencilGUID;
                    lbTemplate.fPassSmoothStencilLayerGUID  = landscape.fPassSmoothStencilLayerGUID;
                    lbTemplate.fPassSmoothFilterMode        = landscape.fPassSmoothFilterMode;

                    lbTemplate.thermalErosionPreset           = landscape.thermalErosionPreset;
                    lbTemplate.useThermalErosion              = landscape.useThermalErosion;
                    lbTemplate.thermalErosionIterations       = landscape.thermalErosionIterations;
                    lbTemplate.thermalErosionTalusAngle       = landscape.thermalErosionTalusAngle;
                    lbTemplate.thermalErosionStrength         = landscape.thermalErosionStrength;
                    lbTemplate.fPassThErosionStencilGUID      = landscape.fPassThErosionStencilGUID;
                    lbTemplate.fPassThErosionStencilLayerGUID = landscape.fPassThErosionStencilLayerGUID;
                    lbTemplate.fPassThErosionFilterMode       = landscape.fPassThErosionFilterMode;

                    // Group Settings
                    lbTemplate.autoRefreshGroupDesigner = landscape.autoRefreshGroupDesigner;

                    // Vegetation Integration variables
                    lbTemplate.useVegetationSystem         = landscape.useVegetationSystem;
                    lbTemplate.useVegetationSystemTextures = landscape.useVegetationSystemTextures;

                    // Landscape Extension
                    lbTemplate.useLandscapeExtension = landscape.useLandscapeExtension;
                    if (landscape.lbLandscapeExtension != null)
                    {
                        lbTemplate.lbLandscapeExtension = new LBLandscapeExtension(landscape.lbLandscapeExtension);
                    }
                    else
                    {
                        lbTemplate.lbLandscapeExtension = new LBLandscapeExtension();
                    }

                    // GPU acceleration
                    lbTemplate.useGPUTexturing  = landscape.useGPUTexturing;
                    lbTemplate.useGPUTopography = landscape.useGPUTopography;
                    lbTemplate.useGPUGrass      = landscape.useGPUGrass;
                    lbTemplate.useGPUPath       = landscape.useGPUPath;

                    // Undo override
                    lbTemplate.isUndoTopographyDisabled = landscape.isUndoTopographyDisabled;

                    // Topography Mask - there is one per landscape
                    lbTemplate.topographyMaskMode     = (LBTemplate.MaskMode)landscape.topographyMaskMode;
                    lbTemplate.distanceToCentreMask   = landscape.distanceToCentreMask;
                    lbTemplate.maskWarpAmount         = landscape.maskWarpAmount;
                    lbTemplate.maskNoiseTileSize      = landscape.maskNoiseTileSize;
                    lbTemplate.maskNoiseOffsetX       = landscape.maskNoiseOffsetX;
                    lbTemplate.maskNoiseOffsetY       = landscape.maskNoiseOffsetY;
                    lbTemplate.maskNoiseCurveModifier = landscape.maskNoiseCurveModifier;

                    // Does user wish to include LBLighting?
                    if (addLBLightingToTemplate)
                    {
                        // Only include LBLighting if it is in the scene
                        LBLighting lbLighting = GameObject.FindObjectOfType <LBLighting>();
                        if (lbLighting == null)
                        {
                            lbTemplate.isLBLightingIncluded = false;
                            Debug.LogWarning("Landscape Builder - Export Template - No LBLighting found in the scene");
                        }
                        else
                        {
                            lbTemplate.isLBLightingIncluded = true;
                            lbTemplate.AddLBLightingSettings(lbLighting);
                        }
                    }
                    else
                    {
                        lbTemplate.isLBLightingIncluded = false;
                    }

                    // Create an empty list of Asset Paths for the mesh materials
                    List <string> lbMapPathMaterialAssetPathList = new List <string>();

                    if (addPathsToTemplate)
                    {
                        // Find any Camera Paths in this landscape (changed from all in scene in 1.3.2 Beta 9b)
                        List <LBCameraPath> lbCameraPathList = LBCameraPath.GetCameraPathsInLandscape(landscape);
                        if (lbCameraPathList != null)
                        {
                            // Get the LBPath from each LBCameraPath and add it to the LBTemplate instance
                            foreach (LBCameraPath lbCameraPath in lbCameraPathList)
                            {
                                if (lbCameraPath.lbPath != null)
                                {
                                    // Update the path name before adding to the template
                                    if (lbCameraPath.gameObject != null)
                                    {
                                        lbCameraPath.lbPath.pathName = lbCameraPath.gameObject.name;
                                        isSceneSaveRequired          = true;
                                    }
                                    lbTemplate.lbPathList.Add(lbCameraPath.lbPath);
                                }
                            }
                        }

                        // Find all MapPaths in the this landscape
                        List <LBMapPath> lbMapPathList = LBMapPath.GetMapPathsInLandscape(landscape);
                        if (lbMapPathList != null)
                        {
                            // Get the LBPath from each LBMapPath and add it to the LBTemplate instance
                            foreach (LBMapPath lbMapPath in lbMapPathList)
                            {
                                if (lbMapPath.lbPath != null)
                                {
                                    // Update the path name before adding to the template
                                    if (lbMapPath.gameObject != null)
                                    {
                                        lbMapPath.lbPath.pathName = lbMapPath.gameObject.name;

                                        // Check for a mesh
                                        if (lbMapPath.lbPath.lbMesh != null && addPathMeshMaterialsToTemplate)
                                        {
                                            lbMapPath.lbPath.meshTempMaterial = lbMapPath.meshMaterial;

                                            // If also creating a package, remember the asset path for this mesh material
                                            if (createTemplatePackage)
                                            {
                                                string mapPathMatAssetPath = UnityEditor.AssetDatabase.GetAssetPath(lbMapPath.meshMaterial);
                                                if (!string.IsNullOrEmpty(mapPathMatAssetPath))
                                                {
                                                    lbMapPathMaterialAssetPathList.Add(mapPathMatAssetPath);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            lbMapPath.lbPath.meshTempMaterial = null;
                                        }

                                        isSceneSaveRequired = true;
                                    }
                                    lbTemplate.lbPathList.Add(lbMapPath.lbPath);
                                }
                            }
                        }
                    }

                    if (addStencilsToTemplate)
                    {
                        List <LBStencil> lbStencilList = LBStencil.GetStencilsInLandscape(landscape, true);
                        if (lbTemplate.lbTemplateStencilList == null)
                        {
                            lbTemplate.lbTemplateStencilList = new List <LBTemplateStencil>();
                        }

                        if (lbTemplate.lbTemplateStencilList != null && lbStencilList != null)
                        {
                            // Create a LBTemplateStencil for each Stencil in the landscape, and add it to the Template.
                            // NOTE Does not copy the USHORT layerArray or render textures in the Stencil Layers as we want to keep
                            // the Template as small as possible.
                            foreach (LBStencil lbStencil in lbStencilList)
                            {
                                if (lbStencil != null)
                                {
                                    LBTemplateStencil lbTemplateStencil = new LBTemplateStencil(lbStencil);
                                    if (lbTemplateStencil != null)
                                    {
                                        lbTemplate.lbTemplateStencilList.Add(lbTemplateStencil);
                                    }
                                }
                            }
                        }
                    }

                    // Create template folders if they don't already exist
                    LBEditorHelper.CheckFolder("Assets/LandscapeBuilder/Templates");

                    if (!Directory.Exists("LandscapeBuilder/TemplatePackages"))
                    {
                        Directory.CreateDirectory("LandscapeBuilder/TemplatePackages");
                    }

                    // Create a prefab
                    bool   continueToSave    = false;
                    string templateFullPath  = Application.dataPath + "/LandscapeBuilder/Templates/" + landscapeTemplateName + ".prefab";
                    string templateAssetPath = "Assets/LandscapeBuilder/Templates/" + landscapeTemplateName + ".prefab";
                    if (File.Exists(templateFullPath))
                    {
                        if (EditorUtility.DisplayDialog("Template Already Exists", "Are you sure you want to save the template? The currently existing" +
                                                        " template will be lost.", "Overwrite", "Cancel"))
                        {
                            if (!AssetDatabase.DeleteAsset(templateAssetPath))
                            {
                                Debug.LogWarning("Landscape Builder - could not overwrite Assets/LandscapeBuilder/Templates/" + landscapeTemplateName + " for " + landscapeName + " template");
                            }
                            else
                            {
                                continueToSave = true;
                            }
                        }
                    }
                    else
                    {
                        continueToSave = true;
                    }

                    if (continueToSave)
                    {
                        #if UNITY_2018_3_OR_NEWER
                        GameObject templatePrefabGO = PrefabUtility.SaveAsPrefabAsset(newTemplateObj, templateAssetPath);
                        #else
                        GameObject templatePrefabGO = PrefabUtility.CreatePrefab(templateAssetPath, newTemplateObj);
                        #endif

                        if (templatePrefabGO != null && createTemplatePackage)
                        {
                            // Always include the template prefab (this is meta-data only)
                            List <string> templateAssetPaths = new List <string>();
                            templateAssetPaths.Add(templateAssetPath);

                            // Although technically users could include 3rd party textures in a LBMap texture, they are MUCH more likely to use
                            // map textures generated from within Landscape Builder.
                            if (addMapTexturesToTemplatePackage)
                            {
                                List <string> uniqueMapTexPaths = LBLandscapeOperations.GetMapTextureAssetPathsFromLandscape(landscape, true);
                                if (uniqueMapTexPaths != null)
                                {
                                    if (uniqueMapTexPaths.Count > 0)
                                    {
                                        templateAssetPaths.AddRange(uniqueMapTexPaths);
                                    }
                                }
                            }

                            if (addLayerHeightmapTexturesToTemplatePackage)
                            {
                                // Get a list of the image-based topography layers with a heightmap texture
                                List <LBLayer> layerList = landscape.topographyLayersList.FindAll(lyr => lyr.heightmapImage != null && (lyr.type == LBLayer.LayerType.ImageBase || lyr.type == LBLayer.LayerType.ImageAdditive || lyr.type == LBLayer.LayerType.ImageSubtractive || lyr.type == LBLayer.LayerType.ImageDetail));
                                if (layerList != null)
                                {
                                    //Debug.Log("Save Template found " + layerList.Count + " image layers with a heightmap");
                                    for (int lyrIdx = 0; lyrIdx < layerList.Count; lyrIdx++)
                                    {
                                        // Get the path in the asset db to the image-based layer heightmap texture
                                        string heightmapPath = UnityEditor.AssetDatabase.GetAssetPath(layerList[lyrIdx].heightmapImage);
                                        if (!string.IsNullOrEmpty(heightmapPath))
                                        {
                                            templateAssetPaths.Add(heightmapPath);
                                        }
                                    }
                                }
                            }

                            // Add the list of map path mesh materials we add earlier.
                            if (addPathMeshMaterialsToTemplate && lbMapPathMaterialAssetPathList.Count > 0)
                            {
                                templateAssetPaths.AddRange(lbMapPathMaterialAssetPathList);
                            }

                            AssetDatabase.ExportPackage(templateAssetPaths.ToArray(), "LandscapeBuilder/TemplatePackages/" + landscapeTemplateName + ".unitypackage", ExportPackageOptions.Interactive);
                        }
                        LBEditorHelper.HighlightItemInProjectWindow(templateAssetPath);
                    }

                    // Cleanup scene hierarchy
                    GameObject.DestroyImmediate(newTemplateObj);
                }
            }

            return(isSuccessful);
        }