/// <summary> /// Copy or paste settings to selected PlacementSettings /// </summary> /// <param name="loadout">The loadout that got clicked</param> /// <param name="copy">do we copy or paste ?</param> /// <param name="selected">the list of currently selected PlacementSettings for edition in the current PrefabPalette</param> private void CopyPasteSettings(LoadoutInfo loadout, bool copy, HashSet <int> selected) { if (copy) { copyPastePrefabSettings = loadout; } else { if (copyPastePrefabSettings == null) { return; } PrefabPaletteEditor sourceEditor = prefabPaletteEditors[copyPastePrefabSettings.palette]; PrefabPaletteEditor destEditor = prefabPaletteEditors[loadout.palette]; SerializedProperty srcPAS = sourceEditor.prefabs.GetArrayElementAtIndex(loadout.palette.FindIndex(loadout.prefab)); SerializedProperty srcPS = srcPAS.FindPropertyRelative("settings"); destEditor.serializedObject.Update(); foreach (int i in selected) { SerializedProperty destPAS = destEditor.prefabs.GetArrayElementAtIndex(i); SerializedProperty destPS = destPAS.FindPropertyRelative("settings"); PlacementSettings.CopySerializedProperty(srcPS, destPS); } destEditor.serializedObject.ApplyModifiedProperties(); } }
/// <summary> /// Draw a single loadout /// </summary> /// <param name="loadout">The loadout being drawn</param> /// <param name="thumbSize">Size of the preview</param> /// <param name="infos">additionnal infos about the loadout being drawn (parent prefab palette and index in it)</param> void DrawSingleLoadout(SerializedProperty loadout, int thumbSize, LoadoutInfo infos, float x, float y) { var editor = prefabPaletteEditors[infos.palette]; editor.serializedObject.Update(); Rect r = new Rect(x, y, thumbSize, thumbSize); // Texture Preview Texture2D preview = PreviewsDatabase.GetAssetPreview(loadout.FindPropertyRelative("gameObject").objectReferenceValue); EditorGUI.DrawPreviewTexture(r, preview); float pad = thumbSize * 0.05f; GUILayoutUtility.GetRect(thumbSize, thumbSize); Rect r3 = new Rect(r); r3.width = Styles.deleteButtonStyle.fixedWidth; r3.height = Styles.deleteButtonStyle.fixedHeight; r3.x += thumbSize - pad - r3.width; r3.y += pad; if (GUI.Button(r3, "", Styles.deleteButtonStyle)) { toUnload = infos; GUI.changed = true; } r.y += thumbSize - pad - 10; r.x += pad; r.width = thumbSize - (2 * pad); var prefabOccurence = loadout.FindPropertyRelative("settings").FindPropertyRelative("m_Strength"); prefabOccurence.floatValue = GUI.HorizontalSlider(r, prefabOccurence.floatValue, BrushModePrefab.k_PrefabOccurrenceMin, BrushModePrefab.k_PrefabOccurrenceMax); editor.serializedObject.ApplyModifiedProperties(); }
internal void RemovePrefabFromLoadout(LoadoutInfo loadoutInfo) { if (m_CurrentLoadouts.Contains(loadoutInfo)) { m_CurrentLoadouts.Remove(loadoutInfo); } SaveUserCurrentLoadouts(); }
internal void AddPrefabInLoadout(LoadoutInfo loadoutInfo) { if (!m_CurrentLoadouts.Contains(loadoutInfo)) { m_CurrentLoadouts.Add(loadoutInfo); } SaveUserCurrentLoadouts(); }
/// <summary> /// Show the Menu to copu/paste prefab placement settings /// </summary> /// <param name="info">The PrefabAndSettings which was right clicked</param> /// <param name="selected">The list of selected PlacementSettings in the current PrefabPalette</param> internal void OpenCopyPasteMenu(LoadoutInfo info, HashSet <int> selected) { GenericMenu menu = new GenericMenu(); if (selected.Count > 1) { menu.AddDisabledItem(Styles.copyPrefabSettingsLabel); } else { menu.AddItem(Styles.copyPrefabSettingsLabel, false, () => { CopyPasteSettings(info, true, selected); }); } menu.AddItem(Styles.pastePrefabSettingsLabel, false, () => { CopyPasteSettings(info, false, selected); }); menu.ShowAsContext(); }
/// <summary> /// Returns a random PrefabAndSettings from the loadout list /// </summary> /// <returns></returns> internal PrefabAndSettings GetRandomLoadout() { if (m_CurrentLoadouts.Count < 1) { return(null); } // Weighted random implementation List <float> weights = new List <float>() { 0.0f }; float totalWeights = 0.0f; foreach (LoadoutInfo info in m_CurrentLoadouts) { float strength = info.palette.Get(info.prefab).settings.strength; weights.Add(totalWeights + strength); totalWeights += strength; } float random = UnityEngine.Random.Range(0.0f + Mathf.Epsilon, totalWeights); int resultIndex = -1; for (int i = 0; i < weights.Count - 1; i++) { if (weights[i] < random && random < weights[i + 1]) { resultIndex = i; break; } } if (resultIndex == -1) { return(null); } LoadoutInfo loadout = m_CurrentLoadouts[resultIndex]; return(loadout.palette.Get(loadout.prefab)); }
/// <summary> /// Draws previews for a prefab in the palette. /// </summary> /// <param name="prefab">Prefab being previewed</param> /// <param name="index">index of the prefab in `prefabs`</param> /// <param name="thumbSize">Size of the preview texture</param> private void DrawPrefabPreview(SerializedProperty prefab, int index, int thumbSize, float x, float y) { Rect r = new Rect(x, y, thumbSize, thumbSize); Rect rightClickZone = new Rect(r); // Texture Preview UnityEngine.Object o = prefab.FindPropertyRelative("gameObject").objectReferenceValue; Texture2D preview = PreviewsDatabase.GetAssetPreview(o); if (selected.Contains(index)) { Rect r2 = new Rect(r); r2.x -= 1; r2.y -= 1; r2.width += 2; r2.height += 2; EditorGUI.DrawRect(r2, Color.blue); } EditorGUI.DrawPreviewTexture(r, preview); // Those numbers were obtained by empirical experimentation r.x += thumbSize - 17; r.y += thumbSize - 17; r.width = 17; r.height = 17; LoadoutInfo li = new LoadoutInfo(target as PrefabPalette, index); bool isLoaded = loadoutEditor.ContainsPrefab(li); Event e = Event.current; bool rightClick = (e.type == EventType.MouseDown || e.type == EventType.ContextClick) && rightClickZone.Contains(e.mousePosition) && e.button == 1; bool b1 = GUI.Toggle(r, isLoaded, ""); // Reducing the width by 1 to ensure the button is not larger than the thumbnail. // Otherwise button is slightly too large and horizontal scrollbar may appear. bool b2 = GUILayout.Button("", GUIStyle.none, GUILayout.Width(thumbSize - 1), GUILayout.Height(thumbSize)); // Set the focus to nothing in case the user want to press delete or backspace key // I dont know why but If we don't do that the Textfield with the name of prefab settings never looses focus if (b2 || rightClick) { GUI.FocusControl(null); e.Use(); } if (rightClick) { rightClickTime = redrawCounter; shouldopencontextmenu = true; idx = index; if (!selected.Contains(index)) { selected.Clear(); selected.Add(index); } return; } else if (shouldopencontextmenu && redrawCounter > rightClickTime) { loadoutEditor.OpenCopyPasteMenu(new LoadoutInfo(target as PrefabPalette, idx), selected); shouldopencontextmenu = false; idx = -1; // reset the redraw counter to avoid overflow redrawCounter = 0; } if (b1 && !isLoaded) { loadoutEditor.AddPrefabInLoadout(li); //loadoutEditor.loadouts.Add(li); } else if (!b1 && isLoaded) { loadoutEditor.RemovePrefabFromLoadout(li); //loadoutEditor.loadouts.Remove(li); } else if (b2) { if (Event.current.shift || Event.current.control) { if (!selected.Add(index)) { selected.Remove(index); } } else { if (selected.Count == 1 && selected.Contains(index)) { selected.Remove(index); } else { selected.Clear(); selected.Add(index); } } if (onSelectionChanged != null) { onSelectionChanged(selected); } GUI.changed = true; } }
internal bool ContainsPrefab(LoadoutInfo loadoutInfo) { return(m_CurrentLoadouts.Contains(loadoutInfo)); }
/// <summary> /// Show the list of current loadouts /// </summary> /// <param name="thumbSize">Size of the preview texture</param> internal void DrawLoadoutList(int thumbSize) { SyncLoadoutWithPalettes(); int count = m_CurrentLoadouts.Count; PolyGUILayout.Label(Styles.brushLoadoutLabel); Rect backGroundRect = EditorGUILayout.BeginVertical(PrefabPaletteEditor.paletteStyle); backGroundRect.width = EditorGUIUtility.currentViewWidth; if (count == 0) { var r = EditorGUILayout.BeginVertical(GUILayout.Height(thumbSize + 4)); EditorGUI.DrawRect(r, EditorGUIUtility.isProSkin ? PolyGUI.k_BoxBackgroundDark : PolyGUI.k_BoxBackgroundLight); GUILayout.FlexibleSpace(); GUILayout.Label("Select items from the Palette below", EditorStyles.centeredGreyMiniLabel); GUILayout.FlexibleSpace(); EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical(); return; } const int pad = 4; int size = thumbSize + pad; backGroundRect.x += 8; backGroundRect.y += 4; // The backgroundRect is currently as wide as the current view. // Adjust it to take the size of the vertical scrollbar and padding into account. backGroundRect.width -= (20 + (int)GUI.skin.verticalScrollbar.fixedWidth); // size variable will not take into account the padding to the right of all the thumbnails, // therefore it needs to be substracted from the width. int container_width = ((int)Mathf.Floor(backGroundRect.width) - (pad + 1)); int columns = (int)Mathf.Floor(container_width / size); if (columns == 0) { columns = 1; } int rows = count / columns + (count % columns == 0 ? 0 : 1); if (rows < 1) { rows = 1; } backGroundRect.height = 8 + rows * thumbSize + (rows - 1) * pad; EditorGUI.DrawRect(backGroundRect, EditorGUIUtility.isProSkin ? PolyGUI.k_BoxBackgroundDark : PolyGUI.k_BoxBackgroundLight); int currentIndex = 0; for (int i = 0; i < rows; i++) { var horizontalRect = EditorGUILayout.BeginHorizontal(); for (int j = 0; j < columns; j++) { LoadoutInfo loadoutInfo = m_CurrentLoadouts[currentIndex]; PrefabPaletteEditor prefabEditor = prefabPaletteEditors[loadoutInfo.palette]; SerializedProperty prefabs = prefabEditor.prefabs; SerializedProperty prefab = prefabs.GetArrayElementAtIndex(loadoutInfo.palette.FindIndex(loadoutInfo.prefab)); var previewRectXPos = pad + j * size + horizontalRect.x; DrawSingleLoadout(prefab, thumbSize, loadoutInfo, previewRectXPos, horizontalRect.y); if (j != columns - 1) { GUILayout.Space(pad); } currentIndex++; if (currentIndex >= count) { break; } } EditorGUILayout.EndHorizontal(); GUILayout.Space(4); } EditorGUILayout.EndVertical(); if (toUnload != null) { RemovePrefabFromLoadout(toUnload); toUnload = null; SaveUserCurrentLoadouts(); } }
/// <summary> /// Show the list of current loadouts /// </summary> /// <param name="thumbSize">Size of the preview texture</param> internal void DrawLoadoutList(int thumbSize) { SyncLoadoutWithPalettes(); int count = m_CurrentLoadouts.Count; EditorGUILayout.LabelField(Styles.brushLoadoutLabel); Rect backGroundRect = EditorGUILayout.BeginVertical(PrefabPaletteEditor.paletteStyle); if (count == 0) { var r = EditorGUILayout.BeginVertical(GUILayout.Height(thumbSize)); EditorGUI.DrawRect(r, EditorGUIUtility.isProSkin ? PolyGUI.k_BoxBackgroundDark : PolyGUI.k_BoxBackgroundLight); GUILayout.FlexibleSpace(); if (GUI.skin.name.Contains("polybrush")) { EditorGUILayout.LabelField("No loadout selected yet", "dragprefablabel"); } else { EditorGUILayout.LabelField("No loadout selected yet", EditorStyles.centeredGreyMiniLabel); } GUILayout.FlexibleSpace(); EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical(); return; } const int margin_x = 8; const int pad = 4; int size = thumbSize + pad; float width = EditorGUIUtility.currentViewWidth; int container_width = (int)Mathf.Floor(EditorGUIUtility.currentViewWidth) - (margin_x * 2); int columns = (int)Mathf.Floor(container_width / size); if (columns == 0) { columns = 1; } int rows = count / columns + (count % columns == 0 ? 0 : 1); if (rows < 1) { rows = 1; } backGroundRect.x += 4; backGroundRect.y += 4; backGroundRect.width -= 8; backGroundRect.height = 8 + rows * thumbSize + (rows - 1) * pad; EditorGUI.DrawRect(backGroundRect, EditorGUIUtility.isProSkin ? PolyGUI.k_BoxBackgroundDark : PolyGUI.k_BoxBackgroundLight); int currentIndex = 0; for (int i = 0; i < rows; i++) { EditorGUILayout.BeginHorizontal(); for (int j = 0; j < columns; j++) { LoadoutInfo loadoutInfo = m_CurrentLoadouts[currentIndex]; PrefabPaletteEditor prefabEditor = prefabPaletteEditors[loadoutInfo.palette]; SerializedProperty prefabs = prefabEditor.prefabs; SerializedProperty prefab = prefabs.GetArrayElementAtIndex(loadoutInfo.palette.FindIndex(loadoutInfo.prefab)); DrawSingleLoadout(prefab, thumbSize, loadoutInfo); if (j != columns - 1) { GUILayout.Space(pad); } currentIndex++; if (currentIndex >= count) { break; } } EditorGUILayout.EndHorizontal(); GUILayout.Space(4); } EditorGUILayout.EndVertical(); if (toUnload != null) { RemovePrefabFromLoadout(toUnload); toUnload = null; SaveUserCurrentLoadouts(); } }