/// <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));
        }
Esempio n. 7
0
        /// <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();
            }
        }