private void DrawGrass() { EditorGUILayout.LabelField("Items", EditorStyles.boldLabel); grassScrollPos = EditorGUILayout.BeginScrollView(grassScrollPos, EditorStyles.textArea, GUILayout.Height(thumbSize + 10f)); using (new EditorGUILayout.HorizontalScope()) { for (int i = 0; i < script.grassPrefabs.Count; i++) { Texture2D thumb = AssetPreview.GetAssetPreview(script.grassPrefabs[i].prefab); if (script.grassPrefabs[i].type == SpawnerBase.GrassType.Billboard) { thumb = script.grassPrefabs[i].billboard; } if (thumb == null) { thumb = EditorGUIUtility.IconContent("d_BuildSettings.Broadcom").image as Texture2D; } if (GUILayout.Button(new GUIContent("", thumb), (selectedGrassID == i) ? VegetationSpawnerEditor.PreviewTexSelected : VegetationSpawnerEditor.PreviewTex, GUILayout.MinHeight(thumbSize), GUILayout.MaxWidth(thumbSize), GUILayout.MaxHeight(thumbSize))) { selectedGrassID = i; } } } EditorGUILayout.EndScrollView(); //Edge case: Clamp in case there's a switch to scene with less items selectedGrassID = Mathf.Min(selectedGrassID, script.grassPrefabs.Count - 1); VegetationSpawner.GrassPrefab grass = script.grassPrefabs.Count > 0 ? script.grassPrefabs[selectedGrassID] : null; using (new EditorGUILayout.HorizontalScope()) { if (grass != null) { EditorGUILayout.LabelField("Instances: " + grass.instanceCount.ToString("##,#"), EditorStyles.miniLabel); } GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent("Add", EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Toolbar Plus" : "Toolbar Plus").image, "Add new item"))) { VegetationSpawner.GrassPrefab newGrass = new SpawnerBase.GrassPrefab(); script.grassPrefabs.Add(newGrass); newGrass.seed = Random.Range(0, 9999); selectedGrassID = script.grassPrefabs.Count - 1; newGrass.index = script.grassPrefabs.Count; script.RefreshGrassPrototypes(); } if (GUILayout.Button(new GUIContent("", EditorGUIUtility.IconContent("TreeEditor.Duplicate").image, "Duplicate item"))) { GrassPrefab newGrass = Duplicate(script.grassPrefabs[selectedGrassID]); script.grassPrefabs.Add(newGrass); selectedGrassID = script.grassPrefabs.Count - 1; newGrass.index = script.grassPrefabs.Count; script.RefreshGrassPrototypes(); //Spawn it now so changes are visible script.SpawnGrass(script.grassPrefabs[selectedGrassID]); } if (GUILayout.Button(new GUIContent("", EditorGUIUtility.IconContent("d_TreeEditor.Trash").image, "Remove"))) { script.grassPrefabs.RemoveAt(selectedGrassID); selectedGrassID = script.grassPrefabs.Count - 1; script.RefreshGrassPrototypes(); } } if (grass != null) { Undo.RecordObject(script, "Modified grass item"); serializedObject.Update(); using (var grassChange = new EditorGUI.ChangeCheckScope()) { EditorGUILayout.LabelField("Appearance", EditorStyles.boldLabel); grass.type = (SpawnerBase.GrassType)EditorGUILayout.Popup("Render type", (int)grass.type, new string[] { "Mesh", "Billboard" }); if (grass.type == SpawnerBase.GrassType.Mesh) { grass.prefab = EditorGUILayout.ObjectField("Prefab", grass.prefab, typeof(GameObject), true) as GameObject; } if (grass.type == SpawnerBase.GrassType.Billboard) { grass.billboard = EditorGUILayout.ObjectField("Billboard", grass.billboard, typeof(Texture2D), true) as Texture2D; } grass.mainColor = EditorGUILayout.ColorField("Main", grass.mainColor); grass.linkColors = EditorGUILayout.Toggle(new GUIContent("Link", "Set the main and secondary color with one value"), grass.linkColors); if (grass.linkColors) { grass.secondairyColor = grass.mainColor; } else { grass.secondairyColor = EditorGUILayout.ColorField("Secondary", grass.secondairyColor); } VegetationSpawnerEditor.DrawRangeSlider(new GUIContent("Width", "Min/max width of the mesh"), ref grass.minMaxWidth, 0f, 2f); VegetationSpawnerEditor.DrawRangeSlider(new GUIContent("Length", "Min/max length of the mesh"), ref grass.minMaxHeight, 0f, 2f); if (grassChange.changed) { EditorUtility.SetDirty(target); script.UpdateProperties(grass); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Spawning rules", EditorStyles.boldLabel); using (new EditorGUILayout.HorizontalScope()) { grass.seed = EditorGUILayout.IntField("Seed", grass.seed, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 50f)); if (GUILayout.Button("Randomize", GUILayout.MaxWidth(100f))) { grass.seed = Random.Range(0, 99999); } } grass.probability = EditorGUILayout.Slider("Spawn chance %", grass.probability, 0f, 100f); EditorGUILayout.Space(); grass.collisionCheck = EditorGUILayout.Toggle(new GUIContent("Collision check", "Take into account the collision cache to avoid spawning inside colliders (see Settings tab)"), grass.collisionCheck); grass.rejectUnderwater = EditorGUILayout.Toggle(new GUIContent("Remove underwater", "The water height level can be set in the settings tab"), grass.rejectUnderwater); VegetationSpawnerEditor.DrawRangeSlider(new GUIContent("Height range", "Min/max height this item can spawn at"), ref grass.heightRange, 0f, 1000f); VegetationSpawnerEditor.DrawRangeSlider(new GUIContent("Slope range", "Min/max slope (0-90 degrees) this item can spawn at"), ref grass.slopeRange, 0f, 90f); VegetationSpawnerEditor.DrawRangeSlider(new GUIContent("Curvature range", "0=Concave (bowl), 0.5=flat, 1=convex (edge)"), ref grass.curvatureRange, 0f, 1f); EditorGUILayout.Space(); LayerMaskSettings(grass.layerMasks); if (grassChange.changed) { serializedObject.ApplyModifiedProperties(); } } EditorGUILayout.Space(); if (GUILayout.Button(new GUIContent(" Respawn", EditorGUIUtility.IconContent("d_Refresh").image), GUILayout.Height(30f))) { Stopwatch sw = new Stopwatch(); sw.Restart(); script.SpawnGrass(script.grassPrefabs[selectedGrassID]); sw.Stop(); Log.Add("Respawning grass: " + sw.Elapsed.Seconds + " seconds..."); } } }
private void DrawGrass() { EditorGUILayout.LabelField("Items", EditorStyles.boldLabel); //Edge case: Clamp in case there's a switch to scene with less items selectedGrassID = Mathf.Min(selectedGrassID, spawner.grassPrefabs.Count - 1); grassScrollPos = EditorGUILayout.BeginScrollView(grassScrollPos, EditorStyles.helpBox, GUILayout.MaxHeight(thumbSize + 10f), GUILayout.MinHeight(thumbSize + 10f)); using (new EditorGUILayout.HorizontalScope()) { for (int i = 0; i < spawner.grassPrefabs.Count; i++) { if (spawner.grassPrefabs[i] == null) { continue; } Texture2D thumb = spawner.grassPrefabs[i].billboard; if (spawner.grassPrefabs[i].type == SpawnerBase.GrassType.Mesh) { thumb = AssetPreview.GetAssetPreview(spawner.grassPrefabs[i].prefab); } if (thumb == null) { thumb = EditorGUIUtility.IconContent("d_BuildSettings.Broadcom").image as Texture2D; } if (GUILayout.Button(new GUIContent(spawner.grassPrefabs[i].name, thumb), (selectedGrassID == i) ? VegetationSpawnerEditor.PreviewTexSelected : VegetationSpawnerEditor.PreviewTex, GUILayout.Height(thumbSize), GUILayout.Width(thumbSize))) { selectedGrassID = i; } } } EditorGUILayout.EndScrollView(); VegetationSpawner.GrassPrefab grass = GetGrassPrefab(selectedGrassID); Undo.RecordObject(spawner, "Modified grass"); serializedObject.Update(); using (var grassChange = new EditorGUI.ChangeCheckScope()) { using (new EditorGUILayout.HorizontalScope()) { if (grass != null) { EditorGUILayout.LabelField("Instances: " + grass.instanceCount.ToString("##,#"), EditorStyles.miniLabel); } GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent("Add", EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Toolbar Plus" : "Toolbar Plus").image, "Add new item"), EditorStyles.miniButtonLeft, GUILayout.Width(60f))) { VegetationSpawner.GrassPrefab newGrass = new SpawnerBase.GrassPrefab(); spawner.grassPrefabs.Add(newGrass); newGrass.seed = Random.Range(0, 9999); selectedGrassID = spawner.grassPrefabs.Count - 1; newGrass.index = spawner.grassPrefabs.Count; spawner.RefreshGrassPrototypes(); } using (new EditorGUI.DisabledScope(grass == null)) { if (GUILayout.Button(new GUIContent("", EditorGUIUtility.IconContent("TreeEditor.Duplicate").image, "Duplicate item"), EditorStyles.miniButtonMid)) { SpawnerBase.GrassPrefab newGrass = SpawnerBase.GrassPrefab.Duplicate(spawner.grassPrefabs[selectedGrassID]); spawner.grassPrefabs.Add(newGrass); selectedGrassID = spawner.grassPrefabs.Count - 1; newGrass.index = spawner.grassPrefabs.Count; spawner.RefreshGrassPrototypes(); //Spawn it now so changes are visible spawner.SpawnGrass(spawner.grassPrefabs[selectedGrassID]); } if (GUILayout.Button(new GUIContent("", EditorGUIUtility.IconContent("d_TreeEditor.Trash").image, "Remove"), EditorStyles.miniButtonRight)) { spawner.grassPrefabs.RemoveAt(selectedGrassID); selectedGrassID = spawner.grassPrefabs.Count - 1; spawner.RefreshGrassPrototypes(); } } } if (grass != null) { grass.enabled = EditorGUILayout.Toggle("Enabled", grass.enabled); grass.name = EditorGUILayout.TextField("Name", grass.name); EditorGUILayout.Space(); EditorGUILayout.LabelField("Appearance", EditorStyles.boldLabel); grass.type = (SpawnerBase.GrassType)EditorGUILayout.Popup("Render type", (int)grass.type, new[] { "Mesh", "Texture" }, GUILayout.Width(EditorGUIUtility.labelWidth + 80f)); if (grass.type == SpawnerBase.GrassType.Mesh) { grass.prefab = EditorGUILayout.ObjectField("Prefab", grass.prefab, typeof(GameObject), true) as GameObject; //Update from 1.0.4 to 1.0.5 if (grass.name == "VegetationItem" && grass.prefab) { grass.name = grass.prefab.name; } } if (grass.type == SpawnerBase.GrassType.Texture) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField("Texture", GUILayout.MaxWidth(EditorGUIUtility.labelWidth)); grass.billboard = (Texture2D)EditorGUILayout.ObjectField(grass.billboard, typeof(Texture2D), false); //Update from 1.0.4 to 1.0.5 if (grass.name == "VegetationItem" && grass.billboard) { grass.name = grass.billboard.name; } } grass.renderAsBillboard = EditorGUILayout.Toggle(new GUIContent("Billboard", "When enabled, orients the grass towards the camera on the Y axis"), grass.renderAsBillboard); } grass.mainColor = EditorGUILayout.ColorField("Primary", grass.mainColor, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 60f)); EditorGUI.indentLevel++; grass.linkColors = EditorGUILayout.Toggle(new GUIContent("Link colors", "Use the primary color as the secondary color, also"), grass.linkColors); EditorGUI.indentLevel--; if (!grass.linkColors) { grass.secondaryColor = EditorGUILayout.ColorField("Secondary", grass.secondaryColor, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 60f)); } grass.noiseSize = EditorGUILayout.FloatField(new GUIContent("Noise size", "Grass size and color variation is controlled by an internal noise value. This controls the tiling size of the noise"), grass.noiseSize); DrawRangeSlider(new GUIContent("Width", "Min/max width of the mesh"), ref grass.minMaxWidth, 0f, 3f); DrawRangeSlider(new GUIContent("Length", "Min/max length of the mesh"), ref grass.minMaxHeight, 0f, 3f); if (grassChange.changed) { EditorUtility.SetDirty(target); spawner.UpdateProperties(grass); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Spawning rules", EditorStyles.boldLabel); DrawSeedField(ref grass.seed); grass.probability = EditorGUILayout.Slider("Spawn chance %", grass.probability, 0f, 100f); grass.collisionCheck = EditorGUILayout.Toggle(new GUIContent("Collision check", "Take into account the collision cache to avoid spawning inside colliders (see Settings tab)"), grass.collisionCheck); grass.rejectUnderwater = EditorGUILayout.Toggle(new GUIContent("Remove underwater", "The water height level can be set in the settings tab"), grass.rejectUnderwater); EditorGUILayout.Space(); DrawRangeSlider(new GUIContent("Height range", "Min/max height this item can spawn at"), ref grass.heightRange, 0f, 1000f); DrawRangeSlider(new GUIContent("Slope range", "Min/max slope (0-90 degrees) this item can spawn at"), ref grass.slopeRange, 0f, 90f); DrawRangeSlider(new GUIContent("Curvature range", "0=Concave (bowl), 0.5=flat, 1=convex (edge)"), ref grass.curvatureRange, 0f, 1f); //EditorGUILayout.Space(); LayerMaskSettings(grass.layerMasks); if (grassChange.changed) { serializedObject.ApplyModifiedProperties(); } EditorGUILayout.Space(); if (GUILayout.Button(new GUIContent(" Respawn", EditorGUIUtility.IconContent("d_Refresh").image), GUILayout.MaxHeight(30f))) { Stopwatch sw = new Stopwatch(); sw.Restart(); spawner.SpawnGrass(grass); sw.Stop(); VegetationSpawnerEditor.Log.Add("Respawned " + grass.name + " in " + sw.Elapsed.Seconds + " seconds..."); } } else { EditorGUILayout.HelpBox("Nothing selected", MessageType.Info); } } }