Complete reorga

This commit is contained in:
2026-03-09 17:55:23 +01:00
parent d9326e48cc
commit 10faf74405
703 changed files with 13040 additions and 1533 deletions
@@ -1,6 +1,6 @@
using UnityEngine;
using UnityEditor;
using Unheimlich.Audio;
using Unheimlich.Core.Audio;
namespace Unheimlich.Editor
{
@@ -0,0 +1,63 @@
using UnityEngine;
namespace Unheimlich.Audio
{
public class AudioSourceInspector : MonoBehaviour
{
[Header("Debug Settings")]
[SerializeField] private float _logInterval = 1f;
private AudioSource _source;
private float _lastLogTime;
private void Awake()
{
_source = GetComponent<AudioSource>();
}
private void Update()
{
if (_source == null) return;
if (Time.time - _lastLogTime >= _logInterval)
{
LogAudioSourceState();
_lastLogTime = Time.time;
}
}
private void OnEnable()
{
Debug.Log($"<color=cyan>[AudioInspector] OnEnable called on {gameObject.name}</color>");
if (_source != null)
LogAudioSourceState();
}
private void OnDisable()
{
Debug.Log($"<color=magenta>[AudioInspector] OnDisable called on {gameObject.name}</color>");
if (_source != null)
LogAudioSourceState();
}
private void LogAudioSourceState()
{
if (_source == null)
{
Debug.LogWarning($"[AudioInspector] No AudioSource on {gameObject.name}");
return;
}
string clipName = _source.clip != null ? _source.clip.name : "NULL";
Debug.Log($"<color=yellow>[AudioInspector] {gameObject.name} | " +
$"Clip: {clipName} | " +
$"Time: {_source.time:F2}s | " +
$"isPlaying: {_source.isPlaying} | " +
$"enabled: {_source.enabled} | " +
$"volume: {_source.volume:F2} | " +
$"mute: {_source.mute} | " +
$"loop: {_source.loop} | " +
$"Active: {gameObject.activeInHierarchy}</color>");
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 65fea0a39ddb811419ec546ea98e5917
@@ -1,38 +0,0 @@
using UnityEngine;
using UnityEditor;
using Unheimlich.Data.DetectiveBoard;
namespace Unheimlich.Editor
{
[CustomEditor(typeof(ClueData))]
public class ClueDataEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
ClueData clueData = (ClueData)target;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Quick Actions", EditorStyles.boldLabel);
if (GUILayout.Button("Generate Unique ID"))
{
clueData.ClueID = System.Guid.NewGuid().ToString();
EditorUtility.SetDirty(clueData);
}
if (GUILayout.Button("Test Unlock Clue (Play Mode Only)"))
{
if (Application.isPlaying)
{
Managers.DetectiveBoardManager.Instance?.UnlockClue(clueData);
}
else
{
Debug.LogWarning("This button only works in Play Mode!");
}
}
}
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 184cbe5b79ee0a84ba29da016ec76159
@@ -1,112 +0,0 @@
using UnityEngine;
using UnityEditor;
using Unheimlich.Data.Dialogues;
[CustomEditor(typeof(DialogueConversation))]
public class DialogueConversationEditor : Editor
{
private SerializedProperty _speakerNameProp;
private SerializedProperty _displayModeProp;
private SerializedProperty _dialogueNodesProp;
[MenuItem("Unheimlich/Tools/Dialogue/Refresh All Conversations")]
public static void RefreshAllConversations()
{
string[] guids = AssetDatabase.FindAssets("t:DialogueConversation");
int count = 0;
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
DialogueConversation conv = AssetDatabase.LoadAssetAtPath<DialogueConversation>(path);
if (conv != null)
{
EditorUtility.SetDirty(conv);
count++;
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log($"<color=green>[Dialogue Refresher]</color> {count} conversations ont été rafraîchies !");
}
private void OnEnable()
{
_speakerNameProp = serializedObject.FindProperty("SpeakerName");
_displayModeProp = serializedObject.FindProperty("DisplayMode");
_dialogueNodesProp = serializedObject.FindProperty("DialogueNodes");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Conversation Setup", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_speakerNameProp);
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("Display Settings", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_displayModeProp, new GUIContent("Display Mode"));
EditorGUILayout.HelpBox(
"World: Dialogue text appears in 3D space\n" +
"Screen: Dialogue text appears on Canvas UI\n" +
"Choices always appear in World space.",
MessageType.Info);
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 = 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);
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: e3385c171e333c347bcf6f68b953acdb
@@ -1,112 +0,0 @@
using UnityEngine;
using UnityEditor;
using Unheimlich.Data.Dialogues;
[CustomEditor(typeof(DialogueNode))]
public class DialogueNodeEditor : Editor
{
private SerializedProperty _dialogueTextProp;
private SerializedProperty _choicesProp;
private SerializedProperty _autoCloseDelayProp;
private SerializedProperty _clueToUnlockProp;
private void OnEnable()
{
_dialogueTextProp = serializedObject.FindProperty("DialogueText");
_choicesProp = serializedObject.FindProperty("Choices");
_autoCloseDelayProp = serializedObject.FindProperty("AutoCloseDelay");
_clueToUnlockProp = serializedObject.FindProperty("ClueToUnlock");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Node Content", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_dialogueTextProp);
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.LabelField("Detective Board Integration", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_clueToUnlockProp, new GUIContent("Clue To Unlock"));
if (_clueToUnlockProp.objectReferenceValue != null)
{
EditorGUILayout.HelpBox("This clue will be unlocked on the Detective Board when this dialogue node is reached.", MessageType.Info);
}
else
{
EditorGUILayout.HelpBox("Optional: Assign a ClueData to unlock an evidence on the Detective Board when reaching this node.", MessageType.None);
}
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 = null, // Will need to assign OctoLocalizedTextData manually
NextNode = null
};
node.Choices.Add(newChoice);
EditorUtility.SetDirty(node);
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 91d402e79d02c8246b21d7f72df91e84