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 = 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, previewParamValues); } 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 (selectedEvent.Is3D && (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 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.ID, previewParamValues[paramRef.Name]); } GUILayout.EndScrollView(); GUILayout.EndArea(); GUILayout.EndArea(); }
void OnDestroy() { EditorUtils.PreviewStop(); }
void OnGUI() { if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying) { // Brute force hack to stop us calling DLL functions while Unity is starting up // playing in editor mode and will cause us to leak system objects ShowNotification(new GUIContent("Playing In Editor Starting")); return; } if (!EventManager.IsValid) { 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; borderIcon = EditorGUIUtility.Load("FMOD/Border.png") as Texture2D; } if (fromInspector) { var border = new GUIStyle(GUI.skin.box); border.normal.background = borderIcon; GUI.Box(new Rect(1, 1, position.width - 1, position.height - 1), GUIContent.none, border); } // Split the window int search box, tree view, preview pane (only if full browser) Rect searchRect, listRect, previewRect; SplitWindow(out searchRect, out listRect, out previewRect); // 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(); } if (Event.current.keyCode == KeyCode.RightArrow) { selectedItem.Expanded = true; Event.current.Use(); } if (Event.current.keyCode == KeyCode.LeftArrow) { selectedItem.Expanded = false; 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 = EditorGUILayout.TextField(searchString); GUILayout.EndHorizontal(); GUILayout.EndArea(); if (fromInspector) { EditorGUI.FocusTextInControl("SearchBox"); if (selectedItem != null && Event.current.isKey && Event.current.keyCode == KeyCode.Return && !(selectedItem.EventRef == null && selectedItem.BankRef == null)) { Event.current.Use(); if (selectedItem.EventRef != null) { outputProperty.stringValue = ""; outputProperty.stringValue = selectedItem.EventRef.Path; EditorUtils.UpdateParamsOnEmitter(outputProperty.serializedObject, selectedItem.EventRef.Path); } else { outputProperty.stringValue = selectedItem.BankRef.Name; } outputProperty.serializedObject.ApplyModifiedProperties(); Close(); } if (Event.current.isKey && Event.current.keyCode == KeyCode.Escape) { 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) && selectedItem.Children.Count == 0) { 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[(int)TreeType.Events].Expanded = fromInspector ? true : treeItems[(int)TreeType.Events].Expanded; ShowEventFolder(treeItems[(int)TreeType.Events], searchFilter); ShowEventFolder(treeItems[(int)TreeType.Snapshots], searchFilter); } if (showBanks) { treeItems[(int)TreeType.Banks].Expanded = fromInspector ? true : treeItems[(int)TreeType.Banks].Expanded; ShowEventFolder(treeItems[(int)TreeType.Banks], searchFilter); } if (showParameters) { treeItems[(int)TreeType.GlobalParameters].Expanded = fromInspector ? true : treeItems[(int)TreeType.GlobalParameters].Expanded; ShowEventFolder(treeItems[(int)TreeType.GlobalParameters], searchFilter); } GUILayout.EndScrollView(); GUILayout.EndArea(); // If the standalone event browser show a preview of the selected item if (!fromInspector) { GUI.Box(previewRect, GUIContent.none); if (selectedItem != null && selectedItem.EventRef != null && selectedItem.EventRef.Path.StartsWith("event:")) { PreviewEvent(previewRect, selectedItem.EventRef); } if (selectedItem != null && selectedItem.EventRef != null && selectedItem.EventRef.Path.StartsWith("snapshot:")) { PreviewSnapshot(previewRect, selectedItem.EventRef); } if (selectedItem != null && selectedItem.BankRef != null) { PreviewBank(previewRect, selectedItem.BankRef); } if (selectedItem != null && selectedItem.ParamRef != null) { PreviewParameter(previewRect, selectedItem.ParamRef); } } }
public void OnGUI() { var borderIcon = EditorGUIUtility.Load("FMOD/Border.png") as Texture2D; var border = new GUIStyle(GUI.skin.box); border.normal.background = borderIcon; GUI.Box(new Rect(1, 1, position.width - 1, position.height - 1), GUIContent.none, border); if (Event.current.type == EventType.Layout) { isConnected = EditorUtils.IsConnectedToStudio(); } if (!isConnected) { this.ShowNotification(new GUIContent("FMOD Studio not running")); return; } this.RemoveNotification(); if (rootFolder == null) { BuildTree(); currentFolder = rootFolder; } var arrowIcon = EditorGUIUtility.Load("FMOD/ArrowIcon.png") as Texture; var hoverIcon = EditorGUIUtility.Load("FMOD/SelectedAlt.png") as Texture2D; var titleIcon = EditorGUIUtility.Load("IN BigTitle") as Texture2D; var nextEntry = currentFolder; var filteredEntries = currentFolder.entries.FindAll((x) => x.name.StartsWith(currentFilter, StringComparison.CurrentCultureIgnoreCase)); // Process key strokes for the folder list { if (Event.current.keyCode == KeyCode.UpArrow) { if (Event.current.type == EventType.KeyDown) { lastHover = Math.Max(lastHover - 1, 0); if (filteredEntries [lastHover].rect.y < scrollPos.y) { scrollPos.y = filteredEntries [lastHover].rect.y; } } Event.current.Use(); } if (Event.current.keyCode == KeyCode.DownArrow) { if (Event.current.type == EventType.KeyDown) { lastHover = Math.Min(lastHover + 1, filteredEntries.Count - 1); if (filteredEntries [lastHover].rect.y + filteredEntries [lastHover].rect.height > scrollPos.y + scrollRect.height) { scrollPos.y = filteredEntries [lastHover].rect.y - scrollRect.height + filteredEntries [lastHover].rect.height * 2; } } Event.current.Use(); } if (Event.current.keyCode == KeyCode.RightArrow) { if (Event.current.type == EventType.KeyDown) { nextEntry = filteredEntries [lastHover]; } Event.current.Use(); } if (Event.current.keyCode == KeyCode.LeftArrow) { if (Event.current.type == EventType.KeyDown) { if (currentFolder.parent != null) { nextEntry = currentFolder.parent; } } Event.current.Use(); } } bool disabled = eventName.Length == 0; EditorGUI.BeginDisabledGroup(disabled); if (GUILayout.Button("Create Event")) { CreateEventInStudio(); this.Close(); } EditorGUI.EndDisabledGroup(); { GUI.SetNextControlName("name"); EditorGUILayout.LabelField("Name"); eventName = EditorGUILayout.TextField(eventName); } { EditorGUILayout.LabelField("Bank"); selectedBank = EditorGUILayout.Popup(selectedBank, banks.Select(x => x.name).ToArray()); } bool updateEventPath = false; { GUI.SetNextControlName("folder"); EditorGUI.BeginChangeCheck(); EditorGUILayout.LabelField("Path"); eventFolder = GUILayout.TextField(eventFolder); if (EditorGUI.EndChangeCheck()) { updateEventPath = true; } } if (resetCursor) { resetCursor = false; var textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); if (textEditor != null) { textEditor.MoveCursorToPosition(new Vector2(9999, 9999)); } } // Draw the current folder as a title bar, click to go back one level { Rect currentRect = EditorGUILayout.GetControlRect(); var bg = new GUIStyle(GUI.skin.box); bg.normal.background = titleIcon; Rect bgRect = new Rect(currentRect); bgRect.x = 2; bgRect.width = position.width - 4; GUI.Box(bgRect, GUIContent.none, bg); Rect textureRect = currentRect; textureRect.width = arrowIcon.width; if (currentFolder.name != null) { GUI.DrawTextureWithTexCoords(textureRect, arrowIcon, new Rect(1, 1, -1, -1)); } Rect labelRect = currentRect; labelRect.x += arrowIcon.width + 50; labelRect.width -= arrowIcon.width + 50; GUI.Label(labelRect, currentFolder.name != null ? currentFolder.name : "Folders", EditorStyles.boldLabel); if (Event.current.type == EventType.MouseDown && currentRect.Contains(Event.current.mousePosition) && currentFolder.parent != null) { nextEntry = currentFolder.parent; Event.current.Use(); } } var normal = new GUIStyle(GUI.skin.label); normal.padding.left = 14; var hover = new GUIStyle(normal); hover.normal.background = hoverIcon; scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, false); for (int i = 0; i < filteredEntries.Count; i++) { var entry = filteredEntries [i]; var content = new GUIContent(entry.name); var rect = EditorGUILayout.GetControlRect(); if ((rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseMove) || i == lastHover) { lastHover = i; GUI.Label(rect, content, hover); if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDown) { nextEntry = entry; } } else { GUI.Label(rect, content, normal); } Rect textureRect = rect; textureRect.x = textureRect.width - arrowIcon.width; textureRect.width = arrowIcon.width; GUI.DrawTexture(textureRect, arrowIcon); if (Event.current.type == EventType.Repaint) { entry.rect = rect; } } EditorGUILayout.EndScrollView(); if (Event.current.type == EventType.Repaint) { scrollRect = GUILayoutUtility.GetLastRect(); } if (currentFolder != nextEntry) { lastHover = 0; currentFolder = nextEntry; UpdateTextFromList(); Repaint(); } if (updateEventPath) { UpdateListFromText(); } if (Event.current.type == EventType.MouseMove) { Repaint(); } }
void ShowEventFolder(TreeItem item, Predicate <TreeItem> filter) { eventStyle.padding.left += 17; { // Highlight first found item if (item.EventRef != null || item.BankRef != null) { if (!String.IsNullOrEmpty(searchString) && itemCount == 0 && selectedItem == null ) { SetSelectedItem(item); } itemCount++; } item.Next = null; item.Prev = lastDrawnItem; if (lastDrawnItem != null) { lastDrawnItem.Next = item; } lastDrawnItem = item; } if (item.EventRef != null) { // Rendering and GUI event handling to show an event GUIContent content = new GUIContent(item.Name, item.EventRef.Path.StartsWith("snapshot") ? snapshotIcon : eventIcon); eventStyle.normal.background = selectedItem == item?EditorGUIUtility.Load("FMOD/Selected.png") as Texture2D : null; GUILayout.Label(content, eventStyle, GUILayout.ExpandWidth(true)); Event e = Event.current; Rect rect = GUILayoutUtility.GetLastRect(); if (e.type == EventType.MouseDown && e.button == 0 && rect.Contains(e.mousePosition)) { e.Use(); if (fromInspector && e.clickCount >= 2) { outputProperty.stringValue = ""; outputProperty.stringValue = item.EventRef.Path; EditorUtils.UpdateParamsOnEmitter(outputProperty.serializedObject, item.EventRef.Path); outputProperty.serializedObject.ApplyModifiedProperties(); Close(); } SetSelectedItem(item); } if (e.type == EventType.MouseDrag && rect.Contains(e.mousePosition) && !fromInspector) { DragAndDrop.PrepareStartDrag(); DragAndDrop.objectReferences = new UnityEngine.Object[] { Instantiate(item.EventRef) }; DragAndDrop.StartDrag("New FMOD Studio Emitter"); e.Use(); } if (Event.current.type == EventType.Repaint) { item.Rect = rect; } } else if (item.BankRef != null) { // Rendering and event handling for a bank GUIContent content = new GUIContent(item.Name, bankIcon); eventStyle.normal.background = selectedItem == item?EditorGUIUtility.Load("FMOD/Selected.png") as Texture2D : null; GUILayout.Label(content, eventStyle, GUILayout.ExpandWidth(true)); Event e = Event.current; Rect rect = GUILayoutUtility.GetLastRect(); if (e.type == EventType.MouseDown && e.button == 0 && rect.Contains(e.mousePosition)) { e.Use(); if (fromInspector && e.clickCount >= 2) { outputProperty.stringValue = item.BankRef.Name; outputProperty.serializedObject.ApplyModifiedProperties(); Close(); } SetSelectedItem(item); } if (e.type == EventType.MouseDrag && rect.Contains(e.mousePosition) && !fromInspector) { DragAndDrop.PrepareStartDrag(); DragAndDrop.objectReferences = new UnityEngine.Object[] { Instantiate(item.BankRef) }; DragAndDrop.StartDrag("New FMOD Studio Bank Loader"); e.Use(); } if (Event.current.type == EventType.Repaint) { item.Rect = rect; } } else if (item.ParamRef != null) { // Rendering and event handling for a bank GUIContent content = new GUIContent(item.Name, eventIcon); eventStyle.normal.background = selectedItem == item?EditorGUIUtility.Load("FMOD/Selected.png") as Texture2D : null; GUILayout.Label(content, eventStyle, GUILayout.ExpandWidth(true)); Event e = Event.current; Rect rect = GUILayoutUtility.GetLastRect(); if (e.type == EventType.MouseDown && e.button == 0 && rect.Contains(e.mousePosition)) { e.Use(); if (fromInspector && e.clickCount >= 2) { outputProperty.stringValue = item.ParamRef.Name; outputProperty.serializedObject.ApplyModifiedProperties(); Close(); } SetSelectedItem(item); } if (e.type == EventType.MouseDrag && rect.Contains(e.mousePosition) && !fromInspector) { DragAndDrop.PrepareStartDrag(); DragAndDrop.objectReferences = new UnityEngine.Object[] { Instantiate(item.ParamRef) }; DragAndDrop.StartDrag("New FMOD Studio Global Parameter Trigger"); e.Use(); } if (Event.current.type == EventType.Repaint) { item.Rect = rect; } } else { eventStyle.normal.background = selectedItem == item?EditorGUIUtility.Load("FMOD/Selected.png") as Texture2D : null; bool expanded = item.Expanded || !string.IsNullOrEmpty(searchString); GUIContent content = new GUIContent(item.Name, expanded ? folderOpenIcon : folderClosedIcon); GUILayout.Label(content, eventStyle, GUILayout.ExpandWidth(true)); Rect rect = GUILayoutUtility.GetLastRect(); if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition)) { Event.current.Use(); item.Expanded = !item.Expanded; SetSelectedItem(item); } if (item.Expanded || !string.IsNullOrEmpty(searchString)) { item.Children.Sort((a, b) => a.Name.CompareTo(b.Name)); if (item.Name.ToLower().Contains(searchString.ToLower())) { foreach (var childFolder in item.Children) { ShowEventFolder(childFolder, (x) => true); } } else { foreach (var childFolder in item.Children.FindAll(filter)) { ShowEventFolder(childFolder, filter); } } } if (Event.current.type == EventType.Repaint) { item.Rect = rect; } } eventStyle.padding.left -= 17; }
public override void OnInspectorGUI() { Settings settings = target as Settings; EditorUtility.SetDirty(settings); hasBankSourceChanged = false; GUIStyle style = new GUIStyle(GUI.skin.label); style.richText = true; EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Source</b>", GUI.skin.textField, style); int selection = settings.HasSourceProject ? 0 : 1; selection = GUILayout.SelectionGrid(selection, new GUIContent[2] { new GUIContent("Project"), new GUIContent("Bank Folder") }, 2, GUILayout.ExpandWidth(false)); settings.HasSourceProject = selection == 0; EditorGUILayout.EndHorizontal(); if (selection == 0) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceProjectPath; EditorGUILayout.PrefixLabel("Studio Project Path", GUI.skin.textField, style); settings.SourceProjectPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceProjectPath); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string path = EditorUtility.OpenFilePanel("Locate Studio Project", oldPath, "fspro"); if (!String.IsNullOrEmpty(path)) { settings.SourceProjectPath = path; this.Repaint(); } } EditorGUILayout.EndHorizontal(); // Cache in settings for runtime access in play-in-editor mode settings.SourceBankPath = EditorUtils.GetBankDirectory(); settings.HasPlatforms = true; // First time project path is set or changes, copy to streaming assets if (settings.SourceProjectPath != oldPath) { hasBankSourceChanged = true; } } else { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceBankPath; EditorGUILayout.PrefixLabel("Banks Folder Path", GUI.skin.textField, style); settings.SourceBankPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceBankPath); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); var path = EditorUtility.OpenFolderPanel("Locate Studio Banks", oldPath, null); if (!String.IsNullOrEmpty(path)) { settings.SourceBankPath = path; } } EditorGUILayout.EndHorizontal(); settings.HasPlatforms = EditorUtils.GetBankPlatforms().Length > 0; // First time project path is set or changes, copy to streaming assets if (settings.SourceBankPath != oldPath) { hasBankSourceChanged = true; } } if ((settings.HasSourceProject && !File.Exists(settings.SourceProjectPath)) || !Directory.Exists(settings.SourceBankPath)) { return; } // ----- PIE ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Play In Editor Settings</b>", style); EditorGUI.indentLevel++; DisplayParentBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.PlayInEditor); if (settings.IsLiveUpdateEnabled(FMODPlatform.PlayInEditor)) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" "); #if UNITY_5_0 || UNITY_5_1 GUILayout.Label("Unity 5.0 or 5.1 detected: Live update will listen on port <b>9265</b>", style); #else GUILayout.Label("Live update will listen on port <b>9264</b>", style); #endif EditorGUILayout.EndHorizontal(); } DisplayParentSpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { DisplayParentBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.PlayInEditor); } EditorGUI.indentLevel--; // ----- Default ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Default Settings</b>", style); EditorGUI.indentLevel++; DisplayParentBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.Default); if (settings.IsLiveUpdateEnabled(FMODPlatform.Default)) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" "); #if UNITY_5_0 || UNITY_5_1 GUILayout.Label("Unity 5.0 or 5.1 detected: Live update will listen on port <b>9265</b>", style); #else GUILayout.Label("Live update will listen on port <b>9264</b>", style); #endif EditorGUILayout.EndHorizontal(); } DisplayParentSpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.Default); DisplayParentFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.Default); if (settings.HasPlatforms) { bool prevChanged = GUI.changed; DisplayParentBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.Default); hasBankSourceChanged |= !prevChanged && GUI.changed; } DisplayParentInt("Virtual Channel Count", settings.VirtualChannelSettings, FMODPlatform.Default, 0, 2048); DisplayParentInt("Real Channel Count", settings.RealChannelSettings, FMODPlatform.Default, 0, 2048); EditorGUI.indentLevel--; // ----- Plugins ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Plugins</b>", GUI.skin.button, style); if (GUILayout.Button("Add Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.Add(""); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel++; for (int count = 0; count < settings.Plugins.Count; count++) { EditorGUILayout.BeginHorizontal(); settings.Plugins[count] = EditorGUILayout.TextField("Plugin " + (count + 1).ToString() + ":", settings.Plugins[count]); if (GUILayout.Button("Delete Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.RemoveAt(count); } EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; // ----- Windows ---------------------------------------------- DisplayPlatform(FMODPlatform.Desktop, null); DisplayPlatform(FMODPlatform.Mobile, new FMODPlatform[] { FMODPlatform.MobileHigh, FMODPlatform.MobileLow, FMODPlatform.PSVita }); DisplayPlatform(FMODPlatform.Console, new FMODPlatform[] { FMODPlatform.XboxOne, FMODPlatform.PS4, FMODPlatform.WiiU }); if (hasBankSourceChanged) { EditorUtils.CopyToStreamingAssets(); } }
public override void OnInspectorGUI() { var begin = serializedObject.FindProperty("PlayEvent"); var end = serializedObject.FindProperty("StopEvent"); var tag = serializedObject.FindProperty("CollisionTag"); var ev = serializedObject.FindProperty("Event"); var param = serializedObject.FindProperty("Params"); var fadeout = serializedObject.FindProperty("AllowFadeout"); var once = serializedObject.FindProperty("TriggerOnce"); var preload = serializedObject.FindProperty("Preload"); var overrideAtt = serializedObject.FindProperty("OverrideAttenuation"); var minDistance = serializedObject.FindProperty("OverrideMinDistance"); var maxDistance = serializedObject.FindProperty("OverrideMaxDistance"); EditorGUILayout.PropertyField(begin, new GUIContent("Play Event")); EditorGUILayout.PropertyField(end, new GUIContent("Stop Event")); if (begin.enumValueIndex == 3 || begin.enumValueIndex == 4 || end.enumValueIndex == 3 || end.enumValueIndex == 4) { tag.stringValue = EditorGUILayout.TagField("Collision Tag", tag.stringValue); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(ev, new GUIContent("Event")); EditorEventRef editorEvent = EventManager.EventFromPath(ev.stringValue); if (EditorGUI.EndChangeCheck()) { EditorUtils.UpdateParamsOnEmitter(serializedObject, ev.stringValue); if (editorEvent != null) { overrideAtt.boolValue = false; minDistance.floatValue = editorEvent.MinDistance; maxDistance.floatValue = editorEvent.MaxDistance; } } // Attenuation { EditorGUI.BeginDisabledGroup(editorEvent == null || !editorEvent.Is3D); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Override Attenuation"); EditorGUI.BeginChangeCheck(); overrideAtt.boolValue = EditorGUILayout.Toggle(overrideAtt.boolValue, GUILayout.Width(20)); if (EditorGUI.EndChangeCheck() || (minDistance.floatValue == -1 && maxDistance.floatValue == -1) // never been initialiased ) { minDistance.floatValue = editorEvent.MinDistance; maxDistance.floatValue = editorEvent.MaxDistance; } EditorGUI.BeginDisabledGroup(!overrideAtt.boolValue); EditorGUIUtility.labelWidth = 30; minDistance.floatValue = EditorGUILayout.FloatField("Min", minDistance.floatValue); minDistance.floatValue = Mathf.Clamp(minDistance.floatValue, 0, maxDistance.floatValue); maxDistance.floatValue = EditorGUILayout.FloatField("Max", maxDistance.floatValue); maxDistance.floatValue = Mathf.Max(minDistance.floatValue, maxDistance.floatValue); EditorGUIUtility.labelWidth = 0; EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); } param.isExpanded = EditorGUILayout.Foldout(param.isExpanded, "Initial Parameter Values"); if (ev.hasMultipleDifferentValues) { if (param.isExpanded) { GUILayout.Box("Cannot change parameters when different events are selected", GUILayout.ExpandWidth(true)); } } else { var eventRef = EventManager.EventFromPath(ev.stringValue); if (param.isExpanded && eventRef != null) { foreach (var paramRef in eventRef.Parameters) { bool set; float value; bool matchingSet, matchingValue; CheckParameter(paramRef.Name, out set, out matchingSet, out value, out matchingValue); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(paramRef.Name); EditorGUI.showMixedValue = !matchingSet; EditorGUI.BeginChangeCheck(); bool newSet = EditorGUILayout.Toggle(set, GUILayout.Width(20)); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) { Undo.RecordObjects(serializedObject.isEditingMultipleObjects ? serializedObject.targetObjects : new UnityEngine.Object[] { serializedObject.targetObject }, "Inspector"); if (newSet) { AddParameterValue(paramRef.Name, paramRef.Default); } else { DeleteParameterValue(paramRef.Name); } set = newSet; } EditorGUI.BeginDisabledGroup(!newSet); if (set) { EditorGUI.showMixedValue = !matchingValue; EditorGUI.BeginChangeCheck(); value = EditorGUILayout.Slider(value, paramRef.Min, paramRef.Max); if (EditorGUI.EndChangeCheck()) { Undo.RecordObjects(serializedObject.isEditingMultipleObjects ? serializedObject.targetObjects : new UnityEngine.Object[] { serializedObject.targetObject }, "Inspector"); SetParameterValue(paramRef.Name, value); } EditorGUI.showMixedValue = false; } else { EditorGUI.showMixedValue = !matchingValue; EditorGUILayout.Slider(paramRef.Default, paramRef.Min, paramRef.Max); EditorGUI.showMixedValue = false; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); } } } fadeout.isExpanded = EditorGUILayout.Foldout(fadeout.isExpanded, "Advanced Controls"); if (fadeout.isExpanded) { EditorGUILayout.PropertyField(preload, new GUIContent("Preload Sample Data")); EditorGUILayout.PropertyField(fadeout, new GUIContent("Allow Fadeout When Stopping")); EditorGUILayout.PropertyField(once, new GUIContent("Trigger Once")); } serializedObject.ApplyModifiedProperties(); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Texture browseIcon = EditorGUIUtility.Load("FMOD/SearchIconBlack.png") as Texture; Texture openIcon = EditorGUIUtility.Load("FMOD/StudioIcon.png") as Texture; EditorGUI.BeginProperty(position, label, property); SerializedProperty pathProperty = property.FindPropertyRelative("Path"); Event e = Event.current; if (e.type == EventType.dragPerform && position.Contains(e.mousePosition)) { if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] != null && DragAndDrop.objectReferences[0].GetType() == typeof(EditorEventRef)) { pathProperty.stringValue = ((EditorEventRef)DragAndDrop.objectReferences[0]).Path; e.Use(); } } if (e.type == EventType.DragUpdated && position.Contains(e.mousePosition)) { if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] != null && DragAndDrop.objectReferences[0].GetType() == typeof(EditorEventRef)) { DragAndDrop.visualMode = DragAndDropVisualMode.Move; DragAndDrop.AcceptDrag(); e.Use(); } } float baseHeight = GUI.skin.textField.CalcSize(new GUIContent()).y; position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); GUIStyle buttonStyle = GUI.skin.button; buttonStyle.padding.top = 1; buttonStyle.padding.bottom = 1; Rect openRect = new Rect(position.x + position.width - openIcon.width - 15, position.y, openIcon.width + 10, baseHeight); Rect searchRect = new Rect(openRect.x - browseIcon.width - 15, position.y, browseIcon.width + 10, baseHeight); Rect pathRect = new Rect(position.x, position.y, searchRect.x - position.x - 5, baseHeight); EditorGUI.PropertyField(pathRect, pathProperty, GUIContent.none); if (GUI.Button(searchRect, new GUIContent(browseIcon, "Search"), buttonStyle)) { var eventBrowser = EventBrowser.CreateInstance <EventBrowser>(); eventBrowser.titleContent = new GUIContent("Select FMOD Event"); eventBrowser.SelectEvent(property); eventBrowser.ShowUtility(); } if (GUI.Button(openRect, new GUIContent(openIcon, "Open In FMOD Studio"), buttonStyle) && !String.IsNullOrEmpty(pathProperty.stringValue) && EventManager.EventFromPath(pathProperty.stringValue) != null ) { EditorEventRef eventRef = EventManager.EventFromPath(pathProperty.stringValue); string cmd = string.Format("studio.window.navigateTo(studio.project.lookup(\"{0}\"))", eventRef.Guid.ToString("b")); EditorUtils.SendScriptCommand(cmd); } if (!String.IsNullOrEmpty(pathProperty.stringValue) && EventManager.EventFromPath(pathProperty.stringValue) != null) { var style = new GUIStyle(GUI.skin.label); style.richText = true; EditorEventRef eventRef = EventManager.EventFromPath(pathProperty.stringValue); float width = style.CalcSize(new GUIContent("<b>Oneshot</b>")).x; Rect labelRect = new Rect(position.x, position.y + baseHeight, width, baseHeight); Rect valueRect = new Rect(position.x + width + 10, position.y + baseHeight, pathRect.width, baseHeight); GUI.Label(labelRect, new GUIContent("<b>GUID</b>"), style); EditorGUI.SelectableLabel(valueRect, eventRef.Guid.ToString("b")); labelRect.y += baseHeight; valueRect.y += baseHeight; GUI.Label(labelRect, new GUIContent("<b>Banks</b>"), style); StringBuilder builder = new StringBuilder(); eventRef.Banks.ForEach((x) => { builder.Append(Path.GetFileNameWithoutExtension(x.Path)); builder.Append(", "); }); GUI.Label(valueRect, builder.ToString(0, builder.Length - 2)); labelRect.y += baseHeight; valueRect.y += baseHeight; GUI.Label(labelRect, new GUIContent("<b>Panning</b>"), style); GUI.Label(valueRect, eventRef.Is3D ? "3D" : "2D"); labelRect.y += baseHeight; valueRect.y += baseHeight; GUI.Label(labelRect, new GUIContent("<b>Stream</b>"), style); GUI.Label(valueRect, eventRef.IsStream.ToString()); labelRect.y += baseHeight; valueRect.y += baseHeight; GUI.Label(labelRect, new GUIContent("<b>Oneshot</b>"), style); GUI.Label(valueRect, eventRef.IsOneShot.ToString()); labelRect.y += baseHeight; valueRect.y += baseHeight; } else { Rect labelRect = new Rect(position.x, position.y + baseHeight, position.width, baseHeight); GUI.Label(labelRect, new GUIContent("Event Not Found", EditorGUIUtility.Load("FMOD/NotFound.png") as Texture2D)); } EditorGUI.EndProperty(); }
public static void CopyToStreamingAssets() { FMODPlatform platform = RuntimeUtils.GetEditorFMODPlatform(); if (platform == FMODPlatform.None) { UnityEngine.Debug.LogWarning(String.Format("FMOD Studio: copy banks for platform {0} : Unsupported platform", EditorUserBuildSettings.activeBuildTarget.ToString())); return; } string bankTargetFolder = Settings.Instance.ImportType == ImportType.StreamingAssets ? Application.dataPath + "/FMOD/StreamingAssets" : Application.dataPath + "/" + Settings.Instance.TargetAssetPath; Directory.CreateDirectory(bankTargetFolder); string bankTargetExension = Settings.Instance.ImportType == ImportType.StreamingAssets ? "bank" : "bytes"; string bankSourceFolder = EditorUtils.GetBankDirectory() + "/" + Settings.Instance.GetBankPlatform(platform); if (Path.GetFullPath(bankTargetFolder).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).ToUpperInvariant() == Path.GetFullPath(bankSourceFolder).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).ToUpperInvariant()) { return; } bool madeChanges = false; try { // Clean out any stale .bank files string[] currentBankFiles = Directory.GetFiles(bankTargetFolder, "*." + bankTargetExension); foreach (var bankFileName in currentBankFiles) { string bankName = Path.GetFileNameWithoutExtension(bankFileName); if (!eventCache.EditorBanks.Exists((x) => bankName == x.Name)) { File.Delete(bankFileName); madeChanges = true; } } // Copy over any files that don't match timestamp or size or don't exist foreach (var bankRef in eventCache.EditorBanks) { string sourcePath = bankSourceFolder + "/" + bankRef.Name + ".bank"; string targetPath = bankTargetFolder + "/" + bankRef.Name + "." + bankTargetExension; FileInfo sourceInfo = new FileInfo(sourcePath); FileInfo targetInfo = new FileInfo(targetPath); if (!targetInfo.Exists || sourceInfo.Length != targetInfo.Length || sourceInfo.LastWriteTime != targetInfo.LastWriteTime) { File.Copy(sourcePath, targetPath, true); targetInfo = new FileInfo(targetPath); targetInfo.IsReadOnly = false; targetInfo.LastWriteTime = sourceInfo.LastWriteTime; madeChanges = true; } } } catch (Exception exception) { UnityEngine.Debug.LogError(String.Format("FMOD Studio: copy banks for platform {0} : copying banks from {1} to {2}", platform.ToString(), bankSourceFolder, bankTargetFolder)); UnityEngine.Debug.LogException(exception); return; } if (madeChanges) { AssetDatabase.Refresh(); UnityEngine.Debug.Log(String.Format("FMOD Studio: copy banks for platform {0} : copying banks from {1} to {2} succeeded", platform.ToString(), bankSourceFolder, bankTargetFolder)); } }
public void OnGUI(EditorEventRef selectedEvent) { AffirmResources(); var originalColour = GUI.color; if (!selectedEvent.Is3D) { GUI.color = new Color(1.0f, 1.0f, 1.0f, 0.1f); } GUILayout.Label(arena, GUILayout.ExpandWidth(false)); if (Event.current.type == EventType.Repaint) { arenaRect = GUILayoutUtility.GetLastRect(); } Vector2 center = arenaRect.center; Rect rect2 = new Rect(center.x + eventPosition.x - 6, center.y + eventPosition.y - 6, 12, 12); GUI.DrawTexture(rect2, emitter); GUI.color = originalColour; if (selectedEvent.Is3D) { bool useGUIEvent = false; switch (Event.current.type) { case EventType.MouseDown: if (arenaRect.Contains(Event.current.mousePosition)) { isDragging = true; useGUIEvent = true; } break; case EventType.MouseUp: if (isDragging) { isDragging = false; useGUIEvent = true; } break; case EventType.MouseDrag: if (isDragging) { useGUIEvent = true; } break; } if (useGUIEvent) { Vector2 newPosition = Event.current.mousePosition; Vector2 delta = newPosition - center; float maximumDistance = (arena.width - emitter.width) / 2; float distance = Math.Min(delta.magnitude, maximumDistance); delta.Normalize(); eventPosition = delta * distance; eventDistance = distance / maximumDistance * selectedEvent.MaxDistance; float angle = Mathf.Atan2(delta.y, delta.x); eventOrientation = angle + Mathf.PI * 0.5f; Event.current.Use(); } } EditorUtils.PreviewUpdatePosition(eventDistance, eventOrientation); }
static public void UpdateCache() { // Deserialize the cache from the unity resources if (eventCache == null) { eventCache = AssetDatabase.LoadAssetAtPath(CacheAssetFullName, typeof(EventCache)) as EventCache; if (eventCache == null || eventCache.cacheVersion != EventCache.CurrentCacheVersion) { UnityEngine.Debug.Log("FMOD Studio: Cannot find serialized event cache or cache in old format, creating new instance"); eventCache = ScriptableObject.CreateInstance <EventCache>(); eventCache.cacheVersion = EventCache.CurrentCacheVersion; Directory.CreateDirectory(Path.GetDirectoryName(CacheAssetFullName)); AssetDatabase.CreateAsset(eventCache, CacheAssetFullName); } } var settings = Settings.Instance; if (string.IsNullOrEmpty(settings.SourceBankPath)) { ClearCache(); return; } string defaultBankFolder = null; if (!settings.HasPlatforms) { defaultBankFolder = settings.SourceBankPath; } else { Platform platform = settings.CurrentEditorPlatform; if (platform == settings.DefaultPlatform) { platform = settings.PlayInEditorPlatform; } defaultBankFolder = RuntimeUtils.GetCommonPlatformPath(Path.Combine(settings.SourceBankPath, platform.BuildDirectory)); } string[] bankPlatforms = EditorUtils.GetBankPlatforms(); string[] bankFolders = new string[bankPlatforms.Length]; for (int i = 0; i < bankPlatforms.Length; i++) { bankFolders[i] = RuntimeUtils.GetCommonPlatformPath(Path.Combine(settings.SourceBankPath, bankPlatforms[i])); } List <string> stringBanks = new List <string>(0); try { var files = Directory.GetFiles(defaultBankFolder, "*." + StringBankExtension, SearchOption.AllDirectories); stringBanks = new List <string>(files); } catch { } // Strip out OSX resource-fork files that appear on FAT32 stringBanks.RemoveAll((x) => Path.GetFileName(x).StartsWith("._")); if (stringBanks.Count == 0) { bool wasValid = eventCache.StringsBankWriteTime != DateTime.MinValue; ClearCache(); if (wasValid) { UnityEngine.Debug.LogError(string.Format("FMOD Studio: Directory {0} doesn't contain any banks. Build the banks in Studio or check the path in the settings.", defaultBankFolder)); } return; } // If we have multiple .strings.bank files find the most recent stringBanks.Sort((a, b) => File.GetLastWriteTime(b).CompareTo(File.GetLastWriteTime(a))); // Use the most recent string bank timestamp as a marker for the most recent build of any bank because it gets exported every time DateTime lastWriteTime = File.GetLastWriteTime(stringBanks[0]); if (lastWriteTime == eventCache.StringsBankWriteTime) { countdownTimer = CountdownTimerReset; return; } if (EditorUtils.IsFileOpenByStudio(stringBanks[0])) { countdownTimer = CountdownTimerReset; return; } // Most recent strings bank is newer than last cache update time, recache. // Get a list of all banks List <string> bankFileNames = new List <string>(); List <string> reducedStringBanksList = new List <string>(); HashSet <Guid> stringBankGuids = new HashSet <Guid>(); foreach (string stringBankPath in stringBanks) { FMOD.Studio.Bank stringBank; EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank)); if (!stringBank.isValid()) { countdownTimer = CountdownTimerReset; return; } else { // Unload the strings bank stringBank.unload(); } Guid stringBankGuid; EditorUtils.CheckResult(stringBank.getID(out stringBankGuid)); if (!stringBankGuids.Add(stringBankGuid)) { // If we encounter multiple string banks with the same GUID then only use the first. This handles the scenario where // a Studio project is cloned and extended for DLC with a new master bank name. continue; } reducedStringBanksList.Add(stringBankPath); } bankFileNames = new List <string>(Directory.GetFiles(defaultBankFolder, "*.bank", SearchOption.AllDirectories)); bankFileNames.RemoveAll(x => x.Contains(".strings")); stringBanks = reducedStringBanksList; if (!UnityEditorInternal.InternalEditorUtility.inBatchMode) { // Check if any of the files are still being written by studio foreach (string bankFileName in bankFileNames) { EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => RuntimeUtils.GetCommonPlatformPath(bankFileName) == x.Path); if (bankRef == null) { if (EditorUtils.IsFileOpenByStudio(bankFileName)) { countdownTimer = CountdownTimerReset; return; } continue; } if (bankRef.LastModified != File.GetLastWriteTime(bankFileName)) { if (EditorUtils.IsFileOpenByStudio(bankFileName)) { countdownTimer = CountdownTimerReset; return; } } } // Count down the timer in case we catch studio in-between updating two files. if (countdownTimer-- > 0) { return; } } eventCache.StringsBankWriteTime = lastWriteTime; // All files are finished being modified by studio so update the cache // Stop editor preview so no stale data being held EditorUtils.PreviewStop(); // Reload the strings banks List <FMOD.Studio.Bank> loadedStringsBanks = new List <FMOD.Studio.Bank>(); try { AssetDatabase.StartAssetEditing(); eventCache.EditorBanks.ForEach((x) => x.Exists = false); HashSet <string> masterBankFileNames = new HashSet <string>(); foreach (string stringBankPath in stringBanks) { FMOD.Studio.Bank stringBank; EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank)); if (!stringBank.isValid()) { ClearCache(); return; } loadedStringsBanks.Add(stringBank); FileInfo stringBankFileInfo = new FileInfo(stringBankPath); string masterBankFileName = Path.GetFileName(stringBankPath).Replace(StringBankExtension, BankExtension); masterBankFileNames.Add(masterBankFileName); EditorBankRef stringsBankRef = eventCache.StringsBanks.Find(x => RuntimeUtils.GetCommonPlatformPath(stringBankPath) == x.Path); if (stringsBankRef == null) { stringsBankRef = ScriptableObject.CreateInstance <EditorBankRef>(); stringsBankRef.FileSizes = new List <EditorBankRef.NameValuePair>(); AssetDatabase.AddObjectToAsset(stringsBankRef, eventCache); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(stringsBankRef)); eventCache.EditorBanks.Add(stringsBankRef); eventCache.StringsBanks.Add(stringsBankRef); } stringsBankRef.SetPath(stringBankPath, defaultBankFolder); string studioPath; stringBank.getPath(out studioPath); stringsBankRef.SetStudioPath(studioPath); stringsBankRef.LastModified = stringBankFileInfo.LastWriteTime; stringsBankRef.Exists = true; stringsBankRef.FileSizes.Clear(); if (Settings.Instance.HasPlatforms) { for (int i = 0; i < bankPlatforms.Length; i++) { stringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], stringBankFileInfo.Length)); } } else { stringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", stringBankFileInfo.Length)); } } eventCache.EditorParameters.ForEach((x) => x.Exists = false); foreach (string bankFileName in bankFileNames) { EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => RuntimeUtils.GetCommonPlatformPath(bankFileName) == x.Path); // New bank we've never seen before if (bankRef == null) { bankRef = ScriptableObject.CreateInstance <EditorBankRef>(); AssetDatabase.AddObjectToAsset(bankRef, eventCache); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(bankRef)); bankRef.SetPath(bankFileName, defaultBankFolder); bankRef.LastModified = DateTime.MinValue; bankRef.FileSizes = new List <EditorBankRef.NameValuePair>(); eventCache.EditorBanks.Add(bankRef); } bankRef.Exists = true; FileInfo bankFileInfo = new FileInfo(bankFileName); // Timestamp check - if it doesn't match update events from that bank if (bankRef.LastModified != bankFileInfo.LastWriteTime) { bankRef.LastModified = bankFileInfo.LastWriteTime; UpdateCacheBank(bankRef); } // Update file sizes bankRef.FileSizes.Clear(); if (Settings.Instance.HasPlatforms) { for (int i = 0; i < bankPlatforms.Length; i++) { string platformBankPath = RuntimeUtils.GetCommonPlatformPath(Path.Combine(bankFolders[i], bankFileName)); var fileInfo = new FileInfo(platformBankPath); if (fileInfo.Exists) { bankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], fileInfo.Length)); } } } else { string platformBankPath = RuntimeUtils.GetCommonPlatformPath(Path.Combine(Settings.Instance.SourceBankPath, bankFileName)); var fileInfo = new FileInfo(platformBankPath); if (fileInfo.Exists) { bankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", fileInfo.Length)); } } if (masterBankFileNames.Contains(bankFileInfo.Name)) { if (!eventCache.MasterBanks.Exists(x => RuntimeUtils.GetCommonPlatformPath(bankFileName) == x.Path)) { eventCache.MasterBanks.Add(bankRef); } } } // Remove any stale entries from bank, event and parameter lists eventCache.EditorBanks.FindAll((x) => !x.Exists).ForEach(RemoveCacheBank); eventCache.EditorBanks.RemoveAll((x) => !x.Exists); eventCache.EditorEvents.RemoveAll((x) => x.Banks.Count == 0); eventCache.EditorParameters.RemoveAll((x) => !x.Exists); eventCache.MasterBanks.RemoveAll((x) => !x.Exists); eventCache.StringsBanks.RemoveAll((x) => !x.Exists); } finally { // Unload the strings banks loadedStringsBanks.ForEach(x => x.unload()); AssetDatabase.StopAssetEditing(); Debug.Log("[FMOD] Cache Updated."); } }
static public void UpdateCache() { // Deserialize the cache from the unity resources if (eventCache == null) { eventCache = AssetDatabase.LoadAssetAtPath(CacheAssetFullName, typeof(EventCache)) as EventCache; if (eventCache == null) { UnityEngine.Debug.Log("FMOD Studio: Cannot find serialized event cache, creating new instance"); eventCache = ScriptableObject.CreateInstance <EventCache>(); AssetDatabase.CreateAsset(eventCache, CacheAssetFullName); } } if (EditorUtils.GetBankDirectory() == null) { ClearCache(); return; } string defaultBankFolder = null; if (!Settings.Instance.HasPlatforms) { defaultBankFolder = EditorUtils.GetBankDirectory(); } else { defaultBankFolder = Path.Combine(EditorUtils.GetBankDirectory(), Settings.Instance.GetBankPlatform(FMODPlatform.PlayInEditor)); } string[] bankPlatforms = EditorUtils.GetBankPlatforms(); string[] bankFolders = new string[bankPlatforms.Length]; for (int i = 0; i < bankPlatforms.Length; i++) { bankFolders[i] = Path.Combine(EditorUtils.GetBankDirectory(), bankPlatforms[i]); } List <String> stringBanks = new List <string>(0); try { var files = Directory.GetFiles(defaultBankFolder, "*." + StringBankExtension); stringBanks = new List <string>(files); } catch { UnityEngine.Debug.LogWarning(String.Format("FMOD Studio: Directory {0} doesn't exist. Build from the tool or check the path in the settings", defaultBankFolder)); } // Strip out OSX resource-fork files that appear on FAT32 stringBanks.RemoveAll((x) => Path.GetFileName(x).StartsWith("._")); if (stringBanks.Count == 0) { ClearCache(); if (eventCache.StringsBankWriteTime != DateTime.MinValue) { UnityEngine.Debug.LogWarning(String.Format("FMOD Studio: Directory {0} doesn't contain any banks. Build from the tool or check the path in the settings", defaultBankFolder)); } return; } // If we have multiple .strings.bank files find the most recent stringBanks.Sort((a, b) => File.GetLastWriteTime(b).CompareTo(File.GetLastWriteTime(a))); string stringBankPath = stringBanks[0]; // Use the string bank timestamp as a marker for the most recent build of any bank because it gets exported every time if (File.GetLastWriteTime(stringBankPath) <= eventCache.StringsBankWriteTime) { return; } eventCache.StringsBankWriteTime = File.GetLastWriteTime(stringBankPath); string masterBankFileName = Path.GetFileName(stringBankPath).Replace(StringBankExtension, BankExtension); FMOD.Studio.Bank stringBank = null; EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank)); if (stringBank == null) { ClearCache(); return; } // Iterate every string in the strings bank and look for any that identify banks int stringCount; stringBank.getStringCount(out stringCount); List <string> bankFileNames = new List <string>(); for (int stringIndex = 0; stringIndex < stringCount; stringIndex++) { string currentString; Guid currentGuid; stringBank.getStringInfo(stringIndex, out currentGuid, out currentString); const string BankPrefix = "bank:/"; int BankPrefixLength = BankPrefix.Length; if (currentString.StartsWith(BankPrefix)) { string bankFileName = currentString.Substring(BankPrefixLength) + "." + BankExtension; if (!bankFileName.Contains(StringBankExtension)) // filter out the strings bank { bankFileNames.Add(bankFileName); } } } eventCache.EditorBanks.ForEach((x) => x.Exists = false); foreach (string bankFileName in bankFileNames) { string bankPath = Path.Combine(defaultBankFolder, bankFileName); if (!File.Exists(bankPath)) { // If bank files are missing we might be in the middle of a build. // Force the cache to be stale until all the files appear eventCache.StringsBankWriteTime = DateTime.MinValue; continue; } EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => bankPath == x.Path); // New bank we've never seen before if (bankRef == null) { bankRef = ScriptableObject.CreateInstance <EditorBankRef>(); AssetDatabase.AddObjectToAsset(bankRef, eventCache); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(bankRef)); bankRef.Path = bankPath; bankRef.LastModified = DateTime.MinValue; bankRef.FileSizes = new List <EditorBankRef.NameValuePair>(); eventCache.EditorBanks.Add(bankRef); } bankRef.Exists = true; // Timestamp check - if it doesn't match update events from that bank if (bankRef.LastModified != File.GetLastWriteTime(bankPath)) { bankRef.LastModified = File.GetLastWriteTime(bankPath); UpdateCacheBank(bankRef); } // Update file sizes bankRef.FileSizes.Clear(); for (int i = 0; i < bankPlatforms.Length; i++) { string platformBankPath = Path.Combine(bankFolders[i], bankFileName); var fileInfo = new FileInfo(platformBankPath); if (fileInfo.Exists) { bankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], fileInfo.Length)); } } if (bankFileName == masterBankFileName) { eventCache.MasterBankRef = bankRef; } } // Unload the strings bank stringBank.unload(); // Remove any stale entries from bank and event lists eventCache.EditorBanks.FindAll((x) => !x.Exists).ForEach(RemoveCacheBank); eventCache.EditorBanks.RemoveAll((x) => !x.Exists); eventCache.EditorEvents.RemoveAll((x) => x.Banks.Count == 0); OnCacheChange(); }
public override void OnInspectorGUI() { var load = serializedObject.FindProperty("LoadEvent"); var unload = serializedObject.FindProperty("UnloadEvent"); var tag = serializedObject.FindProperty("CollisionTag"); var banks = serializedObject.FindProperty("Banks"); var preload = serializedObject.FindProperty("PreloadSamples"); EditorGUILayout.PropertyField(load, new GUIContent("Load")); EditorGUILayout.PropertyField(unload, new GUIContent("Unload")); if ((load.enumValueIndex >= 3 && load.enumValueIndex <= 6) || (unload.enumValueIndex >= 3 && unload.enumValueIndex <= 6)) { tag.stringValue = EditorGUILayout.TagField("Collision Tag", tag.stringValue); } EditorGUILayout.PropertyField(preload, new GUIContent("Preload Sample Data")); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Banks"); EditorGUILayout.BeginVertical(); if (GUILayout.Button("Add Bank", GUILayout.ExpandWidth(false))) { banks.InsertArrayElementAtIndex(banks.arraySize); SerializedProperty newBank = banks.GetArrayElementAtIndex(banks.arraySize - 1); newBank.stringValue = ""; EventBrowser browser = CreateInstance <EventBrowser>(); browser.titleContent = new GUIContent("Select FMOD Bank"); browser.ChooseBank(newBank); browser.ShowUtility(); } Texture deleteTexture = EditorUtils.LoadImage("Delete.png"); GUIContent deleteContent = new GUIContent(deleteTexture, "Delete Bank"); var buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.padding.top = buttonStyle.padding.bottom = 1; buttonStyle.margin.top = 2; buttonStyle.padding.left = buttonStyle.padding.right = 4; buttonStyle.fixedHeight = GUI.skin.textField.CalcSize(new GUIContent()).y; for (int i = 0; i < banks.arraySize; i++) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(banks.GetArrayElementAtIndex(i), GUIContent.none); if (GUILayout.Button(deleteContent, buttonStyle, GUILayout.ExpandWidth(false))) { banks.DeleteArrayElementAtIndex(i); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); Event e = Event.current; if (e.type == EventType.DragPerform) { if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] != null && DragAndDrop.objectReferences[0].GetType() == typeof(EditorBankRef)) { int pos = banks.arraySize; banks.InsertArrayElementAtIndex(pos); var pathProperty = banks.GetArrayElementAtIndex(pos); pathProperty.stringValue = ((EditorBankRef)DragAndDrop.objectReferences[0]).Name; e.Use(); } } if (e.type == EventType.DragUpdated) { if (DragAndDrop.objectReferences.Length > 0 && DragAndDrop.objectReferences[0] != null && DragAndDrop.objectReferences[0].GetType() == typeof(EditorBankRef)) { DragAndDrop.visualMode = DragAndDropVisualMode.Move; DragAndDrop.AcceptDrag(); e.Use(); } } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { Settings settings = target as Settings; EditorGUI.BeginChangeCheck(); hasBankSourceChanged = false; bool hasBankTargetChanged = false; GUIStyle style = new GUIStyle(GUI.skin.label); style.richText = true; GUI.skin.FindStyle("HelpBox").richText = true; SourceType sourceType = settings.HasSourceProject ? SourceType.Project : (settings.HasPlatforms ? SourceType.Multi : SourceType.Single); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); sourceType = GUILayout.Toggle(sourceType == SourceType.Project, "Project", "Button") ? 0 : sourceType; sourceType = GUILayout.Toggle(sourceType == SourceType.Single, "Single Platform Build", "Button") ? SourceType.Single : sourceType; sourceType = GUILayout.Toggle(sourceType == SourceType.Multi, "Multiple Platform Build", "Button") ? SourceType.Multi : sourceType; EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.HelpBox( "<size=11>Select the way you wish to connect Unity to the FMOD Studio content:\n" + "<b>• Project</b>\t\tIf you have the complete FMOD Studio project avaliable\n" + "<b>• Single Platform</b>\tIf you have only the contents of the <i>Build</i> folder for a single platform\n" + "<b>• Multiple Platforms</b>\tIf you have only the contents of the <i>Build</i> folder for multiple platforms, each platform in it's own sub directory\n" + "</size>" , MessageType.Info, true); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (sourceType == SourceType.Project) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceProjectPath; EditorGUILayout.PrefixLabel("Studio Project Path", GUI.skin.textField, style); EditorGUI.BeginChangeCheck(); string newPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceProjectPath); if (EditorGUI.EndChangeCheck()) { if (newPath.EndsWith(".fspro")) { settings.SourceProjectPath = newPath; } } if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string path = EditorUtility.OpenFilePanel("Locate Studio Project", oldPath, "fspro"); if (!string.IsNullOrEmpty(path)) { settings.SourceProjectPath = MakePathRelative(path); Repaint(); } } EditorGUILayout.EndHorizontal(); // Cache in settings for runtime access in play-in-editor mode string bankPath = EditorUtils.GetBankDirectory(); settings.SourceBankPath = bankPath; settings.HasPlatforms = true; settings.HasSourceProject = true; // First time project path is set or changes, copy to streaming assets if (settings.SourceProjectPath != oldPath) { hasBankSourceChanged = true; } } if (sourceType == SourceType.Single || sourceType == SourceType.Multi) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceBankPath; EditorGUILayout.PrefixLabel("Build Path", GUI.skin.textField, style); EditorGUI.BeginChangeCheck(); string tempPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceBankPath); if (EditorGUI.EndChangeCheck()) { settings.SourceBankPath = tempPath; } if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string newPath = EditorUtility.OpenFolderPanel("Locate Build Folder", oldPath, null); if (!string.IsNullOrEmpty(newPath)) { settings.SourceBankPath = MakePathRelative(newPath); Repaint(); } } EditorGUILayout.EndHorizontal(); settings.HasPlatforms = (sourceType == SourceType.Multi); settings.HasSourceProject = false; // First time project path is set or changes, copy to streaming assets if (settings.SourceBankPath != oldPath) { hasBankSourceChanged = true; } } bool validBanks; string failReason; EditorUtils.ValidateSource(out validBanks, out failReason); if (!validBanks) { EditorGUILayout.HelpBox(failReason, MessageType.Error, true); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } return; } ImportType importType = (ImportType)EditorGUILayout.EnumPopup("Import Type", settings.ImportType); if (importType != settings.ImportType) { hasBankTargetChanged = true; settings.ImportType = importType; } // ----- Text Assets ------------- if (settings.ImportType == ImportType.AssetBundle) { GUI.SetNextControlName("targetAssetPath"); targetAssetPath = EditorGUILayout.TextField("FMOD Asset Folder", string.IsNullOrEmpty(targetAssetPath) ? settings.TargetAssetPath : targetAssetPath); if (GUI.GetNameOfFocusedControl() == "targetAssetPath") { focused = true; if (Event.current.isKey) { switch (Event.current.keyCode) { case KeyCode.Return: case KeyCode.KeypadEnter: settings.TargetAssetPath = targetAssetPath; hasBankTargetChanged = true; break; } } } else if (focused) { settings.TargetAssetPath = targetAssetPath; hasBankTargetChanged = true; focused = false; } } // ----- Logging ----------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Logging</b>", style); EditorGUI.indentLevel++; settings.LoggingLevel = (FMOD.DEBUG_FLAGS)EditorGUILayout.EnumPopup("Logging Level", settings.LoggingLevel); EditorGUI.indentLevel--; // ----- Loading ----------------- EditorGUI.BeginDisabledGroup(settings.ImportType == ImportType.AssetBundle); EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Initialization</b>", style); EditorGUI.indentLevel++; settings.BankLoadType = (BankLoadType)EditorGUILayout.EnumPopup("Load Banks", settings.BankLoadType); switch (settings.BankLoadType) { case BankLoadType.All: break; case BankLoadType.Specified: settings.AutomaticEventLoading = false; Texture upArrowTexture = EditorGUIUtility.Load("FMOD/ArrowUp.png") as Texture; Texture downArrowTexture = EditorGUIUtility.Load("FMOD/ArrowDown.png") as Texture; bankFoldOutState = EditorGUILayout.Foldout(bankFoldOutState, "Specified Banks", true); if (bankFoldOutState) { for (int i = 0; i < settings.BanksToLoad.Count; i++) { EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel++; var bankName = settings.BanksToLoad[i]; EditorGUILayout.TextField(bankName.Replace(".bank", "")); if (GUILayout.Button(upArrowTexture, GUILayout.ExpandWidth(false))) { if (i > 0) { var temp = settings.BanksToLoad[i]; settings.BanksToLoad[i] = settings.BanksToLoad[i - 1]; settings.BanksToLoad[i - 1] = temp; } continue; } if (GUILayout.Button(downArrowTexture, GUILayout.ExpandWidth(false))) { if (i < settings.BanksToLoad.Count - 1) { var temp = settings.BanksToLoad[i]; settings.BanksToLoad[i] = settings.BanksToLoad[i + 1]; settings.BanksToLoad[i + 1] = temp; } continue; } if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string path = EditorUtility.OpenFilePanel("Locate Bank", Application.streamingAssetsPath, "bank"); if (!string.IsNullOrEmpty(path)) { settings.BanksToLoad[i] = path.Replace(Application.streamingAssetsPath + Path.AltDirectorySeparatorChar, ""); Repaint(); } } if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false))) { Settings.Instance.BanksToLoad.RemoveAt(i); continue; } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; } GUILayout.BeginHorizontal(); GUILayout.Space(30); if (GUILayout.Button("Add Bank", GUILayout.ExpandWidth(false))) { settings.BanksToLoad.Add(""); } if (GUILayout.Button("Add All Banks", GUILayout.ExpandWidth(false))) { FMODPlatform platform = RuntimeUtils.GetEditorFMODPlatform(); if (platform == FMODPlatform.None) { platform = FMODPlatform.PlayInEditor; } string sourceDir = RuntimeUtils.GetCommonPlatformPath(settings.SourceBankPath + '/' + (settings.HasSourceProject ? settings.GetBankPlatform(platform) + '/' : "")); var banksFound = new List <string>(Directory.GetFiles(sourceDir, "*.bank", SearchOption.AllDirectories)); for (int i = 0; i < banksFound.Count; i++) { string bankShortName = RuntimeUtils.GetCommonPlatformPath(Path.GetFullPath(banksFound[i])).Replace(sourceDir, ""); if (!settings.BanksToLoad.Contains(bankShortName)) { settings.BanksToLoad.Add(bankShortName); } } Repaint(); } if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false))) { settings.BanksToLoad.Clear(); } GUILayout.EndHorizontal(); } break; case BankLoadType.None: settings.AutomaticEventLoading = false; break; default: break; } EditorGUI.BeginDisabledGroup(settings.BankLoadType == BankLoadType.None); settings.AutomaticSampleLoading = EditorGUILayout.Toggle("Load Bank Sample Data", settings.AutomaticSampleLoading); EditorGUI.EndDisabledGroup(); settings.EncryptionKey = EditorGUILayout.TextField("Bank Encryption Key", settings.EncryptionKey); EditorGUI.indentLevel--; EditorGUI.EndDisabledGroup(); // ----- PIE ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Play In Editor Settings</b>", style); EditorGUI.indentLevel++; DisplayEditorBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.PlayInEditor); if (settings.IsLiveUpdateEnabled(FMODPlatform.PlayInEditor)) { EditorGUILayout.BeginHorizontal(); settings.LiveUpdatePort = ushort.Parse(EditorGUILayout.TextField("Live Update Port:", settings.LiveUpdatePort.ToString())); if (GUILayout.Button("Reset", GUILayout.ExpandWidth(false))) { settings.LiveUpdatePort = 9264; } EditorGUILayout.EndHorizontal(); } DisplayEditorBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.PlayInEditor); DisplayChildFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { DisplayPIEBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.PlayInEditor); } DisplayPIESpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(string.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.PlayInEditor)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } EditorGUI.indentLevel--; // ----- Default ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Default Settings</b>", style); EditorGUI.indentLevel++; DisplayParentBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.Default); if (settings.IsLiveUpdateEnabled(FMODPlatform.Default)) { EditorGUILayout.BeginHorizontal(); settings.LiveUpdatePort = ushort.Parse(EditorGUILayout.TextField("Live Update Port:", settings.LiveUpdatePort.ToString())); if (GUILayout.Button("Reset", GUILayout.ExpandWidth(false))) { settings.LiveUpdatePort = 9264; } EditorGUILayout.EndHorizontal(); } DisplayParentBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.Default); DisplayParentFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.Default); if (settings.HasPlatforms) { bool prevChanged = GUI.changed; DisplayParentBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.Default); hasBankSourceChanged |= !prevChanged && GUI.changed; } DisplayParentSpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.Default); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(string.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.Default)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } DisplayParentInt("Virtual Channel Count", settings.VirtualChannelSettings, FMODPlatform.Default, 1, 2048); DisplayParentInt("Real Channel Count", settings.RealChannelSettings, FMODPlatform.Default, 1, 256); EditorGUI.indentLevel--; // ----- Plugins ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Plugins</b>", GUI.skin.button, style); if (GUILayout.Button("Add Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.Add(""); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel++; for (int count = 0; count < settings.Plugins.Count; count++) { EditorGUILayout.BeginHorizontal(); settings.Plugins[count] = EditorGUILayout.TextField("Plugin " + (count + 1).ToString() + ":", settings.Plugins[count]); if (GUILayout.Button("Delete Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.RemoveAt(count); } EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; // ----- Windows ---------------------------------------------- DisplayPlatform(FMODPlatform.Desktop, null); DisplayPlatform(FMODPlatform.Mobile, new FMODPlatform[] { FMODPlatform.MobileHigh, FMODPlatform.MobileLow, FMODPlatform.AppleTV }); DisplayPlatform(FMODPlatform.Console, new FMODPlatform[] { FMODPlatform.XboxOne, FMODPlatform.PS4, FMODPlatform.Switch, FMODPlatform.Stadia }); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } if (hasBankSourceChanged) { EventManager.RefreshBanks(); } if (hasBankTargetChanged) { EventManager.RefreshBanks(); } }
public override void OnInspectorGUI() { Settings settings = target as Settings; EditorGUI.BeginChangeCheck(); hasBankSourceChanged = false; bool hasBankTargetChanged = false; GUIStyle style = new GUIStyle(GUI.skin.label); style.richText = true; GUI.skin.FindStyle("HelpBox").richText = true; SourceType sourceType = settings.HasSourceProject ? SourceType.Project : (settings.HasPlatforms ? SourceType.Multi : SourceType.Single); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); sourceType = GUILayout.Toggle(sourceType == SourceType.Project, "Project", "Button") ? 0 : sourceType; sourceType = GUILayout.Toggle(sourceType == SourceType.Single, "Single Platform Build", "Button") ? SourceType.Single : sourceType; sourceType = GUILayout.Toggle(sourceType == SourceType.Multi, "Multiple Platform Build", "Button") ? SourceType.Multi : sourceType; EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.HelpBox( "<size=11>Select the way you wish to connect Unity to the FMOD Studio content:\n" + "<b>• Project</b>\t\tIf you have the complete FMOD Studio project avaliable\n" + "<b>• Single Platform</b>\tIf you have only the contents of the <i>Build</i> folder for a single platform\n" + "<b>• Multiple Platforms</b>\tIf you have only the contents of the <i>Build</i> folder for multiple platforms, each platform in it's own sub directory\n" + "</size>" , MessageType.Info, true); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (sourceType == SourceType.Project) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceProjectPath; EditorGUILayout.PrefixLabel("Studio Project Path", GUI.skin.textField, style); EditorGUI.BeginChangeCheck(); string newPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceProjectPath); if (EditorGUI.EndChangeCheck()) { if (newPath.EndsWith(".fspro")) { settings.SourceProjectPath = newPath; } } if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string path = EditorUtility.OpenFilePanel("Locate Studio Project", oldPath, "fspro"); if (!String.IsNullOrEmpty(path)) { settings.SourceProjectPath = MakePathRelative(path); this.Repaint(); } } EditorGUILayout.EndHorizontal(); // Cache in settings for runtime access in play-in-editor mode string bankPath = EditorUtils.GetBankDirectory(); settings.SourceBankPath = bankPath; settings.HasPlatforms = true; settings.HasSourceProject = true; // First time project path is set or changes, copy to streaming assets if (settings.SourceProjectPath != oldPath) { hasBankSourceChanged = true; } } if (sourceType == SourceType.Single || sourceType == SourceType.Multi) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceBankPath; EditorGUILayout.PrefixLabel("Build Path", GUI.skin.textField, style); EditorGUI.BeginChangeCheck(); string newPath = EditorGUILayout.TextField(GUIContent.none, settings.SourceBankPath); if (EditorGUI.EndChangeCheck()) { settings.SourceBankPath = newPath; } if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); var path = EditorUtility.OpenFolderPanel("Locate Build Folder", oldPath, null); if (!String.IsNullOrEmpty(path)) { path = MakePathRelative(path); settings.SourceBankPath = path; } } EditorGUILayout.EndHorizontal(); settings.HasPlatforms = (sourceType == SourceType.Multi); settings.HasSourceProject = false; // First time project path is set or changes, copy to streaming assets if (settings.SourceBankPath != oldPath) { hasBankSourceChanged = true; } } bool validBanks; string failReason; EditorUtils.ValidateSource(out validBanks, out failReason); if (!validBanks) { EditorGUILayout.HelpBox(failReason, MessageType.Error, true); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } return; } ImportType importType = (ImportType)EditorGUILayout.EnumPopup("Import Type", settings.ImportType); if (importType != settings.ImportType) { hasBankTargetChanged = true; settings.ImportType = importType; bool deleteBanks = EditorUtility.DisplayDialog( "FMOD Bank Import Type Changed", "Do you want to delete the " + (importType == ImportType.AssetBundle ? "StreamingAssets" : "AssetBundle") + " banks in " + (importType == ImportType.AssetBundle ? Application.streamingAssetsPath : Application.dataPath + '/' + settings.TargetAssetPath) , "Yes", "No"); if (deleteBanks) { // Delete the old banks EventManager.removeBanks = true; EventManager.RefreshBanks(); } } // ----- Text Assets ------------- if (settings.ImportType == ImportType.AssetBundle) { GUI.SetNextControlName("targetAssetPath"); targetAssetPath = EditorGUILayout.TextField("FMOD Asset Folder", string.IsNullOrEmpty(targetAssetPath) ? settings.TargetAssetPath : targetAssetPath); if (GUI.GetNameOfFocusedControl() == "targetAssetPath") { focused = true; if (Event.current.isKey) { switch (Event.current.keyCode) { case KeyCode.Return: case KeyCode.KeypadEnter: settings.TargetAssetPath = targetAssetPath; hasBankTargetChanged = true; break; } } } else if (focused) { settings.TargetAssetPath = targetAssetPath; hasBankTargetChanged = true; focused = false; } } // ----- Logging ----------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Logging</b>", style); EditorGUI.indentLevel++; settings.LoggingLevel = (FMOD.DEBUG_FLAGS)EditorGUILayout.EnumPopup("Logging Level", settings.LoggingLevel); EditorGUI.indentLevel--; // ----- Loading ----------------- EditorGUI.BeginDisabledGroup(settings.ImportType == ImportType.AssetBundle); EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Loading</b>", style); EditorGUI.indentLevel++; settings.AutomaticEventLoading = EditorGUILayout.Toggle("Load All Event Data at Initialization", settings.AutomaticEventLoading); EditorGUI.BeginDisabledGroup(!settings.AutomaticEventLoading); settings.AutomaticSampleLoading = EditorGUILayout.Toggle("Load All Sample Data at Initialization", settings.AutomaticSampleLoading); EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel--; EditorGUI.EndDisabledGroup(); // ----- PIE ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Play In Editor Settings</b>", style); EditorGUI.indentLevel++; DisplayEditorBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.PlayInEditor); if (settings.IsLiveUpdateEnabled(FMODPlatform.PlayInEditor)) { EditorGUILayout.BeginHorizontal(); settings.LiveUpdatePort = ushort.Parse(EditorGUILayout.TextField("Live Update Port:", settings.LiveUpdatePort.ToString())); if (GUILayout.Button("Reset", GUILayout.ExpandWidth(false))) { #if UNITY_5_0 || UNITY_5_1 settings.LiveUpdatePort = 9265; #else settings.LiveUpdatePort = 9264; #endif } EditorGUILayout.EndHorizontal(); #if UNITY_5_0 || UNITY_5_1 EditorGUILayout.HelpBox("Unity 5.0 or 5.1 detected: Live update will not be able to use port <b>9264</b>", MessageType.Warning, false); #endif } DisplayEditorBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.PlayInEditor); DisplayChildFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { DisplayPIEBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.PlayInEditor); } DisplayPIESpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(String.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.PlayInEditor)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } EditorGUI.indentLevel--; // ----- Default ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Default Settings</b>", style); EditorGUI.indentLevel++; DisplayParentBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.Default); if (settings.IsLiveUpdateEnabled(FMODPlatform.Default)) { #if UNITY_5_0 || UNITY_5_1 EditorGUILayout.HelpBox("Unity 5.0 or 5.1 detected: Live update will listen on port <b>9265</b>", MessageType.Warning, false); #else EditorGUILayout.HelpBox("Live update will listen on port <b>9264</b>", MessageType.Info, false); #endif } DisplayParentBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.Default); DisplayParentFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.Default); if (settings.HasPlatforms) { bool prevChanged = GUI.changed; DisplayParentBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.Default); hasBankSourceChanged |= !prevChanged && GUI.changed; } DisplayParentSpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.Default); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(String.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.Default)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } DisplayParentInt("Virtual Channel Count", settings.VirtualChannelSettings, FMODPlatform.Default, 1, 2048); DisplayParentInt("Real Channel Count", settings.RealChannelSettings, FMODPlatform.Default, 1, 256); EditorGUI.indentLevel--; // ----- Plugins ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Plugins</b>", GUI.skin.button, style); if (GUILayout.Button("Add Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.Add(""); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel++; for (int count = 0; count < settings.Plugins.Count; count++) { EditorGUILayout.BeginHorizontal(); settings.Plugins[count] = EditorGUILayout.TextField("Plugin " + (count + 1).ToString() + ":", settings.Plugins[count]); if (GUILayout.Button("Delete Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.RemoveAt(count); } EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; // ----- Windows ---------------------------------------------- DisplayPlatform(FMODPlatform.Desktop, null); DisplayPlatform(FMODPlatform.Mobile, new FMODPlatform[] { FMODPlatform.MobileHigh, FMODPlatform.MobileLow, FMODPlatform.PSVita, FMODPlatform.AppleTV }); DisplayPlatform(FMODPlatform.Console, new FMODPlatform[] { FMODPlatform.XboxOne, FMODPlatform.PS4, FMODPlatform.WiiU, FMODPlatform.Stadia }); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } if (hasBankSourceChanged) { EventManager.UpdateCache(); } if (hasBankTargetChanged) { EventManager.CopyToStreamingAssets(); } }
static public void UpdateCache() { // Deserialize the cache from the unity resources if (eventCache == null) { eventCache = AssetDatabase.LoadAssetAtPath(CacheAssetFullName, typeof(EventCache)) as EventCache; if (eventCache == null || eventCache.cacheVersion != EventCache.CurrentCacheVersion) { UnityEngine.Debug.Log("FMOD Studio: Cannot find serialized event cache or cache in old format, creating new instance"); eventCache = ScriptableObject.CreateInstance <EventCache>(); eventCache.cacheVersion = EventCache.CurrentCacheVersion; AssetDatabase.CreateAsset(eventCache, CacheAssetFullName); } } if (EditorUtils.GetBankDirectory() == null) { ClearCache(); return; } string defaultBankFolder = null; if (!Settings.Instance.HasPlatforms) { defaultBankFolder = EditorUtils.GetBankDirectory(); } else { FMODPlatform platform = RuntimeUtils.GetEditorFMODPlatform(); if (platform == FMODPlatform.None) { platform = FMODPlatform.PlayInEditor; } defaultBankFolder = Path.Combine(EditorUtils.GetBankDirectory(), Settings.Instance.GetBankPlatform(platform)); } string[] bankPlatforms = EditorUtils.GetBankPlatforms(); string[] bankFolders = new string[bankPlatforms.Length]; for (int i = 0; i < bankPlatforms.Length; i++) { bankFolders[i] = Path.Combine(EditorUtils.GetBankDirectory(), bankPlatforms[i]); } List <String> stringBanks = new List <string>(0); try { var files = Directory.GetFiles(defaultBankFolder, "*." + StringBankExtension); stringBanks = new List <string>(files); } catch { } // Strip out OSX resource-fork files that appear on FAT32 stringBanks.RemoveAll((x) => Path.GetFileName(x).StartsWith("._")); if (stringBanks.Count == 0) { bool wasValid = eventCache.StringsBankWriteTime != DateTime.MinValue; ClearCache(); if (wasValid) { UnityEngine.Debug.LogError(String.Format("FMOD Studio: Directory {0} doesn't contain any banks. Build from the tool or check the path in the settings", defaultBankFolder)); } return; } // If we have multiple .strings.bank files find the most recent stringBanks.Sort((a, b) => File.GetLastWriteTime(b).CompareTo(File.GetLastWriteTime(a))); string stringBankPath = stringBanks[0]; // Use the string bank timestamp as a marker for the most recent build of any bank because it gets exported every time if (File.GetLastWriteTime(stringBankPath) == eventCache.StringsBankWriteTime) { countdownTimer = CountdownTimerReset; return; } if (EditorUtils.IsFileOpenByStudio(stringBankPath)) { countdownTimer = CountdownTimerReset; return; } FMOD.Studio.Bank stringBank; EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank)); if (!stringBank.isValid()) { countdownTimer = CountdownTimerReset; return; } // Iterate every string in the strings bank and look for any that identify banks int stringCount; stringBank.getStringCount(out stringCount); List <string> bankFileNames = new List <string>(); for (int stringIndex = 0; stringIndex < stringCount; stringIndex++) { string currentString; Guid currentGuid; stringBank.getStringInfo(stringIndex, out currentGuid, out currentString); const string BankPrefix = "bank:/"; int BankPrefixLength = BankPrefix.Length; if (currentString.StartsWith(BankPrefix)) { string bankFileName = currentString.Substring(BankPrefixLength) + "." + BankExtension; if (!bankFileName.Contains(StringBankExtension)) // filter out the strings bank { bankFileNames.Add(bankFileName); } } } // Unload the strings bank stringBank.unload(); // Check if any of the files are still being written by studio foreach (string bankFileName in bankFileNames) { string bankPath = Path.Combine(defaultBankFolder, bankFileName); if (!File.Exists(bankPath)) { // TODO: this is meant to catch the case where we're in the middle of a build and a bank is being built // for the first time. But it also stops someone trying to import an incomplete set of banks without any error message. countdownTimer = CountdownTimerReset; return; } EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => bankPath == x.Path); if (bankRef == null) { if (EditorUtils.IsFileOpenByStudio(bankPath)) { countdownTimer = CountdownTimerReset; return; } continue; } if (bankRef.LastModified != File.GetLastWriteTime(bankPath)) { if (EditorUtils.IsFileOpenByStudio(bankPath)) { countdownTimer = CountdownTimerReset; return; } } } // Count down the timer in case we catch studio in-between updating two files. if (countdownTimer-- > 0) { return; } // All files are finished being modified by studio so update the cache // Stop editor preview so no stale data being held EditorUtils.PreviewStop(); // Reload the strings bank EditorUtils.CheckResult(EditorUtils.System.loadBankFile(stringBankPath, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out stringBank)); if (!stringBank.isValid()) { ClearCache(); return; } FileInfo stringBankFileInfo = new FileInfo(stringBankPath); eventCache.StringsBankWriteTime = stringBankFileInfo.LastWriteTime; string masterBankFileName = Path.GetFileName(stringBankPath).Replace(StringBankExtension, BankExtension); AssetDatabase.StartAssetEditing(); if (eventCache.StringsBankRef == null) { eventCache.StringsBankRef = ScriptableObject.CreateInstance <EditorBankRef>(); eventCache.StringsBankRef.FileSizes = new List <EditorBankRef.NameValuePair>(); eventCache.EditorBanks.Add(eventCache.StringsBankRef); AssetDatabase.AddObjectToAsset(eventCache.StringsBankRef, eventCache); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(eventCache.StringsBankRef)); } eventCache.StringsBankRef.Path = stringBankPath; eventCache.StringsBankRef.LastModified = eventCache.StringsBankWriteTime; eventCache.StringsBankRef.FileSizes.Clear(); if (Settings.Instance.HasPlatforms) { for (int i = 0; i < bankPlatforms.Length; i++) { eventCache.StringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], stringBankFileInfo.Length)); } } else { eventCache.StringsBankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", stringBankFileInfo.Length)); } eventCache.EditorBanks.ForEach((x) => x.Exists = false); eventCache.StringsBankRef.Exists = true; string[] folderContents = Directory.GetFiles(defaultBankFolder); foreach (string bankFileName in bankFileNames) { // Get the true file path, can't trust the character case we got from the string bank string bankPath = ArrayUtility.Find(folderContents, x => (string.Equals(bankFileName, Path.GetFileName(x), StringComparison.CurrentCultureIgnoreCase))); FileInfo bankFileInfo = new FileInfo(bankPath); EditorBankRef bankRef = eventCache.EditorBanks.Find((x) => bankFileInfo.FullName == x.Path); // New bank we've never seen before if (bankRef == null) { bankRef = ScriptableObject.CreateInstance <EditorBankRef>(); AssetDatabase.AddObjectToAsset(bankRef, eventCache); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(bankRef)); bankRef.Path = bankFileInfo.FullName; bankRef.LastModified = DateTime.MinValue; bankRef.FileSizes = new List <EditorBankRef.NameValuePair>(); eventCache.EditorBanks.Add(bankRef); } bankRef.Exists = true; // Timestamp check - if it doesn't match update events from that bank if (bankRef.LastModified != bankFileInfo.LastWriteTime) { bankRef.LastModified = bankFileInfo.LastWriteTime; UpdateCacheBank(bankRef); } // Update file sizes bankRef.FileSizes.Clear(); if (Settings.Instance.HasPlatforms) { for (int i = 0; i < bankPlatforms.Length; i++) { string platformBankPath = Path.Combine(bankFolders[i], bankFileName); var fileInfo = new FileInfo(platformBankPath); if (fileInfo.Exists) { bankRef.FileSizes.Add(new EditorBankRef.NameValuePair(bankPlatforms[i], fileInfo.Length)); } } } else { string platformBankPath = Path.Combine(EditorUtils.GetBankDirectory(), bankFileName); var fileInfo = new FileInfo(platformBankPath); if (fileInfo.Exists) { bankRef.FileSizes.Add(new EditorBankRef.NameValuePair("", fileInfo.Length)); } } if (bankFileInfo.Name == masterBankFileName) { eventCache.MasterBankRef = bankRef; } } // Unload the strings bank stringBank.unload(); // Remove any stale entries from bank and event lists eventCache.EditorBanks.FindAll((x) => !x.Exists).ForEach(RemoveCacheBank); eventCache.EditorBanks.RemoveAll((x) => !x.Exists); eventCache.EditorEvents.RemoveAll((x) => x.Banks.Count == 0); OnCacheChange(); AssetDatabase.StopAssetEditing(); }
public override void OnInspectorGUI() { Settings settings = target as Settings; EditorGUI.BeginChangeCheck(); hasBankSourceChanged = false; bool hasBankTargetChanged = false; GUIStyle style = new GUIStyle(GUI.skin.label); style.richText = true; GUI.skin.FindStyle("HelpBox").richText = true; int sourceType = settings.HasSourceProject ? 0 : (settings.HasPlatforms ? 2 : 1); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); sourceType = GUILayout.Toggle(sourceType == 0, "Project", "Button") ? 0 : sourceType; sourceType = GUILayout.Toggle(sourceType == 1, "Single Platform Build", "Button") ? 1 : sourceType; sourceType = GUILayout.Toggle(sourceType == 2, "Multiple Platform Build", "Button") ? 2 : sourceType; EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.HelpBox( "<size=11>Select the way you wish to connect Unity to the FMOD Studio content:\n" + "<b>• Project</b>\t\tIf you have the complete FMOD Studio project avaliable\n" + "<b>• Single Platform</b>\tIf you have only the contents of the <i>Build</i> folder for a single platform\n" + "<b>• Multiple Platforms</b>\tIf you have only the contents of the <i>Build</i> folder for multiple platforms, each platform in it's own sub directory\n" + "</size>" , MessageType.Info, true); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (sourceType == 0) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceProjectPathUnformatted; EditorGUILayout.PrefixLabel("Studio Project Path", GUI.skin.textField, style); settings.SourceProjectPathUnformatted = EditorGUILayout.TextField(GUIContent.none, settings.SourceProjectPathUnformatted); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); string path = EditorUtility.OpenFilePanel("Locate Studio Project", oldPath, "fspro"); if (!String.IsNullOrEmpty(path)) { path = MakePathRelativeToProject(path); settings.SourceProjectPathUnformatted = path; settings.SourceProjectPath = path; this.Repaint(); } } EditorGUILayout.EndHorizontal(); if (settings.SourceBankPathUnformatted != null && !settings.SourceProjectPathUnformatted.Equals(settings.SourceProjectPath)) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField("Platform specific path", settings.SourceProjectPath); EditorGUI.EndDisabledGroup(); } // Cache in settings for runtime access in play-in-editor mode var bankPath = EditorUtils.GetBankDirectoryUnformatted(); settings.SourceBankPathUnformatted = bankPath; settings.SourceBankPath = bankPath; settings.HasPlatforms = true; settings.HasSourceProject = true; // First time project path is set or changes, copy to streaming assets if (settings.SourceProjectPathUnformatted != oldPath) { hasBankSourceChanged = true; } } if (sourceType == 1 || sourceType == 2) { EditorGUILayout.BeginHorizontal(); string oldPath = settings.SourceBankPathUnformatted; EditorGUILayout.PrefixLabel("Build Path", GUI.skin.textField, style); settings.SourceBankPathUnformatted = EditorGUILayout.TextField(GUIContent.none, settings.SourceBankPathUnformatted); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { GUI.FocusControl(null); var path = EditorUtility.OpenFolderPanel("Locate Build Folder", oldPath, null); if (!String.IsNullOrEmpty(path)) { path = MakePathRelativeToProject(path); settings.SourceBankPathUnformatted = path; settings.SourceBankPath = path; } } EditorGUILayout.EndHorizontal(); if (settings.SourceBankPathUnformatted != null && !settings.SourceBankPathUnformatted.Equals(settings.SourceBankPath)) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField("Platform specific path", settings.SourceBankPath); EditorGUI.EndDisabledGroup(); } settings.HasPlatforms = (sourceType == 2); settings.HasSourceProject = false; // First time project path is set or changes, copy to streaming assets if (settings.SourceBankPathUnformatted != oldPath) { hasBankSourceChanged = true; } } bool validBanks; string failReason; EditorUtils.ValidateSource(out validBanks, out failReason); if (!validBanks) { EditorGUILayout.HelpBox(failReason, MessageType.Error, true); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } return; } ImportType importType = (ImportType)EditorGUILayout.EnumPopup("Import Type", settings.ImportType); if (importType != settings.ImportType) { hasBankTargetChanged = true; settings.ImportType = importType; } EditorGUI.BeginDisabledGroup(settings.ImportType == ImportType.StreamingAssets); string targetAssetPath = EditorGUILayout.TextField("FMOD Asset Folder", settings.TargetAssetPath); if (targetAssetPath != settings.TargetAssetPath) { settings.TargetAssetPath = targetAssetPath; hasBankTargetChanged = true; } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(settings.ImportType == ImportType.AssetBundle); // ----- Loading ----------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Loading</b>", style); EditorGUI.indentLevel++; settings.AutomaticEventLoading = EditorGUILayout.Toggle("Load All Event Data at Initialization", settings.AutomaticEventLoading); EditorGUI.BeginDisabledGroup(!settings.AutomaticEventLoading); settings.AutomaticSampleLoading = EditorGUILayout.Toggle("Load All Sample Data at Initialization", settings.AutomaticSampleLoading); EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel--; EditorGUI.EndDisabledGroup(); // ----- PIE ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Play In Editor Settings</b>", style); EditorGUI.indentLevel++; DisplayEditorBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.PlayInEditor); if (settings.IsLiveUpdateEnabled(FMODPlatform.PlayInEditor)) { #if UNITY_5_0 || UNITY_5_1 EditorGUILayout.HelpBox("Unity 5.0 or 5.1 detected: Live update will listen on port <b>9265</b>", MessageType.Warning, false); #else EditorGUILayout.HelpBox("Live update will listen on port <b>9264</b>", MessageType.Info, false); #endif } DisplayEditorBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { DisplayPIEBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.PlayInEditor); } DisplayPIESpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.PlayInEditor); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(String.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.PlayInEditor)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } EditorGUI.indentLevel--; // ----- Default ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.LabelField("<b>Default Settings</b>", style); EditorGUI.indentLevel++; DisplayParentBool("Live Update", settings.LiveUpdateSettings, FMODPlatform.Default); if (settings.IsLiveUpdateEnabled(FMODPlatform.Default)) { #if UNITY_5_0 || UNITY_5_1 EditorGUILayout.HelpBox("Unity 5.0 or 5.1 detected: Live update will listen on port <b>9265</b>", MessageType.Warning, false); #else EditorGUILayout.HelpBox("Live update will listen on port <b>9264</b>", MessageType.Info, false); #endif } DisplayParentBool("Debug Overlay", settings.OverlaySettings, FMODPlatform.Default); DisplayParentFreq("Sample Rate", settings.SampleRateSettings, FMODPlatform.Default); if (settings.HasPlatforms) { bool prevChanged = GUI.changed; DisplayParentBuildDirectory("Bank Platform", settings.BankDirectorySettings, FMODPlatform.Default); hasBankSourceChanged |= !prevChanged && GUI.changed; } DisplayParentSpeakerMode("Speaker Mode", settings.SpeakerModeSettings, FMODPlatform.Default); if (settings.HasPlatforms) { EditorGUILayout.HelpBox(String.Format("Match the speaker mode to the setting of the platform <b>{0}</b> inside FMOD Studio", settings.GetBankPlatform(FMODPlatform.Default)), MessageType.Info, false); } else { EditorGUILayout.HelpBox("Match the speaker mode to the setting inside FMOD Studio", MessageType.Info, false); } DisplayParentInt("Virtual Channel Count", settings.VirtualChannelSettings, FMODPlatform.Default, 1, 2048); DisplayParentInt("Real Channel Count", settings.RealChannelSettings, FMODPlatform.Default, 1, 256); EditorGUI.indentLevel--; // ----- Plugins ---------------------------------------------- EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("<b>Plugins</b>", GUI.skin.button, style); if (GUILayout.Button("Add Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.Add(""); } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel++; for (int count = 0; count < settings.Plugins.Count; count++) { EditorGUILayout.BeginHorizontal(); settings.Plugins[count] = EditorGUILayout.TextField("Plugin " + (count + 1).ToString() + ":", settings.Plugins[count]); if (GUILayout.Button("Delete Plugin", GUILayout.ExpandWidth(false))) { settings.Plugins.RemoveAt(count); } EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; // ----- Windows ---------------------------------------------- DisplayPlatform(FMODPlatform.Desktop, null); DisplayPlatform(FMODPlatform.Mobile, new FMODPlatform[] { FMODPlatform.MobileHigh, FMODPlatform.MobileLow, FMODPlatform.PSVita, FMODPlatform.AppleTV }); DisplayPlatform(FMODPlatform.Console, new FMODPlatform[] { FMODPlatform.XboxOne, FMODPlatform.PS4, FMODPlatform.WiiU }); if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(settings); } if (hasBankSourceChanged) { EventManager.UpdateCache(); } if (hasBankTargetChanged) { EventManager.CopyToStreamingAssets(); } }
public override void OnInspectorGUI() { var begin = serializedObject.FindProperty("PlayEvent"); var end = serializedObject.FindProperty("StopEvent"); var tag = serializedObject.FindProperty("CollisionTag"); var eventReference = serializedObject.FindProperty("EventReference"); var eventPath = eventReference.FindPropertyRelative("Path"); var fadeout = serializedObject.FindProperty("AllowFadeout"); var once = serializedObject.FindProperty("TriggerOnce"); var preload = serializedObject.FindProperty("Preload"); var overrideAtt = serializedObject.FindProperty("OverrideAttenuation"); var minDistance = serializedObject.FindProperty("OverrideMinDistance"); var maxDistance = serializedObject.FindProperty("OverrideMaxDistance"); EditorGUILayout.PropertyField(begin, new GUIContent("Play Event")); EditorGUILayout.PropertyField(end, new GUIContent("Stop Event")); if ((begin.enumValueIndex >= (int)EmitterGameEvent.TriggerEnter && begin.enumValueIndex <= (int)EmitterGameEvent.TriggerExit2D) || (end.enumValueIndex >= (int)EmitterGameEvent.TriggerEnter && end.enumValueIndex <= (int)EmitterGameEvent.TriggerExit2D)) { tag.stringValue = EditorGUILayout.TagField("Collision Tag", tag.stringValue); } EditorGUI.BeginChangeCheck(); const string EventReferenceLabel = "Event"; EditorUtils.DrawLegacyEvent(serializedObject.FindProperty("Event"), EventReferenceLabel); EditorGUILayout.PropertyField(eventReference, new GUIContent(EventReferenceLabel)); EditorEventRef editorEvent = EventManager.EventFromPath(eventPath.stringValue); if (EditorGUI.EndChangeCheck()) { EditorUtils.UpdateParamsOnEmitter(serializedObject, eventPath.stringValue); } // Attenuation if (editorEvent != null) { { EditorGUI.BeginDisabledGroup(editorEvent == null || !editorEvent.Is3D); EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(overrideAtt); if (EditorGUI.EndChangeCheck() || (minDistance.floatValue == -1 && maxDistance.floatValue == -1) // never been initialiased ) { minDistance.floatValue = editorEvent.MinDistance; maxDistance.floatValue = editorEvent.MaxDistance; } EditorGUI.BeginDisabledGroup(!overrideAtt.boolValue); EditorGUIUtility.labelWidth = 30; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(minDistance, new GUIContent("Min")); if (EditorGUI.EndChangeCheck()) { minDistance.floatValue = Mathf.Clamp(minDistance.floatValue, 0, maxDistance.floatValue); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(maxDistance, new GUIContent("Max")); if (EditorGUI.EndChangeCheck()) { maxDistance.floatValue = Mathf.Max(minDistance.floatValue, maxDistance.floatValue); } EditorGUIUtility.labelWidth = 0; EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); } parameterValueView.OnGUI(editorEvent, !eventReference.hasMultipleDifferentValues); fadeout.isExpanded = EditorGUILayout.Foldout(fadeout.isExpanded, "Advanced Controls"); if (fadeout.isExpanded) { EditorGUILayout.PropertyField(preload, new GUIContent("Preload Sample Data")); EditorGUILayout.PropertyField(fadeout, new GUIContent("Allow Fadeout When Stopping")); EditorGUILayout.PropertyField(once, new GUIContent("Trigger Once")); } } serializedObject.ApplyModifiedProperties(); }