Advanced POC - portals, dialogue system + floating words, room loading

This commit is contained in:
2026-01-26 20:31:27 +01:00
parent b5ca4763b3
commit 203b00578a
426 changed files with 123482 additions and 29 deletions
@@ -0,0 +1,79 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using Unheimlich.Data.Dialogues;
[CustomEditor(typeof(DialogueConversation))]
public class DialogueConversationEditor : Editor
{
private SerializedProperty _speakerNameProp;
private SerializedProperty _speakerNameLocalizationKeyProp;
private SerializedProperty _dialogueNodesProp;
private void OnEnable()
{
_speakerNameProp = serializedObject.FindProperty("SpeakerName");
_speakerNameLocalizationKeyProp = serializedObject.FindProperty("SpeakerNameLocalizationKey");
_dialogueNodesProp = serializedObject.FindProperty("DialogueNodes");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Conversation Setup", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_speakerNameProp);
EditorGUILayout.PropertyField(_speakerNameLocalizationKeyProp, new GUIContent("Localization Key (Optional)"));
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Dialogue Flow", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("The first DialogueNode in the list will be the starting point of the conversation.", MessageType.Info);
EditorGUILayout.PropertyField(_dialogueNodesProp, new GUIContent("Dialogue Nodes"), true);
EditorGUILayout.Space(10);
if (GUILayout.Button("Create New Dialogue Node", GUILayout.Height(30)))
CreateNewDialogueNode();
EditorGUILayout.Space(10);
DialogueConversation conversation = (DialogueConversation)target;
if (conversation.DialogueNodes != null && conversation.DialogueNodes.Count > 0)
{
EditorGUILayout.LabelField("Conversation Overview", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"Total Nodes: {conversation.DialogueNodes.Count}");
DialogueNode firstNode = conversation.GetFirstNode();
if (firstNode != null)
EditorGUILayout.LabelField($"Starting Node: {firstNode.name}");
}
serializedObject.ApplyModifiedProperties();
}
private void CreateNewDialogueNode()
{
DialogueConversation conversation = (DialogueConversation)target;
string path = AssetDatabase.GetAssetPath(conversation);
string directory = System.IO.Path.GetDirectoryName(path);
DialogueNode newNode = ScriptableObject.CreateInstance<DialogueNode>();
newNode.name = $"Node_{conversation.DialogueNodes.Count + 1}";
string nodePath = AssetDatabase.GenerateUniqueAssetPath($"{directory}/{newNode.name}.asset");
AssetDatabase.CreateAsset(newNode, nodePath);
conversation.DialogueNodes.Add(newNode);
EditorUtility.SetDirty(conversation);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorGUIUtility.PingObject(newNode);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e3385c171e333c347bcf6f68b953acdb
@@ -0,0 +1,99 @@
using UnityEngine;
using UnityEditor;
using Unheimlich.Data.Dialogues;
[CustomEditor(typeof(DialogueNode))]
public class DialogueNodeEditor : Editor
{
private SerializedProperty _dialogueTextProp;
private SerializedProperty _dialogueTextLocalizationKeyProp;
private SerializedProperty _choicesProp;
private SerializedProperty _autoCloseDelayProp;
private void OnEnable()
{
_dialogueTextProp = serializedObject.FindProperty("DialogueText");
_dialogueTextLocalizationKeyProp = serializedObject.FindProperty("DialogueTextLocalizationKey");
_choicesProp = serializedObject.FindProperty("Choices");
_autoCloseDelayProp = serializedObject.FindProperty("AutoCloseDelay");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Node Content", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_dialogueTextProp);
EditorGUILayout.PropertyField(_dialogueTextLocalizationKeyProp, new GUIContent("Localization Key (Optional)"));
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Choices", EditorStyles.boldLabel);
DialogueNode node = (DialogueNode)target;
if (node.IsEndNode())
{
EditorGUILayout.HelpBox("This node is an end of conversation (no choices).", MessageType.Info);
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("End Node Settings", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_autoCloseDelayProp, new GUIContent("Auto Close Delay (seconds)"));
float delay = _autoCloseDelayProp.floatValue;
if (delay > 0)
EditorGUILayout.HelpBox($"The dialogue will automatically close after {delay:F1}s with a fade out.", MessageType.None);
else
EditorGUILayout.HelpBox("Player must press 'Interact' to close the dialogue.", MessageType.None);
EditorGUILayout.Space(5);
}
else if (!node.HasValidChoices())
EditorGUILayout.HelpBox("Warning: Some choices don't have a NextNode assigned.", MessageType.Warning);
EditorGUILayout.PropertyField(_choicesProp, true);
EditorGUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Choice"))
{
AddNewChoice();
}
if (node.Choices != null && node.Choices.Count > 0)
{
if (GUILayout.Button("Clear All Choices"))
{
if (EditorUtility.DisplayDialog("Clear Choices",
"Are you sure you want to remove all choices?",
"Yes", "Cancel"))
{
node.Choices.Clear();
EditorUtility.SetDirty(node);
}
}
}
EditorGUILayout.EndHorizontal();
serializedObject.ApplyModifiedProperties();
}
private void AddNewChoice()
{
DialogueNode node = (DialogueNode)target;
DialogueChoiceData newChoice = new DialogueChoiceData
{
ChoiceText = "New choice",
NextNode = null
};
node.Choices.Add(newChoice);
EditorUtility.SetDirty(node);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 91d402e79d02c8246b21d7f72df91e84
@@ -0,0 +1,31 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
[InitializeOnLoad]
public static class HierarchySectionHeader
{
static HierarchySectionHeader()
{
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
}
static void HierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
{
var gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (gameObject != null && gameObject.name.StartsWith("//", System.StringComparison.Ordinal))
{
EditorGUI.DrawRect(selectionRect, Color.grey);
EditorGUI.LabelField(selectionRect, gameObject.name.Replace("/", "").ToUpperInvariant(), new GUIStyle(EditorStyles.boldLabel)
{
fontSize = 12,
alignment = TextAnchor.MiddleCenter,
normal = { textColor = Color.black }
});
}
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a8e4f480645562e48bfd2214400c5d2d