public void OnInspectorGUI() { GUILayout.BeginVertical("box"); { EditorGUILayout.LabelField("Prefabs", GUIStyles.BoxTitleStyle); #region template drop targets GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); { // change background color in case there are no prefabs yet if (editorTarget.prefabSettingsList.Count == 0) { EditorGUILayout.HelpBox("Drop prefabs on the prefab template boxes in order to use them.", MessageType.Info); editor.SetErrorBackgroundColor(); } int gridRows = Mathf.CeilToInt((float)templateCollection.templates.Count / Constants.PrefabTemplateGridColumnCount); for (int row = 0; row < gridRows; row++) { GUILayout.BeginHorizontal(); { for (int column = 0; column < Constants.PrefabTemplateGridColumnCount; column++) { int index = column + row * Constants.PrefabTemplateGridColumnCount; PrefabSettingsTemplate template = index < templateCollection.templates.Count ? templateCollection.templates[index] : defaultTemplate; // drop area Rect prefabDropArea = GUILayoutUtility.GetRect(0.0f, 34.0f, GUIStyles.DropAreaStyle, GUILayout.ExpandWidth(true)); bool hasDropArea = index < templateCollection.templates.Count; if (hasDropArea) { // drop area box with background color and info text GUI.color = GUIStyles.DropAreaBackgroundColor; GUI.Box(prefabDropArea, template.templateName, GUIStyles.DropAreaStyle); GUI.color = GUIStyles.DefaultBackgroundColor; Event evt = Event.current; switch (evt.type) { case EventType.DragUpdated: case EventType.DragPerform: if (prefabDropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; if (evt.type == EventType.DragPerform) { DragAndDrop.AcceptDrag(); // list of new prefabs that should be created via drag/drop // we can't do it in the drag/drop code itself, we'd get exceptions like // ArgumentException: Getting control 12's position in a group with only 12 controls when doing dragPerform. Aborting // followed by // Unexpected top level layout group! Missing GUILayout.EndScrollView/EndVertical/EndHorizontal? UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) // they must be added when everything is done (currently at the end of this method) editor.newDraggedPrefabs = new List <PrefabSettings>(); foreach (Object droppedObject in DragAndDrop.objectReferences) { // allow only prefabs if (PrefabUtility.GetPrefabAssetType(droppedObject) == PrefabAssetType.NotAPrefab) { Debug.Log("Not a prefab: " + droppedObject); continue; } // add the prefab to the list using the template AddPrefab(droppedObject as GameObject, template); } } } break; } } } } GUILayout.EndHorizontal(); } editor.SetDefaultBackgroundColor(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); #endregion template drop targets if (editorTarget.prefabSettingsList.Count > 0) { EditorGUILayout.Space(); } for (int i = 0; i < editorTarget.prefabSettingsList.Count; i++) { // horizontal separator editor.AddGUISeparator(i == 0 ? 0f : 10f, 10f); PrefabSettings prefabSettings = this.editorTarget.prefabSettingsList[i]; GUILayout.BeginHorizontal(); { // preview // try to get the asset preview Texture2D previewTexture = AssetPreview.GetAssetPreview(prefabSettings.prefab); // if no asset preview available, try to get the mini thumbnail if (!previewTexture) { previewTexture = AssetPreview.GetMiniThumbnail(prefabSettings.prefab); } // if a preview is available, paint it if (previewTexture) { //GUILayout.Label(previewTexture, EditorStyles.objectFieldThumb, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size GUILayout.Label(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size //GUILayout.Box(previewTexture); // with border //GUILayout.Label(previewTexture); // no border //GUILayout.Box(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // with border and size //EditorGUI.DrawPreviewTexture(new Rect(25, 60, 100, 100), previewTexture); // draws it in absolute coordinates } // right align the buttons GUILayout.FlexibleSpace(); if (GUILayout.Button("Add", EditorStyles.miniButton)) { this.editorTarget.prefabSettingsList.Insert(i + 1, new PrefabSettings()); } if (GUILayout.Button("Duplicate", EditorStyles.miniButton)) { PrefabSettings newPrefabSettings = prefabSettings.Clone(); this.editorTarget.prefabSettingsList.Insert(i + 1, newPrefabSettings); } if (GUILayout.Button("Reset", EditorStyles.miniButton)) { // remove existing this.editorTarget.prefabSettingsList.RemoveAt(i); // add new this.editorTarget.prefabSettingsList.Insert(i, new PrefabSettings()); } if (GUILayout.Button("Remove", EditorStyles.miniButton)) { this.editorTarget.prefabSettingsList.Remove(prefabSettings); } } GUILayout.EndHorizontal(); GUILayout.Space(4); prefabSettings.prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefabSettings.prefab, typeof(GameObject), true); prefabSettings.active = EditorGUILayout.Toggle("Active", prefabSettings.active); prefabSettings.probability = EditorGUILayout.Slider("Probability", prefabSettings.probability, 0, 1); // scale if (editorTarget.brushSettings.distribution == BrushSettings.Distribution.Fluent) { // use the brush scale, hide the change scale option } else { prefabSettings.changeScale = EditorGUILayout.Toggle("Change Scale", prefabSettings.changeScale); if (prefabSettings.changeScale) { prefabSettings.scaleMin = EditorGUILayout.FloatField("Scale Min", prefabSettings.scaleMin); prefabSettings.scaleMax = EditorGUILayout.FloatField("Scale Max", prefabSettings.scaleMax); } } // position prefabSettings.positionOffset = EditorGUILayout.Vector3Field("Position Offset", prefabSettings.positionOffset); // rotation prefabSettings.rotationOffset = EditorGUILayout.Vector3Field("Rotation Offset", prefabSettings.rotationOffset); GUILayout.BeginHorizontal(); { prefabSettings.randomRotation = EditorGUILayout.Toggle("Random Rotation", prefabSettings.randomRotation); // right align the buttons GUILayout.FlexibleSpace(); if (GUILayout.Button("X", EditorStyles.miniButton)) { QuickRotationSetting(prefabSettings, 1f, 0f, 0f); } if (GUILayout.Button("Y", EditorStyles.miniButton)) { QuickRotationSetting(prefabSettings, 0f, 1f, 0f); } if (GUILayout.Button("Z", EditorStyles.miniButton)) { QuickRotationSetting(prefabSettings, 0f, 0f, 1f); } if (GUILayout.Button("XYZ", EditorStyles.miniButton)) { QuickRotationSetting(prefabSettings, 1f, 1f, 1f); } if (GUILayout.Button(prefabSettings.rotationRange.GetDisplayName(), EditorStyles.miniButton)) { prefabSettings.rotationRange = prefabSettings.rotationRange.GetNext(); } } GUILayout.EndHorizontal(); // rotation limits if (prefabSettings.randomRotation) { float min = prefabSettings.rotationRange.GetMinimum(); float max = prefabSettings.rotationRange.GetMaximum(); EditorGuiUtilities.MinMaxEditor(" Rotation Limit X", ref prefabSettings.rotationMinX, ref prefabSettings.rotationMaxX, min, max); EditorGuiUtilities.MinMaxEditor(" Rotation Limit Y", ref prefabSettings.rotationMinY, ref prefabSettings.rotationMaxY, min, max); EditorGuiUtilities.MinMaxEditor(" Rotation Limit Z", ref prefabSettings.rotationMinZ, ref prefabSettings.rotationMaxZ, min, max); } // VS Pro Id #if VEGETATION_STUDIO_PRO EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField("Asset GUID", prefabSettings.assetGUID); EditorGUILayout.TextField("VSPro Id", prefabSettings.vspro_VegetationItemID); EditorGUI.EndDisabledGroup(); #endif } } GUILayout.EndVertical(); }
public void OnInspectorGUI() { GUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Spline settings", GUIStyles.BoxTitleStyle); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(spawnMechanism, new GUIContent("Spawn Mechanism")); if (spawnMechanism.enumValueIndex == (int)SpawnMechanism.Manual) { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel("Manual Spawn"); if (GUILayout.Button("Spawn Prefabs along Spline")) { SpawnPrefabsAlongSpline(); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.PropertyField(curveResolution, new GUIContent("Curve Resolution")); EditorGUILayout.PropertyField(loop, new GUIContent("Loop")); EditorGUILayout.PropertyField(separation, new GUIContent("Separation")); if (editorTarget.splineSettings.separation == SplineSettings.Separation.Fixed) { EditorGUILayout.PropertyField(separationDistance, new GUIContent(" Distance")); } else if (editorTarget.splineSettings.separation == SplineSettings.Separation.Range) { EditorGuiUtilities.MinMaxEditor(" Distance Min", ref separationDistanceMin, " Distance Max", ref separationDistanceMax); } else if (editorTarget.splineSettings.separation == SplineSettings.Separation.PrefabRadiusBounds) { EditorGuiUtilities.MinMaxEditor(" Distance Min", ref separationDistanceMin, " Distance Max", ref separationDistanceMax); } else if (editorTarget.splineSettings.separation == SplineSettings.Separation.PrefabForwardSize) { EditorGuiUtilities.MinMaxEditor(" Distance Min", ref separationDistanceMin, " Distance Max", ref separationDistanceMax); } EditorGUILayout.PropertyField(lanes, new GUIContent("Lanes")); if (lanes.intValue > 1) { EditorGUILayout.PropertyField(skipCenterLane, new GUIContent("Skip Center Lane")); } EditorGUILayout.PropertyField(laneDistance, new GUIContent("Lane Distance")); EditorGUILayout.PropertyField(instanceRotation, new GUIContent("Rotation")); // allow control point rotation only in spline rotation mode SplineSettings.Rotation selectedInstanceRotation = (SplineSettings.Rotation)System.Enum.GetValues(typeof(SplineSettings.Rotation)).GetValue(instanceRotation.enumValueIndex); if (selectedInstanceRotation == SplineSettings.Rotation.Spline) { EditorGUILayout.PropertyField(controlPointRotation, new GUIContent("Control Point Rotation")); } EditorGUILayout.PropertyField(attachMode, new GUIContent("Attach Mode")); EditorGUILayout.PropertyField(reusePrefabs, new GUIContent("Reuse Prefabs", "If active, then already created prefabs will be reused. Otherwise new prefabs are created whenever something changes ont he spline.")); EditorGUILayout.PropertyField(snap, new GUIContent("Snap", "Snap to the closest vertical object / terrain. Best used for initial alignment.")); EditorGUILayout.PropertyField(debug, new GUIContent("Debug")); /* show a list of points * TODO: * optimize instantiation * reflection for position * maybe move to dedicated debug tab * * ReorderableList list = new ReorderableList(editor.serializedObject, controlPoints, false, true, false, false); * list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => * { * var element = list.serializedProperty.GetArrayElementAtIndex(index); * rect.y += 2; * EditorGUI.PropertyField( * new Rect(rect.x, rect.y, 200, EditorGUIUtility.singleLineHeight), * element.FindPropertyRelative("position"), GUIContent.none); * }; * list.DoLayoutList(); */ bool changed = EditorGUI.EndChangeCheck(); if (changed) { // at least 1 lane must be active if (lanes.intValue <= 1) { skipCenterLane.boolValue = false; } // avoid endless loop by limiting min distance between objects to a value above 0 if (separationDistance.floatValue <= 0) { separationDistance.floatValue = minDistanceBetweenObjects; } // allow control point rotation only in spline rotation mode if (selectedInstanceRotation != SplineSettings.Rotation.Spline) { controlPointRotation.boolValue = false; } } dirty.boolValue |= changed; GUILayout.BeginHorizontal(); if (GUILayout.Button("New")) { ClearSpline(false); } if (GUILayout.Button("Clear")) { ClearSpline(true); } if (GUILayout.Button("Update")) { UpdatePrefabs(); } if (GUILayout.Button("Snap All")) { SnapAll(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); PerformEditorAction(); }