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