void CreateNestedSequence(object obj) { SegmentSequence sequence = (SegmentSequence)obj; SegmentDefinition definition = new SegmentDefinition("Nested Sequence"); AddDefinition(sequence, definition); }
internal static int GetRandomSegmentByChance(SegmentSequence sequence, int exclude = -1) { float totalChance = 0f; for (int i = 0; i < sequence.segments.Length; i++) { if (i == exclude) { continue; } totalChance += sequence.segments[i].randomPickChance; } float randomValue = Random.Range(0f, totalChance); float passed = 0f; for (int i = 0; i < sequence.segments.Length; i++) { if (i == exclude) { continue; } if (sequence.segments[i].randomPickChance <= 0f) { continue; } if (randomValue >= passed && randomValue <= passed + sequence.segments[i].randomPickChance) { return(i); } passed += sequence.segments[i].randomPickChance; } return(0); }
void AddDefinition(SegmentSequence sequence, SegmentDefinition segment) { SegmentDefinition[] newSegments = new SegmentDefinition[sequence.segments.Length + 1]; sequence.segments.CopyTo(newSegments, 0); newSegments[newSegments.Length - 1] = segment; sequence.segments = newSegments; }
void RemoveSequence(object obj) { SegmentSequence sequence = (SegmentSequence)obj; int index = GetSequenceIndex(sequence); Undo.RecordObject(undoObject, "Remove sequence"); SegmentSequence[] newSequences = new SegmentSequence[sequences.Length - 1]; for (int i = 0; i < sequences.Length; i++) { if (i < index) { newSequences[i] = sequences[i]; } else if (i == index) { continue; } else { newSequences[i - 1] = sequences[i]; } } sequences = newSequences; if (onApplySequences != null) { onApplySequences(sequences); } }
private void OnSequenceEntered(SegmentSequence sequence) { if (sequence.customPathGenerator != null) { LevelPathGenerator lastGenerator = currentPathGenerator; if (usePathGeneratorInstance) { overridePathGenerator = Instantiate(sequence.customPathGenerator); } else { overridePathGenerator = sequence.customPathGenerator; } overridePathGenerator.Continue(lastGenerator); } else if (overridePathGenerator != null) { pathGenerator.Continue(overridePathGenerator); if (usePathGeneratorInstance) { Destroy(overridePathGenerator); } overridePathGenerator = null; } }
public void Init(SegmentSequence sequence, SegmentSequenceEditor editor) { this.sequence = sequence; this.editor = editor; minSize = maxSize = new Vector2(250f, 250f); titleContent = new GUIContent("Sequence Settings"); Repaint(); }
public virtual SegmentDefinition Get(SegmentSequence sequence, int index) { if (sequence.segments.Length == 0) { return(null); } return(sequence.segments[0]); }
void MoveSequenceDown(object obj) { Undo.RecordObject(undoObject, "Move Sequence Down"); SegmentSequence sequence = (SegmentSequence)obj; int index = GetSequenceIndex(sequence); sequences[index] = sequences[index + 1]; sequences[index + 1] = sequence; }
public void Initialize() { lastSequence = null; sequenceStack.Clear(); for (int i = 0; i < sequences.Length; i++) { sequences[i].Initialize(); } }
int GetSequenceIndex(SegmentSequence sequence) { for (int i = 0; i < sequences.Length; i++) { if (sequences[i] == sequence) { return(i); } } return(-1); }
public static SegmentDefinition GetRandomSegment(SegmentSequence sequence, int index) { if (lastSequence != sequence) { lastRandom = -1; lastSequence = sequence; } int segmentIndex = GetRandomSegmentByChance(sequence, sequence.preventRepeat ? lastRandom : -1); lastRandom = segmentIndex; return(sequence.segments[segmentIndex]); }
void DuplicateSequence(object obj) { Undo.RecordObject(undoObject, "Duplicate Sequence"); SegmentSequence sequence = (SegmentSequence)obj; int index = GetSequenceIndex(sequence); SegmentSequence newSequence = sequence.Duplicate(); Dreamteck.ArrayUtility.Insert(ref sequences, index, newSequence); if (onApplySequences != null) { onApplySequences(sequences); } }
void UnpackSequence(SegmentSequence sequence, int parent, int segmentIndex, ref List <SegmentSequence> flat, ref List <SequenceSerialization> parentIndices) { flat.Add(sequence); parentIndices.Add(new SequenceSerialization(parent, segmentIndex)); int parentIndex = flat.Count - 1; for (int i = 0; i < sequence.segments.Length; i++) { if (sequence.segments[i].nestedSequence != null) { UnpackSequence(sequence.segments[i].nestedSequence, parentIndex, i, ref flat, ref parentIndices); } } }
public static SegmentDefinition GetOrderedSegment(SegmentSequence sequence, int index) { int segmentIndex = index; if (segmentIndex < 0) { segmentIndex = 0; } if (segmentIndex >= sequence.segments.Length) { segmentIndex = sequence.segments.Length - 1; } return(sequence.segments[segmentIndex]); }
public SegmentSequence Duplicate() { SegmentSequence sequence = new SegmentSequence(); sequence.enabled = enabled; sequence.name = name; sequence.preventRepeat = preventRepeat; sequence.isCustom = isCustom; sequence.customSequence = customSequence; sequence.spawnCount = spawnCount; sequence.type = type; sequence.customShuffle = customShuffle; sequence.segments = new SegmentDefinition[segments.Length]; for (int i = 0; i < segments.Length; i++) { sequence.segments[i] = segments[i].Duplicate(); } return(sequence); }
public LevelSegment InstantiateSegment() { while (sequenceStack.Count > 0 && sequenceStack.Peek().IsDone()) { sequenceStack.Pop(); } SegmentSequence sequence = null; if (sequenceStack.Count == 0) { sequence = GetSequence(); if (sequence == null) { throw new System.NullReferenceException(title + " has null sequence"); } sequenceStack.Push(sequence); } sequence = sequenceStack.Peek(); SegmentDefinition definition = sequence.Next(); while (definition.nested) { sequence = definition.nestedSequence; sequenceStack.Push(sequence); definition = sequence.Next(); } if (sequence != lastSequence) { if (onSequenceEntered != null) { onSequenceEntered(sequence); } lastSequence = sequence; } if (definition == null) { throw new System.NullReferenceException(title + " has null definition in sequence " + sequence.name); } return(definition.Instantiate()); }
public SegmentDefinition(string nestedName) { nestedSequence = new SegmentSequence(); nestedSequence.name = nestedName; nested = true; }
void SequenceUI(SegmentSequence sequence) { //Toolbar Vector2 thumbSize = Vector2.one * thumbnailSize; if (sequence.type == SegmentSequence.Type.Random) { thumbSize.y += 16f; } float width = viewRect.width; float totalThumbWidth = thumbSize.x + thumbnailPadding; int elementsPerRow = Mathf.FloorToInt(width / totalThumbWidth); int rows = Mathf.CeilToInt((float)sequence.segments.Length / elementsPerRow); if (rows == 0) { rows = 1; } int row = 0, col = 0; float height = rows * (thumbSize.y + thumbnailPadding) + thumbnailPadding; #region Header GUI.backgroundColor = ForeverPrefs.highlightColor * DreamteckEditorGUI.lightColor; EditorGUILayout.BeginHorizontal(defaultBoxStyle, GUILayout.Width(width)); GUI.backgroundColor = Color.white; if (sequenceAddress.Count == 0) { sequence.enabled = EditorGUILayout.Toggle(sequence.enabled, headerToggle, GUILayout.Width(20)); } if (renameSequence && editSequence == sequence) { if (onWillChange != null) { onWillChange(); } sequence.name = GUILayout.TextField(sequence.name); if (input.enterDown) { renameSequence = false; } if (input.mouseLeftDown && input.mouseRightDown) { if (!GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) { renameSequence = false; } } } else { if (sequence.name == "") { sequence.name = "Sequence"; } string nameText = sequence.name; if (!sequence.isCustom) { nameText += " - " + sequence.type.ToString(); } GUILayout.Label(nameText); } if (GUILayout.Button("Settings", GUILayout.Width(60))) { if (sequenceSettingsWindow == null) { sequenceSettingsWindow = EditorWindow.GetWindow <SegmentSequenceSettingsWindow>(true); sequenceSettingsWindow.onWillChange += OnSequenceSettingsWillChange; } sequenceSettingsWindow.Init(sequence, this); } EditorGUILayout.EndVertical(); Rect headerRect = GUILayoutUtility.GetLastRect(); if (headerRect.Contains(Event.current.mousePosition)) { if (input.mouseRightDown) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Move Up"), false, MoveSequenceUp, sequence); menu.AddItem(new GUIContent("Move Down"), false, MoveSequenceDown, sequence); menu.AddItem(new GUIContent("Rename"), false, SetRename, sequence); menu.AddItem(new GUIContent("Duplicate"), false, DuplicateSequence, sequence); menu.AddSeparator(""); menu.AddItem(new GUIContent("Delete"), false, RemoveSequence, sequence); menu.ShowAsContext(); input.Use(); } } #endregion //Sequence canvas GUI.backgroundColor = DreamteckEditorGUI.lightColor; if (sequence.isCustom) { GUILayout.Box("", defaultBoxStyle, GUILayout.Width(width), GUILayout.Height(thumbSize.y + thumbnailPadding * 2f)); } else { GUILayout.Box("", defaultBoxStyle, GUILayout.Width(width), GUILayout.Height(height)); } GUI.backgroundColor = Color.white; Rect groupRect = GUILayoutUtility.GetLastRect(); GUI.BeginGroup(groupRect); if (sequence.isCustom) { GUI.Label(new Rect(0f, groupRect.height / 2f - 30f, groupRect.width, 50), "Custom Sequence", customSequenceLabel); CustomSequence customSequence = sequence.customSequence; customSequence = (CustomSequence)EditorGUI.ObjectField(new Rect(groupRect.width / 2f - 100, groupRect.height / 2f + 15, 200, 16), customSequence, typeof(CustomSequence), false); if (customSequence != sequence.customSequence) { if (onWillChange != null) { onWillChange(); } sequence.customSequence = customSequence; } GUI.EndGroup(); EditorGUILayout.Space(); return; } #region Drag Reorder int dragTarget = -1; float closestDist = float.MaxValue; Vector2 closestCenter = Vector2.zero; if (dragIndex >= 0 && editSequence == sequence) { for (int i = 0; i < sequence.segments.Length; i++) { Vector2 thumbCenter = new Vector2(thumbnailPadding + col * totalThumbWidth + thumbnailSize / 2, (thumbnailSize + thumbnailPadding) * row + thumbnailPadding + thumbnailSize / 2); float dist = Vector2.Distance(thumbCenter, Event.current.mousePosition); if (dist < closestDist) { closestDist = dist; dragTarget = i; closestCenter = thumbCenter; } col++; if (col >= elementsPerRow) { col = 0; row++; } } if (dragTarget >= 0 && dragTarget != dragIndex) { bool before = Event.current.mousePosition.x < closestCenter.x; int side = before ? -1 : 1; EditorGUI.DrawRect(new Rect(closestCenter.x + side * thumbnailSize / 2 - thumbnailPadding, closestCenter.y - thumbnailSize / 2, thumbnailPadding * 2, thumbnailSize), ForeverPrefs.highlightColor); if (input.mouseLeftUp) { if (dragTarget < 0) { dragTarget = 0; } ReorderSegments(ref sequence.segments, dragIndex, dragTarget); dragIndex = -1; } } } #endregion #region Draw Definitions col = row = 0; for (int i = 0; i < sequence.segments.Length; i++) { Rect thumbRect = new Rect(thumbnailPadding + col * totalThumbWidth, (thumbSize.y + thumbnailPadding) * row + thumbnailPadding, thumbSize.x, thumbSize.y); if (segmentArray != sequence.segments || dragIndex != i) { if (!sequence.segments[i].nested && sequence.segments[i].prefab == null) //dont remove in future, just show as NULL in the window { RemoveSegment(ref sequence.segments, i); i--; continue; } if (DefinitionUI(new Vector2(thumbRect.x, thumbRect.y), sequence.segments[i], i)) { if (input.mouseLeftDown && !renameSequence) { dragIndex = i; dragOffset = new Vector2(thumbRect.x + thumbnailSize / 2f, thumbRect.y + thumbnailSize / 2f) - Event.current.mousePosition; editSequence = sequence; segmentArray = sequence.segments; input.Use(); } else if (input.mouseRightDown) { editSequence = sequence; if (sequence.segments[i].nested) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Edit"), false, EnterNestedSequence, sequence.segments[i]); menu.AddItem(new GUIContent("Remove"), false, RemoveSegment, i); menu.ShowAsContext(); input.Use(); } else { int index = i; GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Change"), false, SetChangeSegment, sequence.segments[i]); menu.AddItem(new GUIContent("Select in Project"), false, SelectDefinitionPrefab, sequence.segments[i]); menu.AddItem(new GUIContent("Duplicate"), false, delegate { Undo.RecordObject(undoObject, "Duplicate Segment"); ArrayUtility.Insert(ref sequence.segments, index, sequence.segments[index].Duplicate()); changed = true; }); menu.AddItem(new GUIContent("Remove"), false, RemoveSegment, i); menu.ShowAsContext(); input.Use(); } input.Use(); } } if (sequence.type == SegmentSequence.Type.Random) { float chance = sequence.segments[i].randomPickChance; chance = GUI.HorizontalSlider(new Rect(thumbRect.x, thumbRect.y + thumbSize.y - 16f, thumbSize.x, 16f), chance, 0f, 1f); GUI.Label(new Rect(thumbRect.x, thumbRect.y + thumbSize.y - 32f, thumbSize.x, 16f), Mathf.RoundToInt(chance * 100) + "% Chance", thumbnailLabel); if (chance != sequence.segments[i].randomPickChance) { onWillChange(); sequence.segments[i].randomPickChance = chance; } } } col++; if (col >= elementsPerRow) { col = 0; row++; } } #endregion GUI.EndGroup(); Rect canvasRect = GUILayoutUtility.GetLastRect(); if (canvasRect.Contains(Event.current.mousePosition) && input.mouseRightDown) { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("New Nested Sequence"), false, CreateNestedSequence, sequence); menu.ShowAsContext(); } SegmentDefinition newSegment = null; GameObject newObj = SegmentField(GUILayoutUtility.GetLastRect()); if (newObj != null) { newSegment = new SegmentDefinition(newObj); } if (newSegment != null && newSegment.prefab != null) { if (onWillChange != null) { onWillChange(); } AddDefinition(sequence, newSegment); changed = true; } if (changed) { changed = false; if (onChanged != null) { onChanged(); } } EditorGUILayout.Space(); }
void SetRename(object obj) { editSequence = (SegmentSequence)obj; renameSequence = true; }
public void DrawEditor() { input.Update(); if (!guiInitialized) { defaultBoxStyle = new GUIStyle(GUI.skin.box); defaultBoxStyle.normal.background = DreamteckEditorGUI.blankImage; defaultBoxStyle.margin = new RectOffset(0, 0, 0, 0); defaultButtonStyle = new GUIStyle(GUI.skin.button); defaultButtonStyle.normal.background = buttonNormal; defaultButtonStyle.normal.textColor = DreamteckEditorGUI.iconColor; defaultButtonStyle.hover.background = buttonHover; defaultButtonStyle.hover.textColor = DreamteckEditorGUI.highlightContentColor; defaultButtonStyle.margin = new RectOffset(2, 2, 2, 2); thumbnailLabel = new GUIStyle(GUI.skin.label); thumbnailLabel.normal.textColor = DreamteckEditorGUI.lightColor; thumbnailLabel.fontSize = 10; thumbnailLabel.alignment = TextAnchor.MiddleCenter; headerToggle = new GUIStyle(GUI.skin.toggle); headerToggle.normal.textColor = Color.white; guiInitialized = true; } if (sequenceAddress.Count > 0) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("<", GUILayout.Width(35))) { sequenceAddress.RemoveAt(sequenceAddress.Count - 1); } GUIContent content = new GUIContent(undoObject.name); float min = 0f, max = 0f; GUI.skin.label.CalcMinMaxWidth(content, out min, out max); GUILayout.Label(undoObject.name, GUILayout.Width(min)); for (int i = 0; i < sequenceAddress.Count; i++) { content = new GUIContent("/ " + sequenceAddress[i].name); GUI.skin.label.CalcMinMaxWidth(content, out min, out max); GUILayout.Label(content, GUILayout.Width(min)); } EditorGUILayout.EndHorizontal(); } scroll = GUILayout.BeginScrollView(scroll, GUILayout.Width(viewRect.width), GUILayout.Height(viewRect.height)); if (sequenceAddress.Count == 0) { for (int i = 0; i < sequences.Length; i++) { SequenceUI(sequences[i]); } if (GUILayout.Button("Add Sequence", GUILayout.Width(100), GUILayout.Height(50))) { SegmentSequence[] newSequence = new SegmentSequence[sequences.Length + 1]; sequences.CopyTo(newSequence, 0); newSequence[newSequence.Length - 1] = new SegmentSequence(); sequences = newSequence; if (onApplySequences != null) { onApplySequences(sequences); } } } else { SequenceUI(sequenceAddress[sequenceAddress.Count - 1]); } GUILayout.EndScrollView(); if (changeDefinition != null && !changeDefinition.nested) { EditorGUI.DrawRect(segmentPanelRect, Color.white); GUILayout.BeginArea(segmentPanelRect); GameObject last = changeDefinition.prefab; last = (GameObject)EditorGUILayout.ObjectField(last, typeof(GameObject), false); if (last != changeDefinition.prefab) { if (onWillChange != null) { onWillChange(); } changeDefinition.prefab = last; changed = true; } GUILayout.EndArea(); if (input.mouseLeftDown && !segmentPanelRect.Contains(Event.current.mousePosition)) { changeDefinition = null; } else if (input.mouseLeftDown) { input.Use(); } } if (dragIndex >= 0) { changed = true; if (input.mouseLeftUp) { dragIndex = -1; segmentArray = null; } else { GUI.color = new Color(1f, 1f, 1f, 0.75f); float dragSize = thumbnailSize * 0.75f; DrawDefinition(new Rect(Event.current.mousePosition.x - dragSize * 0.5f + dragOffset.x, Event.current.mousePosition.y - dragSize * 0.5f + dragOffset.y, dragSize, dragSize), editSequence.segments[dragIndex]); GUI.color = Color.white; if (dragOffset.magnitude > 0.05f) { dragOffset = Vector2.Lerp(dragOffset, Vector2.zero, 0.1f); changed = true; } } } }
public SegmentDefinition() { nestedSequence = null; nested = false; }