using System; using Framework.Support; using UnityEngine; using UnityEditor; namespace Framework.Dialogue { /// /// Assists the user in editing ground definitions for the navigation system /// [CustomEditor(typeof(DialogueOwner), true)] public class DialogueOwnerEditor : Editor { /// Called when Unity wants to layout or draw the inspector public override void OnInspectorGUI() { base.OnInspectorGUI(); if(!Application.isPlaying) { var dialoguePlacement = target as DialogueOwner; if (dialoguePlacement != null) { doPreviewGui(dialoguePlacement); EditorGUILayout.HelpBox( "NOTE: Do not leave dialogue UI previews open. " + "These would remain open when the game starts", MessageType.Info ); updateSelection(dialoguePlacement); } } } /// Called when the editor UI is created for a game object protected virtual void OnEnable() { // Destroy any preview UIs. If we destroyed them in OnDestroy(), the user // would be unable to actually use the previews to position the UI, // but leaving them active would mean the editor UI (which is recreated // each time the object gets selected) would create ever more preview UIs. var dialogueOwner = target as DialogueOwner; if(dialogueOwner != null) { int placementCount = getPlacementCount(dialogueOwner); for(int index = 0; index < placementCount; ++index) { Transform placement = dialogueOwner.StaticPlacements[index]; destroyPreviewPlacement(placement); } } } /// Shows the UI controls for the dialogue placement preview /// Dialogue placement the GUI will be shown for private void doPreviewGui(DialogueOwner dialogueOwner) { int placementCount = getPlacementCount(dialogueOwner); if(this.selectedPreviewIndex > placementCount) { this.selectedPreviewIndex = -1; } // If there are placement slots present, allow the user to select // between them to display an in-editor preview. if(placementCount > 0) { var previews = new string[placementCount]; for(int index = 0; index < placementCount; ++index) { previews[index] = (index + 1).ToString(); } using(var horizontalScope = new EditorGUILayout.HorizontalScope()) { EditorGUILayout.PrefixLabel("Preview"); this.selectedPreviewIndex = GUILayout.SelectionGrid( this.selectedPreviewIndex, previews, placementCount ); } } // Also provide a button for the user to hide all previews using(var horizontalScope = new EditorGUILayout.HorizontalScope()) { if(placementCount == 0) { EditorGUILayout.PrefixLabel("Preview"); } else { EditorGUILayout.PrefixLabel(" "); } bool hidePreviewClicked = GUILayout.Button("Hide Preview"); if(hidePreviewClicked) { this.selectedPreviewIndex = -1; } } } /// Activates the currently selected preview /// Dialogue placement private void updateSelection(DialogueOwner dialogueOwner) { int placementCount = getPlacementCount(dialogueOwner); if(this.selectedPreviewIndex != this.activePreviewIndex) { if((this.activePreviewIndex != -1) && (this.activePreviewIndex < placementCount)) { Transform placement = dialogueOwner.StaticPlacements[this.activePreviewIndex]; if(placement != null) { destroyPreviewPlacement(placement); } } if((this.selectedPreviewIndex != -1) && (this.selectedPreviewIndex < placementCount)) { Transform placement = dialogueOwner.StaticPlacements[this.selectedPreviewIndex]; if(placement == null) { Debug.LogWarning("Showing no preview because the placement is set to null."); } else { createPreviewPlacement(placement, dialogueOwner.PreviewPrefab); } } this.activePreviewIndex = this.selectedPreviewIndex; } } /// Creates a preview placement in the editor /// Position at which a preview placement will be created /// Prefab to instantiate for the preview private void createPreviewPlacement(Transform placement, DialogueCanvas prefab) { DialogueCanvas canvas = GameObject.Instantiate(prefab); GameObjectHelper.SetAsChild(placement.gameObject, canvas.gameObject); } /// Destroys a preview placement in the editor /// Parent in which hte preview placement will be destroyed private void destroyPreviewPlacement(Transform placement) { DialogueCanvas canvas = placement.GetComponentInChildren(); if(canvas != null) { GameObject.DestroyImmediate(canvas.gameObject); } } /// Returns the number of dialogue placements set up /// /// Dialogue placement container whose placement count will be checked /// /// The number of placements set up in the placement container private static int getPlacementCount(DialogueOwner dialogueOwner) { if(dialogueOwner.StaticPlacements == null) { return 0; } else { return dialogueOwner.StaticPlacements.Length; } } /// Index of the placement that is being previewed currently private int selectedPreviewIndex = -1; /// Index of the placement that is being previewed currently private int activePreviewIndex = -1; } } // namespace Framework.Dialogue