public void OnGUI(bool minimized) { AffirmResources(); float[] metering = EditorUtils.GetMetering(); int meterHeight = minimized ? 86 : 128; int meterWidth = (int)((128 / (float)meterOff.height) * meterOff.width); const int MeterCountMaximum = 16; int minimumWidth = meterWidth * MeterCountMaximum; Rect fullRect = GUILayoutUtility.GetRect(minimumWidth, meterHeight, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); float x = fullRect.x + (fullRect.width - (meterWidth * metering.Length)) / 2; foreach (float rms in metering) { Rect meterRect = new Rect(x, fullRect.y, meterWidth, fullRect.height); GUI.DrawTexture(meterRect, meterOff); float db = 20.0f * Mathf.Log10(rms * Mathf.Sqrt(2.0f)); db = Mathf.Clamp(db, -80.0f, 10.0f); float visible = 0; int[] segmentPixels = new int[] { 0, 18, 38, 60, 89, 130, 187, 244, 300 }; float[] segmentDB = new float[] { -80.0f, -60.0f, -50.0f, -40.0f, -30.0f, -20.0f, -10.0f, 0, 10.0f }; int segment = 1; while (segmentDB[segment] < db) { segment++; } visible = segmentPixels[segment - 1] + ((db - segmentDB[segment - 1]) / (segmentDB[segment] - segmentDB[segment - 1])) * (segmentPixels[segment] - segmentPixels[segment - 1]); visible *= fullRect.height / (float)meterOff.height; Rect levelPosRect = new Rect(meterRect.x, fullRect.height - visible + meterRect.y, meterWidth, visible); Rect levelUVRect = new Rect(0, 0, 1.0f, visible / fullRect.height); GUI.DrawTextureWithTexCoords(levelPosRect, meterOn, levelUVRect); x += meterRect.width; } }
//Rect previewPathRect; private void PreviewEvent(Rect previewRect, EditorEventRef selectedEvent) { GUILayout.BeginArea(previewRect); bool isNarrow = previewRect.width < 400; var style = new GUIStyle(EditorStyles.label); EditorStyles.label.fontStyle = FontStyle.Bold; EditorGUIUtility.labelWidth = 75; var copyIcon = EditorGUIUtility.Load("FMOD/CopyIcon.png") as Texture; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Full Path", selectedEvent.Path, style, GUILayout.ExpandWidth(true)); if (GUILayout.Button(copyIcon, GUILayout.ExpandWidth(false))) { EditorGUIUtility.systemCopyBuffer = selectedEvent.Path; } EditorGUILayout.EndHorizontal(); StringBuilder builder = new StringBuilder(); selectedEvent.Banks.ForEach((x) => { builder.Append(Path.GetFileNameWithoutExtension(x.Path)); builder.Append(", "); }); EditorGUILayout.LabelField("Banks", builder.ToString(0, Math.Max(0, builder.Length - 2)), style); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Panning", selectedEvent.Is3D ? "3D" : "2D", style); EditorGUILayout.LabelField("Oneshot", selectedEvent.IsOneShot.ToString(), style); TimeSpan t = System.TimeSpan.FromMilliseconds(selectedEvent.Length); EditorGUILayout.LabelField("Length", selectedEvent.Length > 0 ? string.Format("{0:D2}:{1:D2}:{2:D3}", t.Minutes, t.Seconds, t.Milliseconds) : "N/A", style); if (!isNarrow) { EditorGUILayout.LabelField("Streaming", selectedEvent.IsStream.ToString(), style); } EditorGUILayout.EndHorizontal(); if (isNarrow) { EditorGUILayout.LabelField("Streaming", selectedEvent.IsStream.ToString(), style); } EditorGUIUtility.labelWidth = 0; EditorStyles.label.fontStyle = FontStyle.Normal; if (Event.current.type == EventType.Repaint) { var lastRect = GUILayoutUtility.GetLastRect(); if (!isNarrow) { previewCustomRect = new Rect(lastRect.width / 2 - 200, lastRect.yMax + 10, 400, 150); } else { previewCustomRect = new Rect(lastRect.width / 2 - 130, lastRect.yMax + 10, 260, 150); } } GUI.Box(new Rect(0, previewCustomRect.yMin, previewRect.width, 1), GUIContent.none); GUI.Box(new Rect(0, previewCustomRect.yMax, previewRect.width, 1), GUIContent.none); GUILayout.BeginArea(previewCustomRect); Texture playOff = EditorGUIUtility.Load("FMOD/TransportPlayButtonOff.png") as Texture; Texture playOn = EditorGUIUtility.Load("FMOD/TransportPlayButtonOn.png") as Texture; Texture stopOff = EditorGUIUtility.Load("FMOD/TransportStopButtonOff.png") as Texture; Texture stopOn = EditorGUIUtility.Load("FMOD/TransportStopButtonOn.png") as Texture; Texture openIcon = EditorGUIUtility.Load("FMOD/transportOpen.png") as Texture; var transportButtonStyle = new GUIStyle(); transportButtonStyle.padding.left = 4; transportButtonStyle.padding.top = 10; var previewState = EditorUtils.PreviewState; bool playing = previewState == PreviewState.Playing; bool paused = previewState == PreviewState.Paused; bool stopped = previewState == PreviewState.Stopped; EditorGUILayout.BeginVertical(); if (!isNarrow) { GUILayout.FlexibleSpace(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button(stopped || paused ? stopOn : stopOff, transportButtonStyle, GUILayout.ExpandWidth(false))) { forceRepaint = false; if (paused) { EditorUtils.PreviewStop(); } if (playing) { EditorUtils.PreviewPause(); } } if (GUILayout.Button(playing ? playOn : playOff, transportButtonStyle, GUILayout.ExpandWidth(false))) { if (playing || stopped) { EditorUtils.PreviewEvent(selectedEvent); } else { EditorUtils.PreviewPause(); } forceRepaint = true; } if (GUILayout.Button(new GUIContent(openIcon, "Show Event in FMOD Studio"), transportButtonStyle, GUILayout.ExpandWidth(false))) { string cmd = string.Format("studio.window.navigateTo(studio.project.lookup(\"{0}\"))", selectedEvent.Guid.ToString("b")); EditorUtils.SendScriptCommand(cmd); } EditorGUILayout.EndHorizontal(); if (!isNarrow) { GUILayout.FlexibleSpace(); } EditorGUILayout.EndVertical(); { Texture circle = EditorGUIUtility.Load("FMOD/preview.png") as Texture; Texture circle2 = EditorGUIUtility.Load("FMOD/previewemitter.png") as Texture; var originalColour = GUI.color; if (!selectedEvent.Is3D) { GUI.color = new Color(1.0f, 1.0f, 1.0f, 0.1f); } Rect rect = new Rect(isNarrow ? 120 : 150, 10, 128, 128); GUI.DrawTexture(rect, circle); Vector2 centre = rect.center; Rect rect2 = new Rect(rect.center.x + eventPosition.x - 6, rect.center.y + eventPosition.y - 6, 12, 12); GUI.DrawTexture(rect2, circle2); GUI.color = originalColour; #if UNITY_2017_3_OR_NEWER if (selectedEvent.Is3D && (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) && rect.Contains(Event.current.mousePosition)) #else if (selectedEvent.Is3D && (Event.current.type == EventType.mouseDown || Event.current.type == EventType.mouseDrag) && rect.Contains(Event.current.mousePosition)) #endif { var newPosition = Event.current.mousePosition; Vector2 delta = (newPosition - centre); float distance = delta.magnitude; if (distance < 60) { eventPosition = newPosition - rect.center; previewDistance = distance / 60.0f * selectedEvent.MaxDistance; delta.Normalize(); float angle = Mathf.Atan2(delta.y, delta.x); previewOrientation = angle + Mathf.PI * 0.5f; } Event.current.Use(); } EditorUtils.PreviewUpdatePosition(previewDistance, previewOrientation); } float hoffset = isNarrow ? 15 : 300; float voffset = isNarrow ? 50 : 10; Texture meterOn = EditorGUIUtility.Load("FMOD/LevelMeter.png") as Texture; Texture meterOff = EditorGUIUtility.Load("FMOD/LevelMeterOff.png") as Texture; float[] metering = EditorUtils.GetMetering(); int meterHeight = isNarrow ? 86 : 128; int meterWidth = (int)((128 / (float)meterOff.height) * meterOff.width); foreach (float rms in metering) { GUI.DrawTexture(new Rect(hoffset, voffset, meterWidth, meterHeight), meterOff); float db = 20.0f * Mathf.Log10(rms * Mathf.Sqrt(2.0f)); db = Mathf.Clamp(db, -80.0f, 10.0f); float visible = 0; int[] segmentPixels = new int[] { 0, 18, 38, 60, 89, 130, 187, 244, 300 }; float[] segmentDB = new float[] { -80.0f, -60.0f, -50.0f, -40.0f, -30.0f, -20.0f, -10.0f, 0, 10.0f }; int segment = 1; while (segmentDB[segment] < db) { segment++; } visible = segmentPixels[segment - 1] + ((db - segmentDB[segment - 1]) / (segmentDB[segment] - segmentDB[segment - 1])) * (segmentPixels[segment] - segmentPixels[segment - 1]); visible *= meterHeight / (float)meterOff.height; Rect levelPosRect = new Rect(hoffset, meterHeight - visible + voffset, meterWidth, visible); Rect levelUVRect = new Rect(0, 0, 1.0f, visible / meterHeight); GUI.DrawTextureWithTexCoords(levelPosRect, meterOn, levelUVRect); hoffset += meterWidth + 5.0f; } GUILayout.EndArea(); Rect paramRect = new Rect(0, previewCustomRect.yMax + 10, previewRect.width, previewRect.height - (previewCustomRect.yMax + 10)); GUILayout.BeginArea(paramRect); paramScroll = GUILayout.BeginScrollView(paramScroll, false, false); foreach (var paramRef in selectedEvent.Parameters) { if (!previewParamValues.ContainsKey(paramRef.Name)) { previewParamValues[paramRef.Name] = paramRef.Default; } previewParamValues[paramRef.Name] = EditorGUILayout.Slider(paramRef.Name, previewParamValues[paramRef.Name], paramRef.Min, paramRef.Max); EditorUtils.PreviewUpdateParameter(paramRef.Name, previewParamValues[paramRef.Name]); } GUILayout.EndScrollView(); GUILayout.EndArea(); GUILayout.EndArea(); }
void OnGUI() { if (!EventManager.IsLoaded) { this.ShowNotification(new GUIContent("No FMOD Studio banks loaded. Please check your settings.")); return; } if (Event.current.type == EventType.Layout) { RebuildDisplayFromCache(); } //if (eventStyle == null) { eventStyle = new GUIStyle(GUI.skin.button); eventStyle.normal.background = null; eventStyle.focused.background = null; eventStyle.active.background = null; eventStyle.onFocused.background = null; eventStyle.onNormal.background = null; eventStyle.onHover.background = null; eventStyle.onActive.background = null; eventStyle.stretchWidth = false; eventStyle.padding.left = 0; eventStyle.stretchHeight = false; eventStyle.fixedHeight = eventStyle.lineHeight + eventStyle.margin.top + eventStyle.margin.bottom; eventStyle.alignment = TextAnchor.MiddleLeft; eventIcon = EditorGUIUtility.Load("FMOD/EventIcon.png") as Texture; folderOpenIcon = EditorGUIUtility.Load("FMOD/FolderIconOpen.png") as Texture; folderClosedIcon = EditorGUIUtility.Load("FMOD/FolderIconClosed.png") as Texture; searchIcon = EditorGUIUtility.Load("FMOD/SearchIcon.png") as Texture; bankIcon = EditorGUIUtility.Load("FMOD/BankIcon.png") as Texture; snapshotIcon = EditorGUIUtility.Load("FMOD/SnapshotIcon.png") as Texture; } // Split the window int search box, tree view, preview pane (only if full browser) Rect searchRect = new Rect(0, 0, position.width, 16); float previewBoxHeight = fromInspector ? 0 : 400; Rect listRect = new Rect(0, searchRect.height + 2, position.width, position.height - previewBoxHeight - searchRect.height - 15); Rect previewRect = new Rect(0, position.height - previewBoxHeight, position.width, previewBoxHeight); // Scroll the selected item in the tree view - put above the search box otherwise it will take // our key presses if (selectedItem != null && Event.current.type == EventType.keyDown) { if (Event.current.keyCode == KeyCode.UpArrow) { if (selectedItem.Prev != null) { SetSelectedItem(selectedItem.Prev); // make sure it's visible if (selectedItem.Rect.y < treeScroll.y) { treeScroll.y = selectedItem.Rect.y; } } Event.current.Use(); } if (Event.current.keyCode == KeyCode.DownArrow) { if (selectedItem.Next != null) { SetSelectedItem(selectedItem.Next); // make sure it's visible if (selectedItem.Rect.y + selectedItem.Rect.height > treeScroll.y + listRect.height) { treeScroll.y += (selectedItem.Rect.y + selectedItem.Rect.height) - listRect.height; } } Event.current.Use(); } } // Show the search box at the top GUILayout.BeginArea(searchRect); GUILayout.BeginHorizontal(); GUILayout.Label(new GUIContent(searchIcon), GUILayout.ExpandWidth(false)); GUI.SetNextControlName("SearchBox"); searchString = GUILayout.TextField(searchString); GUILayout.EndHorizontal(); GUILayout.EndArea(); if (fromInspector) { GUI.FocusControl("SearchBox"); if (selectedItem != null && Event.current.isKey && Event.current.keyCode == KeyCode.Return) { Event.current.Use(); if (selectedItem.EventRef != null) { outputProperty.stringValue = selectedItem.EventRef.Path; EditorUtils.UpdateParamsOnEmmitter(outputProperty.serializedObject); } else { outputProperty.stringValue = selectedItem.BankRef.Name; } outputProperty.serializedObject.ApplyModifiedProperties(); Close(); } } // Show the tree view Predicate <TreeItem> searchFilter = null; searchFilter = (x) => (x.Name.ToLower().Contains(searchString.ToLower()) || x.Children.Exists(searchFilter)); // Check if our selected item still matches the search string if (selectedItem != null && !String.IsNullOrEmpty(searchString)) { Predicate <TreeItem> containsSelected = null; containsSelected = (x) => (x == selectedItem || x.Children.Exists(containsSelected)); Predicate <TreeItem> matchForSelected = null; matchForSelected = (x) => (x.Name.ToLower().Contains(searchString.ToLower()) && (x == selectedItem || x.Children.Exists(containsSelected))) || x.Children.Exists(matchForSelected); if (!treeItems.Exists(matchForSelected)) { SetSelectedItem(null); } } GUILayout.BeginArea(listRect); treeScroll = GUILayout.BeginScrollView(treeScroll, GUILayout.ExpandHeight(true)); lastDrawnItem = null; itemCount = 0; if (showEvents) { treeItems[0].Expanded = fromInspector ? true : treeItems[0].Expanded; ShowEventFolder(treeItems[0], searchFilter); ShowEventFolder(treeItems[1], searchFilter); } if (showBanks) { treeItems[2].Expanded = fromInspector ? true : treeItems[2].Expanded; ShowEventFolder(treeItems[2], searchFilter); } GUILayout.EndScrollView(); GUILayout.EndArea(); // If the standalone event browser show a preview of the selected item if (!fromInspector) { Rect previewAutoRect = new Rect(previewRect); previewAutoRect.height -= 140; Rect previewCustomBox = new Rect(previewRect); previewCustomBox.y = previewAutoRect.y + previewAutoRect.height + 10; previewCustomBox.height = 128; GUI.Box(previewRect, GUIContent.none); if (selectedItem != null && selectedItem.EventRef != null && selectedItem.EventRef.Path.StartsWith("event:")) { GUILayout.BeginArea(previewAutoRect); var style = new GUIStyle(GUI.skin.FindStyle("label")); style.richText = true; var selectedEvent = selectedItem.EventRef; // path EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Full Path</b>", style, style); EditorGUILayout.LabelField(selectedEvent.Path); EditorGUILayout.EndHorizontal(); // guid EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>GUID</b>", style, style); EditorGUILayout.LabelField(selectedEvent.Guid.ToString("b")); EditorGUILayout.EndHorizontal(); // Bank EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Bank</b>", style, style); StringBuilder builder = new StringBuilder(); selectedEvent.Banks.ForEach((x) => { builder.Append(Path.GetFileNameWithoutExtension(x.Path)); builder.Append(", "); }); EditorGUILayout.LabelField(builder.ToString(0, Math.Max(0, builder.Length - 2))); EditorGUILayout.EndHorizontal(); // Panning EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Panning</b>", style, style); EditorGUILayout.LabelField(selectedEvent.Is3D ? "3D" : "2D"); EditorGUILayout.EndHorizontal(); // One shot EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Oneshot</b>", style, style); EditorGUILayout.LabelField(selectedEvent.IsOneShot.ToString()); EditorGUILayout.EndHorizontal(); // Streaming EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Streaming</b>", style, style); EditorGUILayout.LabelField(selectedEvent.IsStream.ToString()); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Play")) { EditorUtils.PreviewEvent(selectedEvent); forceRepaint = true; } if (GUILayout.Button("Pause")) { EditorUtils.PreviewPause(); } if (GUILayout.Button("Stop")) { forceRepaint = false; EditorUtils.PreviewStop(); } if (GUILayout.Button("Show In Studio")) { string cmd = string.Format("studio.window.navigateTo(studio.project.lookup(\"{0}\"))", selectedEvent.Guid.ToString("b")); EditorUtils.SendScriptCommand(cmd); } EditorGUILayout.EndHorizontal(); paramScroll = GUILayout.BeginScrollView(paramScroll, false, true); foreach (var paramRef in selectedEvent.Parameters) { if (!previewParamValues.ContainsKey(paramRef.Name)) { previewParamValues[paramRef.Name] = 0; } previewParamValues[paramRef.Name] = EditorGUILayout.Slider(paramRef.Name, previewParamValues[paramRef.Name], paramRef.Min, paramRef.Max); EditorUtils.PreviewUpdateParameter(paramRef.Name, previewParamValues[paramRef.Name]); } GUILayout.EndScrollView(); GUILayout.EndArea(); GUILayout.BeginArea(previewCustomBox); if (selectedEvent.Is3D) { Texture circle = EditorGUIUtility.Load("FMOD/preview.png") as Texture; Texture circle2 = EditorGUIUtility.Load("FMOD/previewemitter.png") as Texture; Rect rect = new Rect(position.width / 2.0f - 150f, 0, 128, 128); GUI.DrawTexture(rect, circle); Vector2 centre = rect.center; Rect rect2 = new Rect(rect.center + eventPosition - new Vector2(6, 6), new Vector2(12, 12)); GUI.DrawTexture(rect2, circle2); if ((Event.current.type == EventType.mouseDown || Event.current.type == EventType.mouseDrag) && rect.Contains(Event.current.mousePosition)) { var newPosition = Event.current.mousePosition; Vector2 delta = (newPosition - centre); float distance = delta.magnitude; if (distance < 60) { eventPosition = newPosition - rect.center; previewDistance = distance / 60.0f * selectedEvent.MaxDistance; delta.Normalize(); float angle = Mathf.Atan2(delta.y, delta.x); previewOrientation = angle + Mathf.PI * 0.5f; } Event.current.Use(); } EditorUtils.PreviewUpdatePosition(previewDistance, previewOrientation); } float offset = position.width / 2.0f; Texture meterOn = EditorGUIUtility.Load("FMOD/LevelMeter.png") as Texture; Texture meterOff = EditorGUIUtility.Load("FMOD/LevelMeterOff.png") as Texture; float[] metering = EditorUtils.GetMetering(); int meterHeight = 128; int meterWidth = (int)((128 / (float)meterOff.height) * meterOff.width); foreach (float rms in metering) { GUI.DrawTexture(new Rect(offset, 0, meterWidth, meterHeight), meterOff); float db = rms > 0 ? 20.0f * Mathf.Log10(rms * Mathf.Sqrt(2.0f)) : -80.0f; if (db > 10.0f) { db = 10.0f; } float visible = 0; int[] segmentPixels = new int[] { 0, 18, 38, 60, 89, 130, 187, 244, 300 }; float[] segmentDB = new float[] { -80.0f, -60.0f, -50.0f, -40.0f, -30.0f, -20.0f, -10.0f, 0, 10.0f }; int segment = 1; while (segmentDB[segment] < db) { segment++; } visible = segmentPixels[segment - 1] + ((db - segmentDB[segment - 1]) / (segmentDB[segment] - segmentDB[segment - 1])) * (segmentPixels[segment] - segmentPixels[segment - 1]); visible *= 128 / (float)meterOff.height; Rect levelPosRect = new Rect(offset, 128 - visible, meterWidth, visible); Rect levelUVRect = new Rect(0, 0, 1.0f, visible / meterHeight); GUI.DrawTextureWithTexCoords(levelPosRect, meterOn, levelUVRect); offset += meterWidth + 5.0f; } GUILayout.EndArea(); } if (selectedItem != null && selectedItem.EventRef != null && selectedItem.EventRef.Path.StartsWith("snapshot:")) { GUILayout.BeginArea(previewAutoRect); var style = new GUIStyle(GUI.skin.FindStyle("label")); style.richText = true; var selectedEvent = selectedItem.EventRef; // path EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Full Path</b>", style, style); EditorGUILayout.LabelField(selectedEvent.Path); EditorGUILayout.EndHorizontal(); // guid EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>GUID</b>", style, style); EditorGUILayout.LabelField(selectedEvent.Guid.ToString("b")); EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); } if (selectedItem != null && selectedItem.BankRef != null) { GUILayout.BeginArea(previewRect); string[] SizeSuffix = { "B", "KB", "MB", "GB" }; var selectedBank = selectedItem.BankRef; var style = new GUIStyle(GUI.skin.FindStyle("label")); style.richText = true; GUILayout.Label("<b>Platform Bank Sizes</b>", style); EditorGUI.indentLevel++; foreach (var sizeInfo in selectedBank.FileSizes) { int order = 0; long len = sizeInfo.Value; while (len >= 1024 && order + 1 < SizeSuffix.Length) { order++; len /= 1024; } EditorGUILayout.LabelField(sizeInfo.Name, String.Format("{0} {1}", len, SizeSuffix[order])); } EditorGUI.indentLevel--; GUILayout.EndArea(); } } }