This commit is contained in:
2026-07-04 18:01:40 +07:00
parent 315c14c651
commit 5b88e6d3c3
75 changed files with 64013 additions and 370482 deletions

View File

@@ -12,9 +12,73 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment=""> <list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.BABA_YAGA/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkConfig.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Editors/AutoSaveTool.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/AutoSaveTool.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkGenerator.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Editors/CameraBookmarksTool.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/CameraBookmarksTool.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/MazeRework/MazeReworkManager.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Editors/LevelDecorator.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/LevelDecorator.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Editors/PlayFromHereTool.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/PlayFromHereTool.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Editors/ProjectDashboardTool.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/ProjectDashboardTool.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Editors/TimeLord.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Editors/TimeLord.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/ArrowLifeSettings.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/ArrowLifeSettings.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/AudioDatabase.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/AudioDatabase.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vBasicLocomotiont@CameraState.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vBasicLocomotiont@CameraState.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vFastShooter@CameraState.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vFastShooter@CameraState.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vMeleeCombat@CameraState.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vMeleeCombat@CameraState.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vShooterMelee@CameraState.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vShooterMelee@CameraState.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vShooterOnly@CameraState.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/CameraStates/vShooterOnly@CameraState.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/DefaultMazeProfile.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/DefaultMazeProfile.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/FOR AI GAME.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/FOR AI GAME.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/FirebaseConfig.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/FirebaseConfig.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/MazeRework.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Presets/MazeRework.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/TestMazeProfile.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/TestMazeProfile.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/vMelee_ItemListData.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/vMelee_ItemListData.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/vShooterMelee_ItemListData.asset" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Presets/vShooterMelee_ItemListData.asset.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/CrawlerAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/CrawlerAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Extensions.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Extensions.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Interfaces.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Interfaces/IMazeAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Interfaces/IMazeAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MapLocation.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MapLocation.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeCellType.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeCellType.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeGrid.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeGrid.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeRenderer.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeRenderer.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeVisualProfile.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/MazeVisualProfile.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Native.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Native/NativeNoiseProvider.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/Native/NativeNoiseProvider.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/NoiseRecursiveGenerator.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/NoiseRecursiveGenerator.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/PrimsAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/PrimsAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/RecursiveAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/RecursiveAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/WilsonsAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Baba_yaga/GameSetup/Maze/WilsonsAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/vHierarchy/vHierarchy Data.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Third Parties/vHierarchy/vHierarchy Data.asset" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -149,7 +213,7 @@
<workItem from="1782445122703" duration="1948000" /> <workItem from="1782445122703" duration="1948000" />
<workItem from="1782825955934" duration="1783000" /> <workItem from="1782825955934" duration="1783000" />
<workItem from="1783149945807" duration="606000" /> <workItem from="1783149945807" duration="606000" />
<workItem from="1783156047890" duration="1863000" /> <workItem from="1783156047890" duration="6605000" />
</task> </task>
<servers /> <servers />
</component> </component>

View File

@@ -29,32 +29,30 @@ using System;
using UnityEditor; using UnityEditor;
using UnityEditor.SceneManagement; using UnityEditor.SceneManagement;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace Editor namespace Editor
{ {
[InitializeOnLoad] // Critical: Ensures the script runs in the background upon Unity startup [InitializeOnLoad]
public class AutoSaveTool : EditorWindow public class AutoSaveTool : EditorWindow
{ {
// Static Configuration Variables (Persisted via EditorPrefs)
private static bool isAutoSaveEnabled; private static bool isAutoSaveEnabled;
private static float saveIntervalMinutes; private static float saveIntervalMinutes;
private static bool showDebugLog; private static bool showDebugLog;
// Time Tracking Variable
private static DateTime nextSaveTime; private static DateTime nextSaveTime;
// Static Constructor: Runs when Unity starts or recompiles private Label statusLabel;
static AutoSaveTool() private VisualElement progressBar;
[InitializeOnLoadMethod]
static void Init()
{ {
// 1. Load settings from EditorPrefs (persistent storage)
isAutoSaveEnabled = EditorPrefs.GetBool("AutoSave_Enabled", false); isAutoSaveEnabled = EditorPrefs.GetBool("AutoSave_Enabled", false);
saveIntervalMinutes = EditorPrefs.GetFloat("AutoSave_Interval", 5f); saveIntervalMinutes = EditorPrefs.GetFloat("AutoSave_Interval", 5f);
showDebugLog = EditorPrefs.GetBool("AutoSave_Log", true); showDebugLog = EditorPrefs.GetBool("AutoSave_Log", true);
// 2. Initialize the timer
ResetTimer(); ResetTimer();
// 3. Register the background update loop
EditorApplication.update += OnEditorUpdate; EditorApplication.update += OnEditorUpdate;
} }
@@ -64,83 +62,194 @@ namespace Editor
GetWindow<AutoSaveTool>("Auto Save"); GetWindow<AutoSaveTool>("Auto Save");
} }
private void OnGUI() public void CreateGUI()
{ {
GUILayout.Label("Auto Save Configuration (Runs in Background)", EditorStyles.boldLabel); VisualElement root = rootVisualElement;
EditorGUILayout.Space(); root.style.paddingTop = 15;
root.style.paddingBottom = 15;
root.style.paddingLeft = 15;
root.style.paddingRight = 15;
// Begin tracking changes on the GUI Label title = new Label("Auto Save Settings");
EditorGUI.BeginChangeCheck(); title.style.fontSize = 22;
title.style.unityFontStyleAndWeight = FontStyle.Bold;
isAutoSaveEnabled = EditorGUILayout.Toggle("Enable Auto Save", isAutoSaveEnabled); title.style.color = new StyleColor(new Color(0.3f, 0.7f, 1f));
saveIntervalMinutes = EditorGUILayout.FloatField("Interval (Minutes)", saveIntervalMinutes); title.style.marginBottom = 15;
showDebugLog = EditorGUILayout.Toggle("Show Debug Log", showDebugLog); root.Add(title);
// If any setting changed, save it immediately to EditorPrefs
if (EditorGUI.EndChangeCheck())
{
if (saveIntervalMinutes < 0.5f) saveIntervalMinutes = 0.5f; // Minimum 30 seconds
// Settings Card
VisualElement settingsCard = CreateCard();
Toggle enableToggle = new Toggle("Enable Auto Save");
enableToggle.value = isAutoSaveEnabled;
enableToggle.RegisterValueChangedCallback(evt => {
isAutoSaveEnabled = evt.newValue;
EditorPrefs.SetBool("AutoSave_Enabled", isAutoSaveEnabled); EditorPrefs.SetBool("AutoSave_Enabled", isAutoSaveEnabled);
ResetTimer();
UpdateUIStatus();
});
enableToggle.style.unityFontStyleAndWeight = FontStyle.Bold;
settingsCard.Add(enableToggle);
Slider intervalSlider = new Slider("Interval (Minutes)", 0.5f, 60f);
intervalSlider.value = saveIntervalMinutes;
intervalSlider.style.marginTop = 15;
intervalSlider.RegisterValueChangedCallback(evt => {
saveIntervalMinutes = evt.newValue;
EditorPrefs.SetFloat("AutoSave_Interval", saveIntervalMinutes); EditorPrefs.SetFloat("AutoSave_Interval", saveIntervalMinutes);
ResetTimer();
});
// Add a label to show exact slider value
Label intervalLabel = new Label($"Current: {saveIntervalMinutes:F1} min");
intervalLabel.style.alignSelf = Align.FlexEnd;
intervalLabel.style.color = new StyleColor(new Color(0.7f, 0.7f, 0.7f));
intervalSlider.RegisterValueChangedCallback(evt => {
intervalLabel.text = $"Current: {evt.newValue:F1} min";
});
settingsCard.Add(intervalSlider);
settingsCard.Add(intervalLabel);
Toggle logToggle = new Toggle("Show Debug Log");
logToggle.value = showDebugLog;
logToggle.style.marginTop = 10;
logToggle.RegisterValueChangedCallback(evt => {
showDebugLog = evt.newValue;
EditorPrefs.SetBool("AutoSave_Log", showDebugLog); EditorPrefs.SetBool("AutoSave_Log", showDebugLog);
});
settingsCard.Add(logToggle);
root.Add(settingsCard);
ResetTimer(); // Reset timer based on new settings // Status Card
} VisualElement statusCard = CreateCard();
statusCard.style.marginTop = 15;
Label statusTitle = new Label("System Status");
statusTitle.style.fontSize = 16;
statusTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
statusTitle.style.marginBottom = 15;
statusCard.Add(statusTitle);
EditorGUILayout.Space(); statusLabel = new Label();
statusLabel.style.fontSize = 15;
statusLabel.style.marginBottom = 10;
statusCard.Add(statusLabel);
if (isAutoSaveEnabled) // Progress bar
{ VisualElement progressBg = new VisualElement();
TimeSpan timeRemaining = nextSaveTime - DateTime.Now; progressBg.style.height = 12;
if (timeRemaining.TotalSeconds < 0) timeRemaining = TimeSpan.Zero; progressBg.style.backgroundColor = new StyleColor(new Color(0.1f, 0.1f, 0.1f));
progressBg.style.borderTopLeftRadius = 6;
progressBg.style.borderTopRightRadius = 6;
progressBg.style.borderBottomLeftRadius = 6;
progressBg.style.borderBottomRightRadius = 6;
progressBg.style.marginBottom = 20;
progressBg.style.overflow = Overflow.Hidden;
// Display warning if Play Mode or Compiling progressBar = new VisualElement();
if (EditorApplication.isPlaying || EditorApplication.isCompiling) progressBar.style.height = 12;
{ progressBar.style.backgroundColor = new StyleColor(new Color(0.3f, 0.7f, 1f));
EditorGUILayout.HelpBox("Currently in Play Mode or Compiling. Saving is temporarily paused to prevent errors.", MessageType.Warning); progressBar.style.width = Length.Percent(0);
} progressBg.Add(progressBar);
else
{
string timeStr = string.Format("{0:00}:{1:00}", timeRemaining.Minutes, timeRemaining.Seconds);
EditorGUILayout.HelpBox($"System is running in background.\nAuto-saving in: {timeStr}", MessageType.Info);
}
if (GUILayout.Button("Save Now", GUILayout.Height(30))) statusCard.Add(progressBg);
{
SaveNow(); Button saveNowBtn = new Button(() => SaveNow());
} saveNowBtn.text = "Force Save Now";
} saveNowBtn.style.height = 40;
else saveNowBtn.style.backgroundColor = new StyleColor(new Color(0.2f, 0.6f, 0.3f));
{ saveNowBtn.style.color = new StyleColor(Color.white);
EditorGUILayout.HelpBox("Auto Save System is currently DISABLED.", MessageType.Error); saveNowBtn.style.fontSize = 14;
} saveNowBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
saveNowBtn.style.borderTopLeftRadius = 6;
saveNowBtn.style.borderTopRightRadius = 6;
saveNowBtn.style.borderBottomLeftRadius = 6;
saveNowBtn.style.borderBottomRightRadius = 6;
statusCard.Add(saveNowBtn);
root.Add(statusCard);
// Periodically update the countdown text and progress bar
root.schedule.Execute(UpdateUIStatus).Every(100);
UpdateUIStatus();
root.Add(ScovySignature.CreateSignatureBox());
}
private VisualElement CreateCard()
{
VisualElement card = new VisualElement();
card.style.backgroundColor = new StyleColor(new Color(0.18f, 0.18f, 0.18f, 0.9f));
card.style.borderTopLeftRadius = 10;
card.style.borderTopRightRadius = 10;
card.style.borderBottomLeftRadius = 10;
card.style.borderBottomRightRadius = 10;
card.style.paddingTop = 15;
card.style.paddingBottom = 15;
card.style.paddingLeft = 15;
card.style.paddingRight = 15;
card.style.borderTopWidth = 1;
card.style.borderBottomWidth = 1;
card.style.borderLeftWidth = 1;
card.style.borderRightWidth = 1;
card.style.borderTopColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderBottomColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderLeftColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderRightColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
return card;
}
private void UpdateUIStatus()
{
if (statusLabel == null || progressBar == null) return;
if (!isAutoSaveEnabled)
{
statusLabel.text = "Auto Save is DISABLED.";
statusLabel.style.color = new StyleColor(new Color(0.85f, 0.35f, 0.35f));
progressBar.style.width = Length.Percent(0);
return;
}
if (EditorApplication.isPlaying || EditorApplication.isCompiling)
{
statusLabel.text = "PAUSED (Play Mode / Compiling)";
statusLabel.style.color = new StyleColor(new Color(0.9f, 0.75f, 0.2f));
progressBar.style.backgroundColor = new StyleColor(new Color(0.9f, 0.75f, 0.2f));
return;
}
TimeSpan timeRemaining = nextSaveTime - DateTime.Now;
if (timeRemaining.TotalSeconds < 0) timeRemaining = TimeSpan.Zero;
string timeStr = string.Format("{0:00}:{1:00}", timeRemaining.Minutes, timeRemaining.Seconds);
statusLabel.text = $"Auto-saving in: {timeStr}";
statusLabel.style.color = new StyleColor(new Color(0.6f, 0.8f, 1f));
progressBar.style.backgroundColor = new StyleColor(new Color(0.3f, 0.7f, 1f));
float totalSeconds = saveIntervalMinutes * 60f;
float elapsed = totalSeconds - (float)timeRemaining.TotalSeconds;
float percent = Mathf.Clamp01(elapsed / totalSeconds) * 100f;
progressBar.style.width = Length.Percent(percent);
} }
// This function runs continuously in the background
private static void OnEditorUpdate() private static void OnEditorUpdate()
{ {
if (!isAutoSaveEnabled) return; if (!isAutoSaveEnabled) return;
// If playing or compiling -> PAUSE the countdown (do not reset)
if (EditorApplication.isPlaying || EditorApplication.isCompiling) if (EditorApplication.isPlaying || EditorApplication.isCompiling)
{ {
// Add delta time to nextSaveTime to compensate for time elapsed while paused
nextSaveTime = nextSaveTime.AddSeconds(Time.unscaledDeltaTime); nextSaveTime = nextSaveTime.AddSeconds(Time.unscaledDeltaTime);
return; return;
} }
// Check if it's time to save
if (DateTime.Now >= nextSaveTime) if (DateTime.Now >= nextSaveTime)
{ {
SaveNow(); SaveNow();
} }
// Repaint the GUI if the window is open to keep the countdown smooth
if (HasOpenInstances<AutoSaveTool>())
{
GetWindow<AutoSaveTool>().Repaint();
}
} }
private static void ResetTimer() private static void ResetTimer()
@@ -151,17 +260,14 @@ namespace Editor
private static void SaveNow() private static void SaveNow()
{ {
var currentScene = EditorSceneManager.GetActiveScene(); var currentScene = EditorSceneManager.GetActiveScene();
bool isSaved = false; bool isSaved = false;
// 1. Save Current Scene if it is dirty AND has a path (not Untitled)
if (currentScene.isDirty && !string.IsNullOrEmpty(currentScene.path)) if (currentScene.isDirty && !string.IsNullOrEmpty(currentScene.path))
{ {
EditorSceneManager.SaveOpenScenes(); EditorSceneManager.SaveOpenScenes();
isSaved = true; isSaved = true;
} }
// 2. Always save Assets (Prefabs, ScriptableObjects, etc.)
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
isSaved = true; isSaved = true;

View File

@@ -22,6 +22,8 @@ using UnityEditor;
using UnityEngine; using UnityEngine;
using System.Globalization; using System.Globalization;
using System; using System;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace Editor namespace Editor
{ {
@@ -33,8 +35,9 @@ namespace Editor
private static EventModifiers loadModifier; private static EventModifiers loadModifier;
private static KeyCode[] slotKeys = new KeyCode[9]; private static KeyCode[] slotKeys = new KeyCode[9];
// Static constructor runs automatically when Unity loads or recompiles // Replaced static constructor with InitializeOnLoadMethod to avoid EditorPrefs exceptions
static CameraBookmarksTool() [InitializeOnLoadMethod]
static void Init()
{ {
LoadSettings(); LoadSettings();
SceneView.duringSceneGui += OnSceneGUI; SceneView.duringSceneGui += OnSceneGUI;
@@ -69,52 +72,130 @@ namespace Editor
} }
} }
private void OnGUI() public void CreateGUI()
{ {
GUILayout.Label("Shortcut Configuration", EditorStyles.boldLabel); VisualElement root = rootVisualElement;
EditorGUILayout.Space(); root.style.paddingTop = 15;
root.style.paddingBottom = 15;
root.style.paddingLeft = 15;
root.style.paddingRight = 15;
EditorGUI.BeginChangeCheck(); Label title = new Label("Shortcut Configuration");
title.style.fontSize = 20;
title.style.unityFontStyleAndWeight = FontStyle.Bold;
title.style.color = new StyleColor(new Color(0.3f, 0.7f, 1f));
title.style.marginBottom = 15;
root.Add(title);
// Modifier Keys Setup // Warning Box
saveModifier = (EventModifiers)EditorGUILayout.EnumFlagsField("Save Modifier", saveModifier); VisualElement warningBox = new VisualElement();
loadModifier = (EventModifiers)EditorGUILayout.EnumFlagsField("Load Modifier", loadModifier); warningBox.style.backgroundColor = new StyleColor(new Color(0.8f, 0.6f, 0.1f, 0.3f));
warningBox.style.borderLeftWidth = 4;
warningBox.style.borderLeftColor = new StyleColor(new Color(0.9f, 0.7f, 0.1f));
warningBox.style.paddingTop = 10;
warningBox.style.paddingBottom = 10;
warningBox.style.paddingLeft = 10;
warningBox.style.marginBottom = 15;
warningBox.style.display = DisplayStyle.None;
Label warningLabel = new Label("Warning: Save and Load modifiers are the SAME! This will cause conflicts.");
warningLabel.style.color = new StyleColor(new Color(0.9f, 0.8f, 0.5f));
warningLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
warningBox.Add(warningLabel);
root.Add(warningBox);
if (saveModifier == loadModifier) // Modifiers Card
{ VisualElement modifiersCard = CreateCard();
EditorGUILayout.HelpBox("Warning: Save and Load modifiers are the SAME! This will cause conflicts.", MessageType.Warning); EnumFlagsField saveField = new EnumFlagsField("Save Modifier", saveModifier);
} saveField.RegisterValueChangedCallback(evt => {
saveModifier = (EventModifiers)evt.newValue;
SaveSettings();
warningBox.style.display = (saveModifier == loadModifier) ? DisplayStyle.Flex : DisplayStyle.None;
});
modifiersCard.Add(saveField);
EditorGUILayout.Space(); EnumFlagsField loadField = new EnumFlagsField("Load Modifier", loadModifier);
GUILayout.Label("Slot Keys Assignment", EditorStyles.boldLabel); loadField.RegisterValueChangedCallback(evt => {
loadModifier = (EventModifiers)evt.newValue;
SaveSettings();
warningBox.style.display = (saveModifier == loadModifier) ? DisplayStyle.Flex : DisplayStyle.None;
});
loadField.style.marginTop = 10;
modifiersCard.Add(loadField);
warningBox.style.display = (saveModifier == loadModifier) ? DisplayStyle.Flex : DisplayStyle.None;
root.Add(modifiersCard);
// KeyCode Setup for 9 slots // Slots Section
Label slotsTitle = new Label("Slot Keys Assignment");
slotsTitle.style.fontSize = 16;
slotsTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
slotsTitle.style.color = new StyleColor(new Color(0.8f, 0.8f, 0.8f));
slotsTitle.style.marginTop = 15;
slotsTitle.style.marginBottom = 10;
root.Add(slotsTitle);
VisualElement slotsCard = CreateCard();
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
{ {
EditorGUILayout.BeginHorizontal(); int index = i;
GUILayout.Label($"Slot {i + 1}", GUILayout.Width(100)); EnumField slotField = new EnumField($"Slot {i + 1}", slotKeys[i]);
slotKeys[i] = (KeyCode)EditorGUILayout.EnumPopup(slotKeys[i]); slotField.RegisterValueChangedCallback(evt => {
EditorGUILayout.EndHorizontal(); slotKeys[index] = (KeyCode)evt.newValue;
SaveSettings();
});
if (i > 0) slotField.style.marginTop = 8;
slotsCard.Add(slotField);
} }
root.Add(slotsCard);
if (EditorGUI.EndChangeCheck())
{
SaveSettings(); // Save immediately if anything changes
}
EditorGUILayout.Space();
EditorGUILayout.Space();
// Reset Button // Reset Button
if (GUILayout.Button("Reset to Default Settings", GUILayout.Height(30))) Button resetBtn = new Button(() => {
{
saveModifier = EventModifiers.Control; saveModifier = EventModifiers.Control;
loadModifier = EventModifiers.Shift; loadModifier = EventModifiers.Shift;
for (int i = 0; i < 9; i++) slotKeys[i] = KeyCode.Alpha1 + i; for (int i = 0; i < 9; i++) slotKeys[i] = KeyCode.Alpha1 + i;
SaveSettings(); SaveSettings();
GUI.FocusControl(null); // Remove focus to refresh UI correctly
} root.Clear();
CreateGUI(); // Rebuild
});
resetBtn.text = "Reset to Default Settings";
resetBtn.style.height = 40;
resetBtn.style.marginTop = 20;
resetBtn.style.backgroundColor = new StyleColor(new Color(0.7f, 0.3f, 0.3f));
resetBtn.style.color = new StyleColor(Color.white);
resetBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
resetBtn.style.borderTopLeftRadius = 6;
resetBtn.style.borderTopRightRadius = 6;
resetBtn.style.borderBottomLeftRadius = 6;
resetBtn.style.borderBottomRightRadius = 6;
root.Add(resetBtn);
root.Add(ScovySignature.CreateSignatureBox());
}
private VisualElement CreateCard()
{
VisualElement card = new VisualElement();
card.style.backgroundColor = new StyleColor(new Color(0.18f, 0.18f, 0.18f, 0.9f));
card.style.borderTopLeftRadius = 8;
card.style.borderTopRightRadius = 8;
card.style.borderBottomLeftRadius = 8;
card.style.borderBottomRightRadius = 8;
card.style.paddingTop = 15;
card.style.paddingBottom = 15;
card.style.paddingLeft = 15;
card.style.paddingRight = 15;
card.style.borderTopWidth = 1;
card.style.borderBottomWidth = 1;
card.style.borderLeftWidth = 1;
card.style.borderRightWidth = 1;
card.style.borderTopColor = new StyleColor(new Color(0.25f, 0.25f, 0.25f));
card.style.borderBottomColor = new StyleColor(new Color(0.25f, 0.25f, 0.25f));
card.style.borderLeftColor = new StyleColor(new Color(0.25f, 0.25f, 0.25f));
card.style.borderRightColor = new StyleColor(new Color(0.25f, 0.25f, 0.25f));
return card;
} }
static void OnSceneGUI(SceneView view) static void OnSceneGUI(SceneView view)

View File

@@ -0,0 +1,454 @@
using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
[CustomEditor(typeof(CameraJumpPoints))]
public class CameraJumpPointsEditor : UnityEditor.Editor
{
private static CameraJumpPoints[] allPoints;
// Store previous pose
private static Vector3 previousPosition;
private static Quaternion previousRotation;
private static bool hasPreviousPose = false;
private static Transform currentJumpTarget = null;
[InitializeOnLoadMethod]
static void Init()
{
SceneView.duringSceneGui += OnSceneGUIStatic;
EditorApplication.hierarchyChanged += OnHierarchyChanged;
}
static void OnHierarchyChanged()
{
allPoints = Object.FindObjectsOfType<CameraJumpPoints>();
}
static void OnSceneGUIStatic(SceneView sceneView)
{
Event e = Event.current;
if (e.type == EventType.KeyDown && e.keyCode != KeyCode.None)
{
if (allPoints == null)
{
allPoints = Object.FindObjectsOfType<CameraJumpPoints>();
}
bool needsRefresh = false;
foreach (var cp in allPoints)
{
if (cp == null)
{
needsRefresh = true;
continue;
}
foreach (var pt in cp.points)
{
if (pt.key == e.keyCode && pt.ctrl == e.control && pt.alt == e.alt && pt.shift == e.shift)
{
if (pt.target == null) continue;
if (currentJumpTarget == pt.target && hasPreviousPose)
{
// Jump back
sceneView.pivot = previousPosition;
sceneView.rotation = previousRotation;
currentJumpTarget = null;
hasPreviousPose = false;
sceneView.Repaint();
}
else
{
// Save previous pose
previousPosition = sceneView.pivot;
previousRotation = sceneView.rotation;
hasPreviousPose = true;
currentJumpTarget = pt.target;
// Jump to target exactly matching camera position
sceneView.rotation = pt.target.rotation;
sceneView.pivot = pt.target.position + pt.target.forward * sceneView.cameraDistance;
sceneView.Repaint();
}
e.Use();
return;
}
}
}
if (needsRefresh)
{
allPoints = Object.FindObjectsOfType<CameraJumpPoints>();
}
}
// Lock camera movement when in View Mode
if (hasPreviousPose && currentJumpTarget != null)
{
bool isNavigating = false;
if (e.type == EventType.KeyDown)
{
if (e.keyCode == KeyCode.W || e.keyCode == KeyCode.A || e.keyCode == KeyCode.S || e.keyCode == KeyCode.D ||
e.keyCode == KeyCode.Q || e.keyCode == KeyCode.E ||
e.keyCode == KeyCode.UpArrow || e.keyCode == KeyCode.DownArrow ||
e.keyCode == KeyCode.LeftArrow || e.keyCode == KeyCode.RightArrow)
{
isNavigating = true;
}
}
else if (e.type == EventType.MouseDown || e.type == EventType.MouseDrag)
{
// Right click (1), Middle click (2), or Alt+Left click (orbit)
if (e.button == 1 || e.button == 2 || (e.button == 0 && e.alt))
{
isNavigating = true;
}
}
else if (e.type == EventType.ScrollWheel)
{
isNavigating = true;
}
if (isNavigating)
{
string hotkeyStr = "your shortcut";
if (allPoints != null)
{
foreach (var cp in allPoints)
{
if (cp == null) continue;
foreach (var pt in cp.points)
{
if (pt.target == currentJumpTarget)
{
hotkeyStr = pt.GetKeyString();
break;
}
}
}
}
sceneView.ShowNotification(new GUIContent($"View Mode Locked. Press {hotkeyStr} again to escape."));
e.Use();
}
}
}
public override VisualElement CreateInspectorGUI()
{
VisualElement root = new VisualElement();
root.style.paddingTop = 15;
root.style.paddingBottom = 15;
root.style.paddingLeft = 10;
root.style.paddingRight = 10;
// Title
Label title = new Label("Camera Bookmarks");
title.style.fontSize = 22;
title.style.unityFontStyleAndWeight = FontStyle.Bold;
title.style.marginBottom = 15;
title.style.color = new StyleColor(new Color(0.3f, 0.7f, 1f));
root.Add(title);
// Help Box Custom
VisualElement helpBox = new VisualElement();
helpBox.style.backgroundColor = new StyleColor(new Color(0.15f, 0.15f, 0.15f, 0.8f));
helpBox.style.borderLeftWidth = 4;
helpBox.style.borderLeftColor = new StyleColor(new Color(0.3f, 0.7f, 1f));
helpBox.style.borderTopRightRadius = 6;
helpBox.style.borderBottomRightRadius = 6;
helpBox.style.paddingTop = 12;
helpBox.style.paddingBottom = 12;
helpBox.style.paddingLeft = 12;
helpBox.style.paddingRight = 12;
helpBox.style.marginBottom = 20;
Label helpText = new Label("• Jump instantly via hotkeys in Scene View.\n• Press the exact same hotkey again to return.\n• Use 'Capture Current View' for quick setup.");
helpText.style.whiteSpace = WhiteSpace.Normal;
helpText.style.color = new StyleColor(new Color(0.85f, 0.85f, 0.85f));
helpBox.Add(helpText);
root.Add(helpBox);
// List Container
VisualElement listContainer = new VisualElement();
root.Add(listContainer);
SerializedProperty pointsProp = serializedObject.FindProperty("points");
System.Action rebuildList = null;
rebuildList = () => {
listContainer.Clear();
serializedObject.Update();
for (int i = 0; i < pointsProp.arraySize; i++)
{
int index = i;
SerializedProperty pointProp = pointsProp.GetArrayElementAtIndex(index);
// Card UI
VisualElement card = new VisualElement();
card.style.backgroundColor = new StyleColor(new Color(0.2f, 0.2f, 0.2f, 0.9f));
card.style.borderTopLeftRadius = 8;
card.style.borderTopRightRadius = 8;
card.style.borderBottomLeftRadius = 8;
card.style.borderBottomRightRadius = 8;
card.style.paddingTop = 15;
card.style.paddingBottom = 15;
card.style.paddingLeft = 15;
card.style.paddingRight = 15;
card.style.marginBottom = 12;
// Subtle shadow/border
card.style.borderTopWidth = 1;
card.style.borderBottomWidth = 1;
card.style.borderLeftWidth = 1;
card.style.borderRightWidth = 1;
card.style.borderTopColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderBottomColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderLeftColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderRightColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
// Header
VisualElement header = new VisualElement();
header.style.flexDirection = FlexDirection.Row;
header.style.justifyContent = Justify.SpaceBetween;
header.style.marginBottom = 12;
PropertyField nameField = new PropertyField(pointProp.FindPropertyRelative("name"), "");
nameField.style.flexGrow = 1;
nameField.style.unityFontStyleAndWeight = FontStyle.Bold;
Button deleteBtn = new Button(() => {
pointsProp.DeleteArrayElementAtIndex(index);
serializedObject.ApplyModifiedProperties();
rebuildList();
});
deleteBtn.text = "✕";
deleteBtn.style.backgroundColor = new StyleColor(new Color(0.8f, 0.25f, 0.25f, 0.9f));
deleteBtn.style.color = new StyleColor(Color.white);
deleteBtn.style.borderTopLeftRadius = 4;
deleteBtn.style.borderTopRightRadius = 4;
deleteBtn.style.borderBottomLeftRadius = 4;
deleteBtn.style.borderBottomRightRadius = 4;
deleteBtn.style.width = 24;
deleteBtn.style.height = 24;
deleteBtn.style.marginLeft = 15;
deleteBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
header.Add(nameField);
header.Add(deleteBtn);
card.Add(header);
// Target Row with Sync button
VisualElement targetRow = new VisualElement();
targetRow.style.flexDirection = FlexDirection.Row;
targetRow.style.marginBottom = 12;
PropertyField targetField = new PropertyField(pointProp.FindPropertyRelative("target"), "Target Object");
targetField.style.flexGrow = 1;
targetRow.Add(targetField);
Button syncBtn = new Button(() => {
SceneView sv = SceneView.lastActiveSceneView;
if (sv != null && sv.camera != null) {
Transform t = (Transform)pointProp.FindPropertyRelative("target").objectReferenceValue;
if (t != null) {
Undo.RecordObject(t, "Sync Target View");
t.position = sv.camera.transform.position;
t.rotation = sv.camera.transform.rotation;
}
}
});
syncBtn.text = "Sync to Scene";
syncBtn.tooltip = "Updates this object's transform to match your current Scene View.";
syncBtn.style.marginLeft = 10;
syncBtn.style.paddingLeft = 8;
syncBtn.style.paddingRight = 8;
syncBtn.style.borderTopLeftRadius = 4;
syncBtn.style.borderTopRightRadius = 4;
syncBtn.style.borderBottomLeftRadius = 4;
syncBtn.style.borderBottomRightRadius = 4;
syncBtn.style.backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f));
targetRow.Add(syncBtn);
card.Add(targetRow);
// Key binding Row
VisualElement keyRow = new VisualElement();
keyRow.style.flexDirection = FlexDirection.Row;
keyRow.style.alignItems = Align.Center;
Label keyLabel = new Label("Shortcut Key");
keyLabel.style.width = 120;
keyRow.Add(keyLabel);
Button recordBtn = new Button();
recordBtn.style.flexGrow = 1;
recordBtn.style.height = 30;
recordBtn.style.borderTopLeftRadius = 6;
recordBtn.style.borderTopRightRadius = 6;
recordBtn.style.borderBottomLeftRadius = 6;
recordBtn.style.borderBottomRightRadius = 6;
recordBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
System.Action updateBtnText = () => {
SerializedProperty keyP = pointProp.FindPropertyRelative("key");
SerializedProperty cP = pointProp.FindPropertyRelative("ctrl");
SerializedProperty aP = pointProp.FindPropertyRelative("alt");
SerializedProperty sP = pointProp.FindPropertyRelative("shift");
if ((KeyCode)keyP.intValue == KeyCode.None) {
recordBtn.text = "Not Set (Click to Record)";
recordBtn.style.backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f));
} else {
string s = "";
if (cP.boolValue) s += "Ctrl + ";
if (aP.boolValue) s += "Alt + ";
if (sP.boolValue) s += "Shift + ";
s += ((KeyCode)keyP.intValue).ToString();
recordBtn.text = s;
recordBtn.style.backgroundColor = new StyleColor(new Color(0.15f, 0.45f, 0.8f));
}
};
updateBtnText();
bool isRecording = false;
recordBtn.clicked += () => {
if (isRecording) {
isRecording = false;
updateBtnText();
return;
}
isRecording = true;
recordBtn.text = "Press any key... (ESC to cancel)";
recordBtn.style.backgroundColor = new StyleColor(new Color(0.8f, 0.4f, 0.1f));
recordBtn.Focus();
};
recordBtn.RegisterCallback<KeyDownEvent>((evt) => {
if (!isRecording) return;
if (evt.keyCode == KeyCode.Escape) {
isRecording = false;
updateBtnText();
evt.StopPropagation();
return;
}
if (evt.keyCode != KeyCode.None &&
evt.keyCode != KeyCode.LeftAlt && evt.keyCode != KeyCode.RightAlt &&
evt.keyCode != KeyCode.LeftControl && evt.keyCode != KeyCode.RightControl &&
evt.keyCode != KeyCode.LeftShift && evt.keyCode != KeyCode.RightShift &&
evt.keyCode != KeyCode.LeftCommand && evt.keyCode != KeyCode.RightCommand)
{
pointProp.FindPropertyRelative("key").intValue = (int)evt.keyCode;
pointProp.FindPropertyRelative("ctrl").boolValue = evt.ctrlKey;
pointProp.FindPropertyRelative("alt").boolValue = evt.altKey;
pointProp.FindPropertyRelative("shift").boolValue = evt.shiftKey;
serializedObject.ApplyModifiedProperties();
isRecording = false;
updateBtnText();
evt.StopPropagation();
}
});
recordBtn.focusable = true;
keyRow.Add(recordBtn);
card.Add(keyRow);
listContainer.Add(card);
}
// Buttons layout
VisualElement buttonsRow = new VisualElement();
buttonsRow.style.flexDirection = FlexDirection.Row;
buttonsRow.style.marginTop = 15;
// Capture Current View Button
Button captureBtn = new Button(() => {
SceneView sv = SceneView.lastActiveSceneView;
if (sv != null && sv.camera != null) {
GameObject go = new GameObject("Camera Point " + (pointsProp.arraySize + 1));
CameraJumpPoints tgt = (CameraJumpPoints)target;
go.transform.SetParent(tgt.transform);
go.transform.position = sv.camera.transform.position;
go.transform.rotation = sv.camera.transform.rotation;
Undo.RegisterCreatedObjectUndo(go, "Capture Camera Point");
pointsProp.arraySize++;
SerializedProperty newElem = pointsProp.GetArrayElementAtIndex(pointsProp.arraySize - 1);
newElem.FindPropertyRelative("name").stringValue = go.name;
newElem.FindPropertyRelative("target").objectReferenceValue = go.transform;
newElem.FindPropertyRelative("key").intValue = (int)KeyCode.None;
newElem.FindPropertyRelative("ctrl").boolValue = false;
newElem.FindPropertyRelative("alt").boolValue = false;
newElem.FindPropertyRelative("shift").boolValue = false;
serializedObject.ApplyModifiedProperties();
rebuildList();
} else {
Debug.LogWarning("No active Scene View found to capture.");
}
});
captureBtn.text = "+ Capture Scene View";
captureBtn.style.flexGrow = 1;
captureBtn.style.height = 40;
captureBtn.style.fontSize = 14;
captureBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
captureBtn.style.backgroundColor = new StyleColor(new Color(0.25f, 0.65f, 0.4f));
captureBtn.style.color = new StyleColor(Color.white);
captureBtn.style.borderTopLeftRadius = 8;
captureBtn.style.borderTopRightRadius = 8;
captureBtn.style.borderBottomLeftRadius = 8;
captureBtn.style.borderBottomRightRadius = 8;
captureBtn.style.marginRight = 5;
// Add Empty Button
Button addEmptyBtn = new Button(() => {
pointsProp.arraySize++;
SerializedProperty newElem = pointsProp.GetArrayElementAtIndex(pointsProp.arraySize - 1);
newElem.FindPropertyRelative("name").stringValue = "New Empty " + pointsProp.arraySize;
newElem.FindPropertyRelative("target").objectReferenceValue = null;
newElem.FindPropertyRelative("key").intValue = (int)KeyCode.None;
newElem.FindPropertyRelative("ctrl").boolValue = false;
newElem.FindPropertyRelative("alt").boolValue = false;
newElem.FindPropertyRelative("shift").boolValue = false;
serializedObject.ApplyModifiedProperties();
rebuildList();
});
addEmptyBtn.text = "Add Empty";
addEmptyBtn.style.width = 100;
addEmptyBtn.style.height = 40;
addEmptyBtn.style.borderTopLeftRadius = 8;
addEmptyBtn.style.borderTopRightRadius = 8;
addEmptyBtn.style.borderBottomLeftRadius = 8;
addEmptyBtn.style.borderBottomRightRadius = 8;
buttonsRow.Add(captureBtn);
buttonsRow.Add(addEmptyBtn);
listContainer.Add(buttonsRow);
};
rebuildList();
// Listen for Unity serialization changes (e.g. Undo/Redo)
root.TrackPropertyValue(pointsProp, (prop) => {
rebuildList();
});
root.Add(Editor.ScovySignature.CreateSignatureBox());
return root;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6418c2e4db0af4342add5271469ded58

View File

@@ -37,7 +37,7 @@ namespace Editor
private float maxTilt = 5f; private float maxTilt = 5f;
private bool uniformScale = true; private bool uniformScale = true;
[MenuItem("Tools/Level Decorator (Chaos Maker)")] [MenuItem("Tools/Level Decorator")]
public static void ShowWindow() public static void ShowWindow()
{ {
GetWindow<LevelDecorator>("Chaos Maker"); GetWindow<LevelDecorator>("Chaos Maker");

View File

@@ -26,6 +26,8 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace Editor namespace Editor
{ {
@@ -40,8 +42,8 @@ namespace Editor
private static EventModifiers playModifier; private static EventModifiers playModifier;
private static KeyCode playKey; private static KeyCode playKey;
// Static constructor runs automatically when Unity loads or recompiles [InitializeOnLoadMethod]
static PlayFromHereTool() static void Init()
{ {
LoadSettings(); LoadSettings();
// Subscribe to SceneView GUI to listen for keyboard inputs // Subscribe to SceneView GUI to listen for keyboard inputs
@@ -72,52 +74,149 @@ namespace Editor
EditorPrefs.SetInt("PFH_PlayKey", (int)playKey); EditorPrefs.SetInt("PFH_PlayKey", (int)playKey);
} }
private void OnGUI() public void CreateGUI()
{ {
GUILayout.Label("Shortcut Configuration", EditorStyles.boldLabel); VisualElement root = rootVisualElement;
EditorGUILayout.Space(); root.style.paddingTop = 15;
root.style.paddingBottom = 15;
root.style.paddingLeft = 15;
root.style.paddingRight = 15;
EditorGUI.BeginChangeCheck(); Label title = new Label("Shortcut Configuration");
title.style.fontSize = 22;
title.style.unityFontStyleAndWeight = FontStyle.Bold;
title.style.color = new StyleColor(new Color(0.3f, 0.7f, 1f));
title.style.marginBottom = 15;
root.Add(title);
// Section for Mode 1 // Warning Box for Conflicts
EditorGUILayout.BeginVertical("box"); VisualElement warningBox = new VisualElement();
GUILayout.Label("Mode 1: Teleport Only", EditorStyles.boldLabel); warningBox.style.backgroundColor = new StyleColor(new Color(0.8f, 0.2f, 0.2f, 0.3f));
teleportModifier = (EventModifiers)EditorGUILayout.EnumFlagsField("Modifier Keys", teleportModifier); warningBox.style.borderLeftWidth = 4;
teleportKey = (KeyCode)EditorGUILayout.EnumPopup("Main Key", teleportKey); warningBox.style.borderLeftColor = new StyleColor(new Color(0.9f, 0.3f, 0.3f));
EditorGUILayout.EndVertical(); warningBox.style.paddingTop = 10;
warningBox.style.paddingBottom = 10;
warningBox.style.paddingLeft = 10;
warningBox.style.marginBottom = 15;
warningBox.style.display = DisplayStyle.None;
Label warningLabel = new Label("Conflict: Mode 1 and Mode 2 have the same hotkey!");
warningLabel.style.color = new StyleColor(new Color(0.9f, 0.5f, 0.5f));
warningLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
warningBox.Add(warningLabel);
root.Add(warningBox);
EditorGUILayout.Space(); System.Action checkConflicts = () => {
bool conflict = (teleportModifier == playModifier && teleportKey == playKey);
warningBox.style.display = conflict ? DisplayStyle.Flex : DisplayStyle.None;
};
// Section for Mode 2 // Mode 1 Card
EditorGUILayout.BeginVertical("box"); Label mode1Title = new Label("Mode 1: Teleport Only");
GUILayout.Label("Mode 2: Play From Here (Teleport + Play)", EditorStyles.boldLabel); mode1Title.style.fontSize = 16;
playModifier = (EventModifiers)EditorGUILayout.EnumFlagsField("Modifier Keys", playModifier); mode1Title.style.unityFontStyleAndWeight = FontStyle.Bold;
playKey = (KeyCode)EditorGUILayout.EnumPopup("Main Key", playKey); mode1Title.style.color = new StyleColor(new Color(0.8f, 0.8f, 0.8f));
EditorGUILayout.EndVertical(); mode1Title.style.marginBottom = 10;
root.Add(mode1Title);
if (EditorGUI.EndChangeCheck()) VisualElement card1 = CreateCard();
{ EnumFlagsField tMod = new EnumFlagsField("Modifier Keys", teleportModifier);
tMod.RegisterValueChangedCallback(evt => {
teleportModifier = (EventModifiers)evt.newValue;
SaveSettings(); SaveSettings();
} checkConflicts();
});
card1.Add(tMod);
// Conflict warning EnumField tKey = new EnumField("Main Key", teleportKey);
if (teleportModifier == playModifier && teleportKey == playKey) tKey.RegisterValueChangedCallback(evt => {
{ teleportKey = (KeyCode)evt.newValue;
EditorGUILayout.HelpBox("Conflict: Mode 1 and Mode 2 have the same hotkey!", MessageType.Error); SaveSettings();
} checkConflicts();
});
tKey.style.marginTop = 10;
card1.Add(tKey);
root.Add(card1);
EditorGUILayout.Space(); // Mode 2 Card
EditorGUILayout.Space(); Label mode2Title = new Label("Mode 2: Play From Here (Teleport + Play)");
mode2Title.style.fontSize = 16;
mode2Title.style.unityFontStyleAndWeight = FontStyle.Bold;
mode2Title.style.color = new StyleColor(new Color(0.8f, 0.8f, 0.8f));
mode2Title.style.marginTop = 15;
mode2Title.style.marginBottom = 10;
root.Add(mode2Title);
if (GUILayout.Button("Reset to Defaults", GUILayout.Height(30))) VisualElement card2 = CreateCard();
{ EnumFlagsField pMod = new EnumFlagsField("Modifier Keys", playModifier);
pMod.RegisterValueChangedCallback(evt => {
playModifier = (EventModifiers)evt.newValue;
SaveSettings();
checkConflicts();
});
card2.Add(pMod);
EnumField pKey = new EnumField("Main Key", playKey);
pKey.RegisterValueChangedCallback(evt => {
playKey = (KeyCode)evt.newValue;
SaveSettings();
checkConflicts();
});
pKey.style.marginTop = 10;
card2.Add(pKey);
root.Add(card2);
checkConflicts();
// Reset Button
Button resetBtn = new Button(() => {
teleportModifier = EventModifiers.Control | EventModifiers.Alt; teleportModifier = EventModifiers.Control | EventModifiers.Alt;
teleportKey = KeyCode.P; teleportKey = KeyCode.P;
playModifier = EventModifiers.Control | EventModifiers.Alt | EventModifiers.Shift; playModifier = EventModifiers.Control | EventModifiers.Alt | EventModifiers.Shift;
playKey = KeyCode.P; playKey = KeyCode.P;
SaveSettings(); SaveSettings();
GUI.FocusControl(null);
} root.Clear();
CreateGUI(); // Rebuild
});
resetBtn.text = "Reset to Defaults";
resetBtn.style.height = 40;
resetBtn.style.marginTop = 20;
resetBtn.style.backgroundColor = new StyleColor(new Color(0.7f, 0.3f, 0.3f));
resetBtn.style.color = new StyleColor(Color.white);
resetBtn.style.fontSize = 14;
resetBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
resetBtn.style.borderTopLeftRadius = 6;
resetBtn.style.borderTopRightRadius = 6;
resetBtn.style.borderBottomLeftRadius = 6;
resetBtn.style.borderBottomRightRadius = 6;
root.Add(resetBtn);
root.Add(ScovySignature.CreateSignatureBox());
}
private VisualElement CreateCard()
{
VisualElement card = new VisualElement();
card.style.backgroundColor = new StyleColor(new Color(0.18f, 0.18f, 0.18f, 0.9f));
card.style.borderTopLeftRadius = 10;
card.style.borderTopRightRadius = 10;
card.style.borderBottomLeftRadius = 10;
card.style.borderBottomRightRadius = 10;
card.style.paddingTop = 15;
card.style.paddingBottom = 15;
card.style.paddingLeft = 15;
card.style.paddingRight = 15;
card.style.borderTopWidth = 1;
card.style.borderBottomWidth = 1;
card.style.borderLeftWidth = 1;
card.style.borderRightWidth = 1;
card.style.borderTopColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderBottomColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderLeftColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderRightColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
return card;
} }
private static void OnSceneGUI(SceneView view) private static void OnSceneGUI(SceneView view)

View File

@@ -26,6 +26,8 @@ using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityEditor.SceneManagement; using UnityEditor.SceneManagement;
using System.IO; using System.IO;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace Editor namespace Editor
{ {
@@ -41,55 +43,69 @@ namespace Editor
window.minSize = new Vector2(300, 450); window.minSize = new Vector2(300, 450);
} }
private void OnGUI() public void CreateGUI()
{ {
EditorGUILayout.Space(); VisualElement root = rootVisualElement;
root.style.paddingTop = 15;
root.style.paddingBottom = 15;
root.style.paddingLeft = 15;
root.style.paddingRight = 15;
DrawPlaySection(); // Header
EditorGUILayout.Space(15); Label title = new Label("Project Dashboard");
title.style.fontSize = 22;
DrawSceneNavigation(); title.style.unityFontStyleAndWeight = FontStyle.Bold;
EditorGUILayout.Space(15); title.style.color = new StyleColor(new Color(0.3f, 0.7f, 1f));
title.style.marginBottom = 15;
DrawDataManagement(); root.Add(title);
}
private void DrawPlaySection() // Quick Play Card
{ VisualElement playCard = CreateCard();
GUILayout.Label("QUICK PLAY", EditorStyles.boldLabel); Label playTitle = new Label("QUICK PLAY");
EditorGUILayout.BeginVertical("box"); playTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
playTitle.style.marginBottom = 10;
playCard.Add(playTitle);
// Green Play Button Button playBtn = new Button(() => PlayFromBootScene());
Color oldColor = GUI.backgroundColor; playBtn.text = "▶ PLAY GAME (From Boot Scene)";
GUI.backgroundColor = new Color(0.4f, 1f, 0.4f); // Light Green playBtn.style.height = 40;
playBtn.style.backgroundColor = new StyleColor(new Color(0.2f, 0.6f, 0.3f));
playBtn.style.color = new StyleColor(Color.white);
playBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
playBtn.style.borderTopLeftRadius = 6;
playBtn.style.borderTopRightRadius = 6;
playBtn.style.borderBottomLeftRadius = 6;
playBtn.style.borderBottomRightRadius = 6;
playCard.Add(playBtn);
if (GUILayout.Button("▶ PLAY GAME (From Boot Scene)", GUILayout.Height(40))) Label helpText = new Label("Automatically saves, loads the first scene in Build Settings, and presses Play.");
{ helpText.style.color = new StyleColor(new Color(0.6f, 0.6f, 0.6f));
PlayFromBootScene(); helpText.style.marginTop = 10;
} helpText.style.whiteSpace = WhiteSpace.Normal;
playCard.Add(helpText);
GUI.backgroundColor = oldColor; root.Add(playCard);
EditorGUILayout.HelpBox("Automatically saves your current scene, loads the first scene in Build Settings, and presses Play.", MessageType.Info);
EditorGUILayout.EndVertical();
}
private void DrawSceneNavigation() // Scene Navigation
{ VisualElement navCard = CreateCard();
GUILayout.Label("SCENE NAVIGATION (Build Settings)", EditorStyles.boldLabel); navCard.style.marginTop = 15;
EditorGUILayout.BeginVertical("box"); Label navTitle = new Label("SCENE NAVIGATION (Build Settings)");
navTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
navTitle.style.marginBottom = 10;
navCard.Add(navTitle);
// Fetch scenes dynamically from Build Settings ScrollView scrollView = new ScrollView();
scrollView.style.maxHeight = 200;
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes; EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
if (scenes.Length == 0) if (scenes.Length == 0)
{ {
EditorGUILayout.HelpBox("No scenes found in Build Settings! Please go to File -> Build Settings and add your scenes.", MessageType.Warning); Label warn = new Label("No scenes found in Build Settings! Please go to File -> Build Settings.");
warn.style.color = new StyleColor(new Color(0.9f, 0.7f, 0.2f));
warn.style.whiteSpace = WhiteSpace.Normal;
navCard.Add(warn);
} }
else else
{ {
sceneScrollPos = EditorGUILayout.BeginScrollView(sceneScrollPos, GUILayout.MaxHeight(200));
for (int i = 0; i < scenes.Length; i++) for (int i = 0; i < scenes.Length; i++)
{ {
if (scenes[i].enabled) if (scenes[i].enabled)
@@ -97,41 +113,51 @@ namespace Editor
string scenePath = scenes[i].path; string scenePath = scenes[i].path;
string sceneName = Path.GetFileNameWithoutExtension(scenePath); string sceneName = Path.GetFileNameWithoutExtension(scenePath);
EditorGUILayout.BeginHorizontal(); VisualElement row = new VisualElement();
GUILayout.Label($"[{i}]", GUILayout.Width(25)); row.style.flexDirection = FlexDirection.Row;
row.style.marginBottom = 5;
row.style.alignItems = Align.Center;
Label indexLbl = new Label($"[{i}]");
indexLbl.style.width = 30;
indexLbl.style.unityTextAlign = TextAnchor.MiddleLeft;
Button loadBtn = new Button(() => OpenScene(scenePath));
loadBtn.text = $"Load {sceneName}";
loadBtn.style.flexGrow = 1;
loadBtn.style.height = 25;
loadBtn.style.borderTopLeftRadius = 4;
loadBtn.style.borderTopRightRadius = 4;
loadBtn.style.borderBottomLeftRadius = 4;
loadBtn.style.borderBottomRightRadius = 4;
if (GUILayout.Button($"Load {sceneName}", GUILayout.Height(25))) row.Add(indexLbl);
{ row.Add(loadBtn);
OpenScene(scenePath); scrollView.Add(row);
}
EditorGUILayout.EndHorizontal();
} }
} }
navCard.Add(scrollView);
EditorGUILayout.EndScrollView();
} }
root.Add(navCard);
EditorGUILayout.EndVertical(); // Data Management
} VisualElement dataCard = CreateCard();
dataCard.style.marginTop = 15;
Label dataTitle = new Label("DATA MANAGEMENT");
dataTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
dataTitle.style.marginBottom = 10;
dataCard.Add(dataTitle);
private void DrawDataManagement() Button folderBtn = new Button(() => EditorUtility.RevealInFinder(Application.persistentDataPath));
{ folderBtn.text = "Open Save Folder (Explorer/Finder)";
GUILayout.Label("DATA MANAGEMENT", EditorStyles.boldLabel); folderBtn.style.height = 30;
EditorGUILayout.BeginVertical("box"); folderBtn.style.borderTopLeftRadius = 4;
folderBtn.style.borderTopRightRadius = 4;
folderBtn.style.borderBottomLeftRadius = 4;
folderBtn.style.borderBottomRightRadius = 4;
dataCard.Add(folderBtn);
if (GUILayout.Button("Open Save Folder (Explorer/Finder)", GUILayout.Height(30))) Button clearBtn = new Button(() => {
{
EditorUtility.RevealInFinder(Application.persistentDataPath);
}
EditorGUILayout.Space(5);
// Red Delete Button
Color oldColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(1f, 0.4f, 0.4f); // Light Red
if (GUILayout.Button("⚠ Clear PlayerPrefs & Save Data", GUILayout.Height(35)))
{
if (EditorUtility.DisplayDialog( if (EditorUtility.DisplayDialog(
"Clear All Data?", "Clear All Data?",
"Are you sure you want to delete all PlayerPrefs and JSON save files?\nThis action cannot be undone.", "Are you sure you want to delete all PlayerPrefs and JSON save files?\nThis action cannot be undone.",
@@ -140,10 +166,46 @@ namespace Editor
{ {
ClearAllData(); ClearAllData();
} }
} });
clearBtn.text = "⚠ Clear PlayerPrefs & Save Data";
clearBtn.style.height = 35;
clearBtn.style.marginTop = 10;
clearBtn.style.backgroundColor = new StyleColor(new Color(0.7f, 0.3f, 0.3f));
clearBtn.style.color = new StyleColor(Color.white);
clearBtn.style.unityFontStyleAndWeight = FontStyle.Bold;
clearBtn.style.borderTopLeftRadius = 6;
clearBtn.style.borderTopRightRadius = 6;
clearBtn.style.borderBottomLeftRadius = 6;
clearBtn.style.borderBottomRightRadius = 6;
dataCard.Add(clearBtn);
GUI.backgroundColor = oldColor; root.Add(dataCard);
EditorGUILayout.EndVertical();
root.Add(ScovySignature.CreateSignatureBox());
}
private VisualElement CreateCard()
{
VisualElement card = new VisualElement();
card.style.backgroundColor = new StyleColor(new Color(0.18f, 0.18f, 0.18f, 0.9f));
card.style.borderTopLeftRadius = 10;
card.style.borderTopRightRadius = 10;
card.style.borderBottomLeftRadius = 10;
card.style.borderBottomRightRadius = 10;
card.style.paddingTop = 15;
card.style.paddingBottom = 15;
card.style.paddingLeft = 15;
card.style.paddingRight = 15;
card.style.borderTopWidth = 1;
card.style.borderBottomWidth = 1;
card.style.borderLeftWidth = 1;
card.style.borderRightWidth = 1;
card.style.borderTopColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderBottomColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderLeftColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
card.style.borderRightColor = new StyleColor(new Color(0.12f, 0.12f, 0.12f));
return card;
} }
private void PlayFromBootScene() private void PlayFromBootScene()

View File

@@ -0,0 +1,82 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using System.IO;
namespace Editor
{
public static class ScovySignature
{
public static VisualElement CreateSignatureBox()
{
VisualElement signatureBox = new VisualElement();
signatureBox.style.marginTop = 25;
signatureBox.style.paddingTop = 15;
signatureBox.style.paddingBottom = 10;
signatureBox.style.borderTopWidth = 1;
signatureBox.style.borderTopColor = new StyleColor(new Color(0.25f, 0.25f, 0.25f));
signatureBox.style.alignItems = Align.Center;
Label creatorLabel = new Label("Created by Scovy");
creatorLabel.style.fontSize = 14;
creatorLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
creatorLabel.style.color = new StyleColor(new Color(0.4f, 0.8f, 1f));
signatureBox.Add(creatorLabel);
// Load ascii art from catgirl.txt
string asciiText = " /\\_/\\ \n ( o.o ) \n > ^ < "; // Fallback
// Search for the text asset anywhere in the project
string[] guids = AssetDatabase.FindAssets("catgirl t:TextAsset");
if (guids.Length > 0)
{
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
TextAsset txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
if (txtAsset != null)
{
asciiText = txtAsset.text;
}
}
else
{
// Fallback attempt to read directly if Unity hasn't indexed it yet
string directPath = Path.Combine(Application.dataPath, "Editors/catgirl.txt");
if (File.Exists(directPath))
{
asciiText = File.ReadAllText(directPath);
}
}
// Prevent Unity from stripping leading spaces by replacing them with non-breaking spaces
asciiText = asciiText.Replace(" ", "\u00A0");
Label asciiArt = new Label(asciiText);
asciiArt.style.whiteSpace = WhiteSpace.Pre;
asciiArt.style.color = new StyleColor(new Color(0.5f, 0.5f, 0.5f));
asciiArt.style.marginTop = 5;
asciiArt.style.unityTextAlign = TextAnchor.MiddleCenter;
// Increased font size based on feedback
asciiArt.style.fontSize = 10;
// Attempt to load an OS system font that supports Braille characters (like MS Gothic or Segoe UI Symbol)
Font osFont = Font.CreateDynamicFontFromOSFont(new string[] { "MS Gothic", "Segoe UI Symbol", "Consolas", "Arial" }, 10);
if (osFont != null)
{
// In newer Unity versions unityFontDefinition is preferred
asciiArt.style.unityFontDefinition = new StyleFontDefinition(osFont);
}
// Also add a scrollview wrapper just in case it's still too large
ScrollView scrollWrapper = new ScrollView();
scrollWrapper.style.maxHeight = 250; // Increased height to accommodate larger font
scrollWrapper.style.marginTop = 5;
scrollWrapper.contentContainer.style.alignItems = Align.Center;
scrollWrapper.Add(asciiArt);
signatureBox.Add(scrollWrapper);
return signatureBox;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e111b033e887ade4b8a2459210a0df00

View File

@@ -45,80 +45,74 @@ namespace Editor
private static void OnSceneGUI(SceneView sceneView) private static void OnSceneGUI(SceneView sceneView)
{ {
// Only display the panel when the game is actually running
if (!Application.isPlaying) return; if (!Application.isPlaying) return;
Handles.BeginGUI(); Handles.BeginGUI();
// Calculate center-top position dynamically based on current Scene View size float panelWidth = 460f;
float posX = (sceneView.position.width - PANEL_WIDTH) / 2f; float panelHeight = 40f;
float posY = 15f; float posX = (sceneView.position.width - panelWidth) / 2f;
Rect panelRect = new Rect(posX, posY, PANEL_WIDTH, PANEL_HEIGHT); float posY = 20f;
Rect panelRect = new Rect(posX, posY, panelWidth, panelHeight);
// Draw the main background box // Sleek semi-transparent dark background
GUI.Box(panelRect, GUIContent.none, EditorStyles.helpBox); EditorGUI.DrawRect(panelRect, new Color(0.1f, 0.1f, 0.1f, 0.85f));
GUILayout.BeginArea(new Rect(posX + 10, posY + 10, PANEL_WIDTH - 20, PANEL_HEIGHT - 20));
// --- 1. HEADER (Title & Current Speed) ---
GUIStyle headerStyle = new GUIStyle(EditorStyles.boldLabel)
{
richText = true,
alignment = TextAnchor.MiddleCenter,
fontSize = 13
};
// Format the time scale to show 2 decimal places // Thin accent line at the top
EditorGUI.DrawRect(new Rect(posX, posY, panelWidth, 2), new Color(0.3f, 0.7f, 1f, 0.8f));
GUILayout.BeginArea(new Rect(posX + 10, posY + 8, panelWidth - 20, panelHeight - 16));
GUILayout.BeginHorizontal();
// --- 1. HEADER (Current Speed) ---
string currentSpeedText = EditorApplication.isPaused ? "<color=#FF6B6B>PAUSED</color>" : $"<color=#4ECDC4>{Time.timeScale:F2}x</color>"; string currentSpeedText = EditorApplication.isPaused ? "<color=#FF6B6B>PAUSED</color>" : $"<color=#4ECDC4>{Time.timeScale:F2}x</color>";
GUILayout.Label($"⏳ <b>TIME LORD</b> | Current: {currentSpeedText}", headerStyle); GUILayout.Label($"⏳ {currentSpeedText}", new GUIStyle(EditorStyles.boldLabel) { richText = true, fontSize = 13, alignment = TextAnchor.MiddleLeft }, GUILayout.Width(80));
GUILayout.Space(5);
// --- 2. TIME SLIDER (Fine-tune control) --- // --- 2. TIME SLIDER (Fine-tune control) ---
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
float newTimeScale = GUILayout.HorizontalSlider(Time.timeScale, 0f, 10f); float newTimeScale = GUILayout.HorizontalSlider(Time.timeScale, 0f, 10f, GUILayout.Width(80), GUILayout.Height(20));
if (EditorGUI.EndChangeCheck()) if (EditorGUI.EndChangeCheck())
{ {
Time.timeScale = newTimeScale; Time.timeScale = newTimeScale;
// Auto-resume if adjusting slider while paused
if (EditorApplication.isPaused && newTimeScale > 0f) if (EditorApplication.isPaused && newTimeScale > 0f)
{ {
EditorApplication.isPaused = false; EditorApplication.isPaused = false;
} }
} }
GUILayout.Space(5);
GUILayout.Space(15);
// --- 3. PRESET SPEED BUTTONS --- // --- 3. PRESET SPEED BUTTONS ---
GUILayout.BeginHorizontal(); DrawSpeedButton("0.5x", 0.5f, 35);
DrawSpeedButton("0.1x", 0.1f); DrawSpeedButton("1x", 1f, 30);
DrawSpeedButton("0.5x", 0.5f); DrawSpeedButton("2x", 2f, 30);
DrawSpeedButton("1x", 1f); DrawSpeedButton("5x", 5f, 30);
DrawSpeedButton("2x", 2f);
DrawSpeedButton("5x", 5f);
GUILayout.EndHorizontal();
GUILayout.Space(5); GUILayout.FlexibleSpace();
// --- 4. PAUSE / RESUME BUTTON --- // --- 4. PAUSE / RESUME BUTTON ---
Color oldBgColor = GUI.backgroundColor; Color oldBgColor = GUI.backgroundColor;
GUI.backgroundColor = EditorApplication.isPaused ? new Color(1f, 0.4f, 0.4f) : new Color(0.9f, 0.9f, 0.9f); GUI.backgroundColor = EditorApplication.isPaused ? new Color(1f, 0.4f, 0.4f) : new Color(0.8f, 0.8f, 0.8f);
string pauseLabel = EditorApplication.isPaused ? "▶ RESUME GAME" : "⏸ PAUSE GAME"; string pauseLabel = EditorApplication.isPaused ? "▶ RESUME" : "⏸ PAUSE";
GUIStyle pauseStyle = new GUIStyle(GUI.skin.button) { fontStyle = FontStyle.Bold }; GUIStyle pauseStyle = new GUIStyle(GUI.skin.button) { fontStyle = FontStyle.Bold };
if (GUILayout.Button(pauseLabel, pauseStyle, GUILayout.Height(25))) if (GUILayout.Button(pauseLabel, pauseStyle, GUILayout.Width(80), GUILayout.Height(24)))
{ {
EditorApplication.isPaused = !EditorApplication.isPaused; EditorApplication.isPaused = !EditorApplication.isPaused;
} }
GUI.backgroundColor = oldBgColor; GUI.backgroundColor = oldBgColor;
GUILayout.EndHorizontal();
GUILayout.EndArea(); GUILayout.EndArea();
Handles.EndGUI(); Handles.EndGUI();
} }
/// <summary> /// <summary>
/// Draws a preset button that automatically highlights green if it matches the current time scale. /// Draws a preset button that automatically highlights green if it matches the current time scale.
/// </summary> /// </summary>
private static void DrawSpeedButton(string label, float targetSpeed) private static void DrawSpeedButton(string label, float targetSpeed, float width)
{ {
Color oldBgColor = GUI.backgroundColor; Color oldBgColor = GUI.backgroundColor;
@@ -129,7 +123,7 @@ namespace Editor
GUI.backgroundColor = new Color(0.4f, 1f, 0.4f); // Light Green GUI.backgroundColor = new Color(0.4f, 1f, 0.4f); // Light Green
} }
if (GUILayout.Button(label, GUILayout.Height(22))) if (GUILayout.Button(label, GUILayout.Width(width), GUILayout.Height(24)))
{ {
Time.timeScale = targetSpeed; Time.timeScale = targetSpeed;

View File

@@ -0,0 +1,4 @@
|、
(˚ˎ 。7
|、˜〵
じしˍ,)

View File

@@ -1,7 +1,6 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: e6a10948eca4f3f4eaeda0611c778875 guid: c1243462c0117614cba30fe64aa5d2b0
folderAsset: yes TextScriptImporter:
DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:
assetBundleName: assetBundleName:

View File

@@ -1,66 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5ddbd92dcd1357e48867cd8dd4822572, type: 3}
m_Name: ArrowLifeSettings
m_EditorClassIdentifier:
bulletLostLifeList:
- layers:
serializedVersion: 2
m_Bits: 1
tags:
- Metal
- Concrete
reduceLife: 90
ricochet: 1
maxThicknessToCross: 0.2
damageReducePercentage: 100
minChangeTrajectory: 0
maxChangeTrajectory: 0
- layers:
serializedVersion: 2
m_Bits: 1
tags:
- Untagged
- Dirt
- Barrel
reduceLife: 50
ricochet: 0
maxThicknessToCross: 0.2
damageReducePercentage: 100
minChangeTrajectory: 3.2
maxChangeTrajectory: 13.5
- layers:
serializedVersion: 2
m_Bits: 32768
tags:
- Enemy
- Player
- Boss
- Untagged
- CompanionAI
reduceLife: 80
ricochet: 0
maxThicknessToCross: 0.35
damageReducePercentage: 50
minChangeTrajectory: 1
maxChangeTrajectory: 2
- layers:
serializedVersion: 2
m_Bits: 1
tags:
- Glass
- Wood
reduceLife: 90
ricochet: 0
maxThicknessToCross: 0.4
damageReducePercentage: 100
minChangeTrajectory: 0.5
maxChangeTrajectory: 1

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 9cf8fdb35fce3c748ba3e6d6502cf435
timeCreated: 1499308802
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,150 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e54b0675598e3f946be47398a01b918a, type: 3}
m_Name: AudioDatabase
m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.Audio.AudioDatabase
samples:
- Name: key-press-1
Clip: {fileID: 8300000, guid: 811444c0714824740a05502fe969c790, type: 3}
DefaultVolume: 0.35
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-press-2
Clip: {fileID: 8300000, guid: 71cfbe0c1eb8128408a6586d5714b279, type: 3}
DefaultVolume: 0.35
DefaultPitch: 1.05
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-press-3
Clip: {fileID: 8300000, guid: 21d31f1a9750c3442b2090dd5941e876, type: 3}
DefaultVolume: 0.35
DefaultPitch: 0.95
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-press-4
Clip: {fileID: 8300000, guid: e3f0dca1e709dae4c97d49ca85b9a3b7, type: 3}
DefaultVolume: 0.35
DefaultPitch: 1.1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-confirm
Clip: {fileID: 8300000, guid: 045d19ad3f303e749990e6b0d2667dbb, type: 3}
DefaultVolume: 0.6
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-delete
Clip: {fileID: 8300000, guid: 5ab37717dcad90346972273e7cb52ba0, type: 3}
DefaultVolume: 0.4
DefaultPitch: 0.9
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-caps
Clip: {fileID: 8300000, guid: 5724c9b6ea245fd4795737122cf22879, type: 3}
DefaultVolume: 0.5
DefaultPitch: 1.2
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: key-movement
Clip: {fileID: 8300000, guid: ff184cc35711e2d4cbeb4b2e39fb6e6a, type: 3}
DefaultVolume: 0.3
DefaultPitch: 1.1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menuclick
Clip: {fileID: 8300000, guid: 0e77a34a88618c947a6f28d62211e533, type: 3}
DefaultVolume: 0.5
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-play-hover
Clip: {fileID: 8300000, guid: c209fbd95b1b02a4cb75a027ce0713aa, type: 3}
DefaultVolume: 0.4
DefaultPitch: 1.1
MixerGroup: {fileID: 24300002, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-back-hover
Clip: {fileID: 8300000, guid: 3408227a2bcd6d8468df7a6bdb185972, type: 3}
DefaultVolume: 0.4
DefaultPitch: 1.05
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-options-hover
Clip: {fileID: 8300000, guid: 7e58115b9cec4cf45a79c858b76077b1, type: 3}
DefaultVolume: 0.4
DefaultPitch: 1.05
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-exit-hover
Clip: {fileID: 8300000, guid: 3fed8036f4c5ad943b1d907d5e29d22c, type: 3}
DefaultVolume: 0.4
DefaultPitch: 0.95
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-play-click
Clip: {fileID: 8300000, guid: ebd4de3e32d29714eb4cfd6338ec1d1a, type: 3}
DefaultVolume: 0.8
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-back-click
Clip: {fileID: 8300000, guid: 5ba84b0e2cf43df408d587976da49d63, type: 3}
DefaultVolume: 0.7
DefaultPitch: 0.9
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: click-short-confirm
Clip: {fileID: 8300000, guid: 55eef2d804c271946a2c47337fa27ce4, type: 3}
DefaultVolume: 0.9
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: click-close
Clip: {fileID: 8300000, guid: 4ca23ada6817c7348a52ecbd49801702, type: 3}
DefaultVolume: 0.6
DefaultPitch: 0.8
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: pause-retry-click
Clip: {fileID: 8300000, guid: a4ab3d4f1ae6ac940a5d16119a73a4e4, type: 3}
DefaultVolume: 0.8
DefaultPitch: 1.1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-options-click
Clip: {fileID: 8300000, guid: 5f51b36760658354a91d710ecab055a1, type: 3}
DefaultVolume: 0.7
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menu-exit-click
Clip: {fileID: 8300000, guid: 872d2756e2154fd44a1b07b67596b94a, type: 3}
DefaultVolume: 0.7
DefaultPitch: 0.85
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: check-on
Clip: {fileID: 8300000, guid: 0467ea34c3274e449b7dd5b6c820db4e, type: 3}
DefaultVolume: 0.6
DefaultPitch: 1.2
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: check-off
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 0.6
DefaultPitch: 0.8
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: UI_Focus
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 0.4
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: heartbeat
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 0.8
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: menuHit
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: sectionpass
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 0.9
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}
- Name: sectionfail
Clip: {fileID: 8300000, guid: 843d92b9180c16f4fb3a878aa7aacc9b, type: 3}
DefaultVolume: 0.9
DefaultPitch: 1
MixerGroup: {fileID: -6431947565845596828, guid: 914a8292e2b2b594e9b7cb3ee0c7e77d, type: 2}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: c73d93f8732fbe64d8b0d1cde67a1892
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: df007b377a2cd274bbfba12dd4f131b2
folderAsset: yes
timeCreated: 1445804257
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,178 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7592ac57a97621844bb7d05b6822c040, type: 3}
m_Name: vBasicLocomotiont@CameraState
m_EditorClassIdentifier:
Name:
tpCameraStates:
- Name: Default
forward: -1
right: 0
defaultDistance: 2.5
maxDistance: 80
minDistance: 0.6
height: 1.25
smooth: 10
smoothDamp: 2
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -75
yMaxLimit: 75
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0.84, y: 0.99, z: 0}
cullingHeight: 1.8
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Sprinting
forward: -1
right: 0
defaultDistance: 2.5
maxDistance: 80
minDistance: 0.6
height: 1.25
smooth: 10
smoothDamp: 2
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -75
yMaxLimit: 75
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0.84, y: 0.99, z: 0}
cullingHeight: 1.8
cullingMinDist: 0.01
fov: 70
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Crouch
forward: -1
right: 0.15
defaultDistance: 2
maxDistance: 6.55
minDistance: 0.5
height: 1
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.7
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Strafing
forward: -1
right: 0
defaultDistance: 2.5
maxDistance: 1.5
minDistance: 0.25
height: 1.6
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 5, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 50
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Pendulum
forward: -1
right: 0.28
defaultDistance: 12
maxDistance: 3
minDistance: 0.5
height: 1.8
smooth: 10
smoothDamp: 4
xMouseSensitivity: 0
yMouseSensitivity: 0
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1
cullingMinDist: 0.1
fov: 55
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints:
- pointName: point_01
positionPoint: {x: 26.55739, y: 11.5149355, z: -14.382481}
eulerAngle: {x: 18.395489, y: 3.074889, z: 0.00039735218}
freeRotation: 1
cameraMode: 2
- Name: Sliding
forward: -1
right: 0
defaultDistance: 1
maxDistance: 3
minDistance: 0.5
height: 0.5
smooth: 10
smoothDamp: 10
xMouseSensitivity: 1
yMouseSensitivity: 1
yMinLimit: -10
yMaxLimit: 20
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.2
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints:
- pointName: point_01
positionPoint: {x: 26.55739, y: 11.5149355, z: -14.382481}
eulerAngle: {x: 18.395489, y: 3.0748892, z: 0.00039735215}
freeRotation: 0
- pointName: point_02
positionPoint: {x: 29.395, y: 0.709, z: 2.2409992}
eulerAngle: {x: 357.80994, y: 88.88348, z: 359.81253}
freeRotation: 0
- pointName: point_03
positionPoint: {x: 37.249695, y: 0.97621524, z: 2.2345524}
eulerAngle: {x: 2.0625482, y: 271.75256, z: -0.00016467154}
freeRotation: 0
cameraMode: 2

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: dbf2c7a931be7ae4d960bc178dc4dda6
timeCreated: 1488647899
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,143 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7592ac57a97621844bb7d05b6822c040, type: 3}
m_Name: vFastShooter@CameraState
m_EditorClassIdentifier:
Name:
tpCameraStates:
- Name: Default
forward: -1
right: 0.25
defaultDistance: 2
maxDistance: 8
minDistance: 0.6
height: 1.5
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -39.999996
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Crouch
forward: -1
right: 0.4
defaultDistance: 1.5
maxDistance: 6.55
minDistance: 0.5
height: 1.3
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.7
cullingMinDist: 0.1
fov: 40
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Strafing
forward: -1
right: 0.25
defaultDistance: 2
maxDistance: 1.5
minDistance: 0.25
height: 1.5
smooth: 10
smoothDamp: 0
xMouseSensitivity: 2.5
yMouseSensitivity: 2.5
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Aiming
forward: -1
right: 0.4
defaultDistance: 2
maxDistance: 3
minDistance: 0.5
height: 1.5
smooth: 10
smoothDamp: 1
xMouseSensitivity: 2
yMouseSensitivity: 2
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 15}
lookPoints:
- pointName: point_01
positionPoint: {x: 27.862371, y: 8.697912, z: -13.253475}
eulerAngle: {x: 1.2032634, y: 0.6535967, z: 0.0000026131736}
freeRotation: 1
cameraMode: 0
- Name: ScopeAiming
forward: -1
right: 0.4
defaultDistance: 2
maxDistance: 3
minDistance: 0.5
height: 1.5
smooth: 10
smoothDamp: 1
xMouseSensitivity: 0.2
yMouseSensitivity: 0.2
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 15}
lookPoints:
- pointName: point_01
positionPoint: {x: 27.862371, y: 8.697912, z: -13.253475}
eulerAngle: {x: 1.2032634, y: 0.6535967, z: 0.0000026131736}
freeRotation: 1
cameraMode: 0

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 08d781d2411aa4a41b60c84b60c87c98
timeCreated: 1486916120
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,116 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7592ac57a97621844bb7d05b6822c040, type: 3}
m_Name: vMeleeCombat@CameraState
m_EditorClassIdentifier:
Name:
tpCameraStates:
- Name: Default
forward: -1
right: 0
defaultDistance: 2.5
maxDistance: 8
minDistance: 0.6
height: 1.8
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.8
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Strafing
forward: -1
right: 0
defaultDistance: 2.5
maxDistance: 8
minDistance: 0.6
height: 1.8
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: 0
yMaxLimit: 0
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.8
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Crouch
forward: -1
right: 0.2
defaultDistance: 1.5
maxDistance: 6.55
minDistance: 0.5
height: 0.7
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.7
cullingMinDist: 0.1
fov: 40
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: _
forward: -1
right: 0.82
defaultDistance: 1.35
maxDistance: 1.5
minDistance: 0.25
height: 1.6
smooth: 10
smoothDamp: 6
xMouseSensitivity: 1
yMouseSensitivity: 1
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 71.1
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 026ed2280610ee74194cd3af679c75a3
timeCreated: 1426901672
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,339 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7592ac57a97621844bb7d05b6822c040, type: 3}
m_Name: vShooterMelee@CameraState
m_EditorClassIdentifier:
Name:
tpCameraStates:
- Name: Default
forward: -1
right: 0.2
defaultDistance: 1.8
maxDistance: 12
minDistance: 0.6
height: 1.6
smooth: 10
smoothDamp: 6
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -70
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.9
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: ThrowStanding
forward: -1
right: 0.75
defaultDistance: 1
maxDistance: 12
minDistance: 0.6
height: 1.75
smooth: 10
smoothDamp: 1
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -70
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.9
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: ThrowCrouching
forward: -1
right: 0.4
defaultDistance: 1.5
maxDistance: 6.55
minDistance: 0.5
height: 0.8
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 70
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Crouch
forward: -1
right: 0.4
defaultDistance: 1.5
maxDistance: 6.55
minDistance: 0.5
height: 0.8
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 70
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Aiming
forward: -1
right: 0.34
defaultDistance: 1.23
maxDistance: 1.5
minDistance: 0.25
height: 1.6
smooth: 10
smoothDamp: 1
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -50
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 35
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: AimingScopeView
forward: 1
right: 0
defaultDistance: -0.2
maxDistance: 1.5
minDistance: 0.25
height: 0
smooth: 60
smoothDamp: 0
xMouseSensitivity: 2
yMouseSensitivity: 1
yMinLimit: -50
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 31
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Strafing
forward: -1
right: 0.15
defaultDistance: 2.8
maxDistance: 3
minDistance: 0.5
height: 1.61
smooth: 10
smoothDamp: 1
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -80
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.9
cullingMinDist: 0.1
fov: 50
useZoom: 0
fixedAngle: {x: 0, y: 15}
lookPoints:
- pointName: point_01
positionPoint: {x: 27.862371, y: 8.697912, z: -13.253475}
eulerAngle: {x: 1.2032634, y: 0.6535967, z: 0.0000026131736}
freeRotation: 1
cameraMode: 0
- Name: LockOn
forward: -1
right: 0.4
defaultDistance: 1.3
maxDistance: 3
minDistance: 0.5
height: 1.9
smooth: 2
smoothDamp: 10
xMouseSensitivity: 2.5
yMouseSensitivity: 2.5
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.9
cullingMinDist: 0.1
fov: 70
useZoom: 0
fixedAngle: {x: 0, y: 15}
lookPoints:
- pointName: point_01
positionPoint: {x: 27.862371, y: 8.697912, z: -13.253475}
eulerAngle: {x: 1.2032634, y: 0.6535967, z: 0.0000026131736}
freeRotation: 1
cameraMode: 0
- Name: Building
forward: -1
right: 0
defaultDistance: 2
maxDistance: 3
minDistance: 0.5
height: 1.5
smooth: 10
smoothDamp: 10
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 1
cullingMinDist: 0.1
fov: 70
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: CrouchingAiming
forward: -1
right: 0.5
defaultDistance: 1.5
maxDistance: 3
minDistance: 0.5
height: 1.2
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.2
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Parachute
forward: -1
right: 0
defaultDistance: 3
maxDistance: 3
minDistance: 0.5
height: 1
smooth: 10
smoothDamp: 6
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -70
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 27.43, y: 0, z: 0}
cullingHeight: 1.9
cullingMinDist: 0.1
fov: 80
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Pendulum
forward: 60
right: 0
defaultDistance: 1.5
maxDistance: 3
minDistance: 0.5
height: 0
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.2
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints:
- pointName: point_01
positionPoint: {x: 243.86966, y: 8.007825, z: 164.1816}
eulerAngle: {x: 24.449335, y: 135.46579, z: 0.001277386}
freeRotation: 1
cameraMode: 2
- Name: FirstPerson
forward: 70
right: 0
defaultDistance: 0
maxDistance: 0
minDistance: 0
height: 0
smooth: 10
smoothDamp: 0
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.2
cullingMinDist: 0.1
fov: 113.1
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints:
- pointName: point_01
positionPoint: {x: 6.950366, y: 2.8947582, z: -24.111038}
eulerAngle: {x: 24.449337, y: 315.46573, z: 0.0012745722}
freeRotation: 1
cameraMode: 3

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 8616a8d80006bfb4d9069ea692c278da
timeCreated: 1486632713
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,139 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7592ac57a97621844bb7d05b6822c040, type: 3}
m_Name: vShooterOnly@CameraState
m_EditorClassIdentifier:
Name:
tpCameraStates:
- Name: Default
forward: -1
right: 0.25
defaultDistance: 2
maxDistance: 8
minDistance: 0.6
height: 1.5
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -39.999996
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.01
fov: 60
useZoom: 0
fixedAngle: {x: 360, y: 78}
lookPoints:
- pointName: point_01
positionPoint: {x: 0, y: 1, z: -10}
eulerAngle: {x: -0, y: 0, z: 0}
freeRotation: 0
cameraMode: 0
- Name: Crouch
forward: -1
right: 0.4
defaultDistance: 1.5
maxDistance: 6.55
minDistance: 0.5
height: 1.2
smooth: 10
smoothDamp: 4
xMouseSensitivity: 3
yMouseSensitivity: 3
yMinLimit: -40
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 0, y: 0, z: 0}
cullingHeight: 0.7
cullingMinDist: 0.1
fov: 40
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Aiming
forward: -1
right: 0.3
defaultDistance: 1.5
maxDistance: 1.5
minDistance: 0.25
height: 1.7
smooth: 10
smoothDamp: 2
xMouseSensitivity: 1
yMouseSensitivity: 1
yMinLimit: -65
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 35
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: CrouchingAiming
forward: -1
right: 0.35
defaultDistance: 1.5
maxDistance: 1.5
minDistance: 0.25
height: 1.5
smooth: 10
smoothDamp: 2
xMouseSensitivity: 1
yMouseSensitivity: 1
yMinLimit: -65
yMaxLimit: 70
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1.5
cullingMinDist: 0.1
fov: 45
useZoom: 0
fixedAngle: {x: 0, y: 0}
lookPoints: []
cameraMode: 0
- Name: Strafing
forward: -1
right: 0.25
defaultDistance: 1.26
maxDistance: 3
minDistance: 0.5
height: 1.62
smooth: 10
smoothDamp: 1
xMouseSensitivity: 2.5
yMouseSensitivity: 2.5
yMinLimit: -40
yMaxLimit: 80
xMinLimit: -360
xMaxLimit: 360
rotationOffSet: {x: 8, y: 0, z: 0}
cullingHeight: 1
cullingMinDist: 0.1
fov: 60
useZoom: 0
fixedAngle: {x: 0, y: 15}
lookPoints:
- pointName: point_01
positionPoint: {x: 27.862371, y: 8.697912, z: -13.253475}
eulerAngle: {x: 1.2032634, y: 0.6535967, z: 0.0000026131736}
freeRotation: 1
cameraMode: 0

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: b89918146e5fddb47902bfe31aeccf5b
timeCreated: 1487963923
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,39 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d3ff96571406a624381b7b0e596a4d1b, type: 3}
m_Name: DefaultMazeProfile
m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.GameSetup.Maze.MazeVisualProfile
tJunctionOffset: 0
cornerOffset: 180
deadEndOffset: 0
stairsOffset: 180
wallPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
corridorPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
processingPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
pathPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
startPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
endPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
stairUpPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
stairDownPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
corridorStraight: {fileID: 1264748121136002, guid: 1652aa5a752a65148a198afb1c8933d2, type: 3}
corridorCorner: {fileID: 1031289983165790, guid: 27b5bfd692a61f64f92a875a55f28376, type: 3}
corridorTJunction: {fileID: 1907757158894496, guid: 95d0988761bfc144e9325a126719df2b, type: 3}
corridorCross: {fileID: 1031289983165790, guid: 27b5bfd692a61f64f92a875a55f28376, type: 3}
corridorDeadEnd: {fileID: 1432061068797346, guid: c64b847edeb2eb94da5ba81384d3f8fc, type: 3}
roomFloorPrefab: {fileID: 1392295376913288, guid: 68316adad77ca6b4abdd0cc62cb4ba24, type: 3}
roomWallPrefab: {fileID: 1703145814520204, guid: 831ba33ea3bd614499bcbc3e5b9188b8, type: 3}
roomCeilingPrefab: {fileID: 1811263594973386, guid: 00bce47c2b02a1e49928328f8a27c7cd, type: 3}
roomDoorwayPrefab: {fileID: 1863703931977514, guid: b484ab835d98f164492ed07a36da9fd6, type: 3}
scale: 1
nodeSpacing: 20
deadEndShift: 1
animationDuration: 1000

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 15b745b0bb979b84ea937c679ee0f1ed
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,60 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e54b0675598e3f946be47398a01b918a, type: 3}
m_Name: FOR AI GAME
m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.Audio.AudioDatabase
samples:
- Name: UI_Win
Clip: {fileID: 8300000, guid: fecdee2673ce2f542a3db1a8b56d1571, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: UI_Warning
Clip: {fileID: 8300000, guid: 32b49cf6b9e2e8e408663785554c3e75, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: UI_Click
Clip: {fileID: 8300000, guid: 30f85fcee050492448db7f91217910b3, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: Item_Pickup
Clip: {fileID: 8300000, guid: b1ae905972eed154497f5454b22ba711, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: Enemy_Alert
Clip: {fileID: 8300000, guid: d5f9671eecb70364f8282999c81d8295, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: Enemy_Shoot
Clip: {fileID: 8300000, guid: de0b7f47746d51f48b733b64b307540e, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 0}
- Name: Laser_Hit
Clip: {fileID: 8300000, guid: e14cb014b8c41bf4a98768f2e4b4c1d7, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: NPC_Interact
Clip: {fileID: 8300000, guid: 6d36adcf33e186c4cbe64a4c149e138f, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}
- Name: NPC_Response
Clip: {fileID: 8300000, guid: 7c266b12aa7ed1a49bf7ea0889d32302, type: 3}
DefaultVolume: 1
DefaultPitch: 1
MixerGroup: {fileID: 24300002, guid: a622ceda579315442bd0a82d6626974c, type: 2}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a8afc185646130b409f5826ef0670577
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0551a27408b84c040a2e009ae17debde, type: 3}
m_Name: FirebaseConfig
m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.UI.FirebaseConfig
baseUrl: https://hallucination-303-default-rtdb.asia-southeast1.firebasedatabase.app/

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 987ed1314b9242c4d8c84deaf9bb8ea0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -12,13 +12,20 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 30892b1102feb6841a9288ddb11ef50d, type: 3} m_Script: {fileID: 11500000, guid: 30892b1102feb6841a9288ddb11ef50d, type: 3}
m_Name: MazeRework m_Name: MazeRework
m_EditorClassIdentifier: Assembly-CSharp::Baba_yaga.GameSetup.MazeRework.MazeReworkConfig m_EditorClassIdentifier: Assembly-CSharp::Baba_yaga.GameSetup.MazeRework.MazeReworkConfig
algorithm: 0 algorithm: 2
width: 13 width: 10
depth: 13 depth: 10
varyFloorSize: 1
floorSizeMode: 1
manualFloorSizes:
- {x: 10, y: 10}
- {x: 5, y: 5}
- {x: 5, y: 8}
- {x: 8, y: 8}
useRandomSeed: 1 useRandomSeed: 1
seed: 1989 seed: 1989
startLocation: {x: 1, y: 1} startLocation: {x: 1, y: 1}
generateRooms: 1 generateRooms: 0
roomCount: 2 roomCount: 2
minRoomSize: {x: 3, y: 3} minRoomSize: {x: 3, y: 3}
maxRoomSize: {x: 5, y: 5} maxRoomSize: {x: 5, y: 5}

View File

@@ -1,39 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d3ff96571406a624381b7b0e596a4d1b, type: 3}
m_Name: TestMazeProfile
m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.GameSetup.Maze.MazeVisualProfile
tJunctionOffset: 0
cornerOffset: 180
deadEndOffset: 0
stairsOffset: 180
wallPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
corridorPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
processingPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
pathPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
startPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
endPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
stairUpPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
stairDownPrefab: {fileID: 100000, guid: 8fb11e307b50ccc42a39120e3c49b4a1, type: 3}
corridorStraight: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
corridorCorner: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
corridorTJunction: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
corridorCross: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
corridorDeadEnd: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
roomFloorPrefab: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
roomWallPrefab: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
roomCeilingPrefab: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
roomDoorwayPrefab: {fileID: 1232322618620288, guid: d31379ea41af1e14184ac8deaa704fcf, type: 3}
scale: 1
nodeSpacing: 20
deadEndShift: 1
animationDuration: 1000

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3886a13498ec73b4bbc588f8c60d2c31
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,745 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1f3602cfd0ac79644a19fea8f4fd1b49, type: 3}
m_Name: vMelee_ItemListData
m_EditorClassIdentifier:
items:
- {fileID: 114000013967465728}
- {fileID: 114000011454979648}
- {fileID: 114000014017037032}
- {fileID: 114000014005472098}
- {fileID: 114000013983157954}
- {fileID: 114000013569560620}
- {fileID: 114000012982302300}
- {fileID: 114000011522160142}
- {fileID: 114000012184096246}
- {fileID: 114000010878405866}
- {fileID: 11411124}
- {fileID: 11437076}
- {fileID: 11411708}
- {fileID: 114043347838910644}
inEdition: 1
itemsHidden: 1
--- !u!114 &11411124
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: KeyCard Blue
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 10
description: Blue Keycard to open doors
type: 0
icon: {fileID: 21300000, guid: 72f7d3138d397a94d82105b26272e764, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000012655258636, guid: cf28841817afdab4c8060f470a322c37, type: 3}
attributes: []
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &11411708
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: KeyCard Gold
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 12
description: Gold Keycard to open doors
type: 0
icon: {fileID: 21300006, guid: 72f7d3138d397a94d82105b26272e764, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000012655258636, guid: cf28841817afdab4c8060f470a322c37, type: 3}
attributes: []
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &11437076
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: KeyCard Red
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 11
description: Red Keycard to open doors
type: 0
icon: {fileID: 21300002, guid: 72f7d3138d397a94d82105b26272e764, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000012655258636, guid: cf28841817afdab4c8060f470a322c37, type: 3}
attributes: []
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000010878405866
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Great Shield
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 9
description: 'Melee Shield
Recoil: Hard
Bonus: Break Attack '
type: 6
icon: {fileID: 21300000, guid: 4a46b7c6ff6f17a4a95bfb58b3397585, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000012874595254, guid: d4ca9135af96d5142987a1f1427b099a,
type: 3}
dropObject: {fileID: 8587624101741613191, guid: e26f928aabf2af048b7def78ec83a486,
type: 3}
attributes:
- name: 3
value: 0
isOpen: 0
isBool: 0
- name: 4
value: 100
isOpen: 0
isBool: 0
- name: 5
value: 90
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowBack
DisableAnim: LowBack
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler: shieldHandler
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000011454979648
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Short Katana
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 1
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: 56e79d7e38be01c4c9171802884dfb05, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000011247033104, guid: 43ec053b9c111644e80b4ddb5f535508,
type: 3}
dropObject: {fileID: 3314097323225006234, guid: 0f2c84cd3287333448744ce0451196cd,
type: 3}
attributes:
- name: 2
value: 25
isOpen: 0
isBool: 0
- name: 3
value: 20
isOpen: 0
isBool: 0
- name: 4
value: 85
isOpen: 0
isBool: 0
- name: 5
value: 70
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowFront
DisableAnim: LowFront
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000011522160142
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Great Sword
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 7
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: 68199bff0f78a2d4ca77e20ccc91ef76, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000014209087140, guid: d03b45803e637bb4fb00a1ca9030d66e,
type: 3}
dropObject: {fileID: 4500584118820961459, guid: eca1e51be6676704dbb7f23b4947883b,
type: 3}
attributes:
- name: 2
value: 30
isOpen: 0
isBool: 0
- name: 3
value: 20
isOpen: 0
isBool: 0
- name: 4
value: 85
isOpen: 0
isBool: 0
- name: 5
value: 70
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowFront
DisableAnim: LowFront
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 1
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000012184096246
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Great Katana
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 8
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: 75c369d61ea60a54e877b01a25ae0916, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000013423493360, guid: 6bbee781522ce5243a02bf72cd914cf5,
type: 3}
dropObject: {fileID: 2197774501603174495, guid: 7dcfb29ec0c968041b99dd41d13cec28,
type: 3}
attributes:
- name: 2
value: 25
isOpen: 0
isBool: 0
- name: 3
value: 20
isOpen: 0
isBool: 0
- name: 4
value: 85
isOpen: 0
isBool: 0
- name: 5
value: 10
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowFront
DisableAnim: LowFront
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 1
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000012982302300
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Shield
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 6
description: 'Melee Shield
Recoil: Low'
type: 6
icon: {fileID: 21300000, guid: 40e348f6451ddf7438089a59a033e57f, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000010116632662, guid: 2232bbcc5a195274c9744c2c6352e910,
type: 3}
dropObject: {fileID: 862192267840601332, guid: d07ef1bfe3f5bf4469394a9c723bbbc1,
type: 3}
attributes:
- name: 3
value: 0
isOpen: 0
isBool: 0
- name: 4
value: 80
isOpen: 0
isBool: 0
- name: 5
value: 90
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowBack
DisableAnim: LowBack
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler: shieldHandler
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000013569560620
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Max Health Potion
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 5
description: Increases the MaxHealth
type: 0
icon: {fileID: 21300000, guid: e60fbeee962473a4bb627f9d7dc341b0, type: 3}
stackable: 1
maxStack: 10
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000010221758328, guid: ece88c1afc659094e93bccace77fab7a, type: 3}
attributes:
- name: 7
value: 50
isOpen: 1
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000013967465728
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Axe
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 0
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: b2158c09d5bc7284989f53a47f7638e3, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000010725870802, guid: 0cf98a7633e41834ba19e8626f1ceadc,
type: 3}
dropObject: {fileID: 880292917891664030, guid: 4ce32edaf6024884898e95f24f9f763a,
type: 3}
attributes:
- name: 2
value: 30
isOpen: 0
isBool: 0
- name: 3
value: 35
isOpen: 0
isBool: 0
- name: 4
value: 60
isOpen: 0
isBool: 0
- name: 5
value: 85
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: HighBack
DisableAnim: HighBack
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000013983157954
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Stamina Up Potion
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 4
description: Increase Stamina
type: 0
icon: {fileID: 21300000, guid: a7eb39caa37204044ae09aa0c8699270, type: 3}
stackable: 1
maxStack: 10
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000011723862914, guid: 439b229da101b06419a0a87e0f4cef84, type: 3}
attributes:
- name: 8
value: 20
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000014005472098
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Short Sword
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 3
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: 359a7ebb90d1a2c4eba5c493a73ca543, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000012884940116, guid: 5dc53aa14e78ec54fbf2281c1abb7f47,
type: 3}
dropObject: {fileID: 819158048279699071, guid: 0f25b0bc9b7934840b324072cedb3325,
type: 3}
attributes:
- name: 2
value: 15
isOpen: 0
isBool: 0
- name: 3
value: 25
isOpen: 0
isBool: 0
- name: 4
value: 85
isOpen: 0
isBool: 0
- name: 5
value: 60
isOpen: 0
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: LowFront
DisableAnim: LowFront
enableDelayTime: 0.25
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114000014017037032
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Health Potion
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 2
description: Recover Health
type: 0
icon: {fileID: 21300000, guid: 862e9f0d31ea667448a05c4d0ec24492, type: 3}
stackable: 1
maxStack: 10
amount: 0
originalObject: {fileID: 0}
dropObject: {fileID: 1000013743731710, guid: 8bbf808ac1be0f84ab505cfdb9eb83b4, type: 3}
attributes:
- name: 0
value: 25
isOpen: 1
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 1
canBeUsed: 1
canBeDroped: 1
canBeDestroyed: 1
EnableAnim:
DisableAnim:
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler:
twoHandWeapon: 0
onDestroy:
m_PersistentCalls:
m_Calls: []
--- !u!114 &114043347838910644
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1adabc1ae49fd3c44a36cc9152ebb0f9, type: 3}
m_Name: Dual Swords
m_EditorClassIdentifier:
itemsToCraft: []
canCraft: 1
price: 0
id: 24
description: Melee Weapon
type: 1
icon: {fileID: 21300000, guid: a568bb7d845ecf140a30a74582d14f45, type: 3}
stackable: 0
maxStack: 1
amount: 0
originalObject: {fileID: 1000012884940116, guid: f0df66e0950da4642afce9f6382ab231,
type: 3}
dropObject: {fileID: 5960025752436353048, guid: 25e7bf6c702446e47bbc7ce3a6aaaeb5,
type: 3}
attributes:
- name: 2
value: 10
isOpen: 0
isBool: 0
- name: 3
value: 25
isOpen: 0
isBool: 0
- name: 4
value: 85
isOpen: 0
isBool: 0
- name: 5
value: 60
isOpen: 1
isBool: 0
isInEquipArea: 0
isEquiped: 0
destroyAfterUse: 0
canBeUsed: 0
canBeDroped: 1
canBeDestroyed: 1
EnableAnim: HighBack
DisableAnim: HighBack
enableDelayTime: 0.5
disableDelayTime: 0.5
customHandler: meleeHandler
twoHandWeapon: 1
onDestroy:
m_PersistentCalls:
m_Calls: []

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 96e918a0f3173b14dbbbe08b7523b670
timeCreated: 1471644554
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 1493f9d9326e8014494b8cb04de38f25
timeCreated: 1486918859
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +0,0 @@
using System.Collections;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class CrawlerAlgorithm : IMazeAlgorithm
{
private const int CrawlChance = 50;
private const int MinBoundary = 1;
private const int VerticalCrawlerCount = 3;
private const int HorizontalCrawlerCount = 3;
public void Generate(MazeGrid grid)
{
for (int i = 0; i < VerticalCrawlerCount; i++) CrawlV(grid, 0);
for (int i = 0; i < HorizontalCrawlerCount; i++) CrawlH(grid, 0);
}
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
{
for (int i = 0; i < VerticalCrawlerCount; i++) yield return CrawlV(grid, cellsPerFrame);
for (int i = 0; i < HorizontalCrawlerCount; i++) yield return CrawlH(grid, cellsPerFrame);
}
private IEnumerator CrawlV(MazeGrid grid, int cellsPerFrame)
{
bool done = false;
int x = Random.Range(MinBoundary, grid.Width - MinBoundary);
int z = MinBoundary;
while (!done)
{
grid.SetCell(x, z, MazeCellType.Processing);
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
grid.SetCell(x, z, MazeCellType.Corridor);
if (Random.Range(0, 100) < CrawlChance)
{
x += Random.Range(-1, 2);
}
else
{
z += Random.Range(0, 2);
}
done |= (x < MinBoundary || x >= grid.Width - MinBoundary || z < MinBoundary || z >= grid.Depth - MinBoundary);
}
}
private IEnumerator CrawlH(MazeGrid grid, int cellsPerFrame)
{
bool done = false;
int x = MinBoundary;
int z = Random.Range(MinBoundary, grid.Depth - MinBoundary);
while (!done)
{
grid.SetCell(x, z, MazeCellType.Processing);
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
grid.SetCell(x, z, MazeCellType.Corridor);
if (Random.Range(0, 100) < CrawlChance)
{
x += Random.Range(0, 2);
}
else
{
z += Random.Range(-1, 2);
}
done |= (x < MinBoundary || x >= grid.Width - MinBoundary || z < MinBoundary || z >= grid.Depth - MinBoundary);
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: bd419f9be92beac48b6f551063165e1f

View File

@@ -1,25 +0,0 @@
using System.Collections.Generic;
namespace Baba_yaga.GameSetup.Maze.Extensions
{
public static class ListExtensions
{
private static System.Random _rng = new System.Random();
/// <summary>
/// Shuffles a list using the Fisher-Yates algorithm.
/// </summary>
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = _rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 7d9791b1b03c14f16a245b2d4577c5f9

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6e1bb9cd9af7ffe40ad1a740c3c30dd6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,20 +0,0 @@
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Interface for all maze generation algorithms.
/// Supports both immediate and step-by-step (animated) generation.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public interface IMazeAlgorithm
{
/// <summary>
/// Generates the maze immediately in one frame.
/// </summary>
void Generate(MazeGrid grid);
/// <summary>
/// Generates the maze step-by-step for visualization.
/// </summary>
System.Collections.IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame);
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 46b6a7796ba3c494581e4dcb884da064

View File

@@ -1,32 +0,0 @@
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Represents a 2D coordinate on the maze grid.
/// Used as a lightweight value type to avoid GC allocations.
/// </summary>
public readonly struct MapLocation
{
public readonly int x;
public readonly int z;
public MapLocation(int _x, int _z)
{
x = _x;
z = _z;
}
// Static predefined directions to eliminate magic numbers in algorithms
public static MapLocation Right => new MapLocation(1, 0);
public static MapLocation Left => new MapLocation(-1, 0);
public static MapLocation Up => new MapLocation(0, 1);
public static MapLocation Down => new MapLocation(0, -1);
/// <summary>
/// Returns a list of all 4 cardinal directions.
/// </summary>
public static System.Collections.Generic.List<MapLocation> Directions => new System.Collections.Generic.List<MapLocation>
{
Right, Up, Left, Down
};
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 987a7c46c96326a44b3a5f179fe61161

View File

@@ -1,43 +0,0 @@
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Defines the state of each cell in the maze.
/// Used to replace magic numbers and drive visual changes.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public enum MazeCellType
{
Wall, // Solid block
Corridor, // Finalized path
Processing, // Currently being evaluated by algorithm (Debug)
Path, // Temporary path (e.g., Wilson's crawler)
Start, // Entry point
End, // Exit point
StairsUp,
StairsDown,
Room
}
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public enum PieceType
{
None,
Wall,
Vertical_Straight, // Đường thẳng dọc
Horizontal_Straight, // Đường thẳng ngang
Corner, // Góc cua
T_Junction, // Ngã ba
Crossroads, // Ngã tư
Stairs,
StairsUp// Cầu thang (Điểm nối)
}
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public struct MazePieceData
{
public PieceType piece; // Hình dạng mảnh ghép
// Bạn có thể thêm rotation nếu cần xoay hướng model sau này
public int rotation;
public GameObject model;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: f54ef08fa4922eb4a968d46c7aa71faf

View File

@@ -1,84 +0,0 @@
using System;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Holds the logical state of the maze grid.
/// Notifies listeners whenever a cell changes to trigger visual updates.
/// </summary>
[Serializable]
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class MazeGrid
{
public int Width { get; set; }
public int Depth { get; set; }
public int Level { get; set; }
public MazePieceData[,] piecePlace;
public float scale = 1f;
private readonly MazeCellType[,] _cells;
/// <summary>
/// Event fired when a cell's type is changed.
/// Useful for the Renderer to trigger animations/FX.
/// </summary>
public event Action<int, int, MazeCellType> OnCellChanged;
public MazeGrid(int width, int depth)
{
Width = width;
Depth = depth;
piecePlace = new MazePieceData[width, depth];
_cells = new MazeCellType[width, depth];
// Initialize all as walls
for (int z = 0; z < depth; z++)
{
for (int x = 0; x < width; x++)
{
_cells[x, z] = MazeCellType.Wall;
piecePlace[x, z].piece = PieceType.Wall;
}
}
}
public void SetCell(int x, int z, MazeCellType type)
{
if (IsInBounds(x, z))
{
if (_cells[x, z] != type)
{
_cells[x, z] = type;
OnCellChanged?.Invoke(x, z, type);
}
}
}
public MazeCellType GetCell(int x, int z)
{
if (IsInBounds(x, z))
return _cells[x, z];
return MazeCellType.Wall; // Treat out of bounds as walls
}
public bool IsInBounds(int x, int z)
{
return x >= 0 && x < Width && z >= 0 && z < Depth;
}
public int CountSquareNeighbours(int x, int z, MazeCellType targetType)
{
int count = 0;
if (x <= 0 || x >= Width - 1 || z <= 0 || z >= Depth - 1) return 5;
if (GetCell(x - 1, z) == targetType) count++;
if (GetCell(x + 1, z) == targetType) count++;
if (GetCell(x, z + 1) == targetType) count++;
if (GetCell(x, z - 1) == targetType) count++;
return count;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a1a7a252ff0b1014a9690f08897e2e59

View File

@@ -1,361 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Central controller for the Maze system.
/// Manages algorithm selection, debug speed, and regeneration.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class MazeManager : MonoBehaviour
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public enum AlgorithmType { Recursive, Wilsons, Prims, Crawler, NoiseRecursive }
[BoxGroup("Generation")]
[InfoBox("Set the array size to control how many maze floors are generated. Runtime grid data is rebuilt when Regenerate runs.")]
[ValidateInput(nameof(HasAtLeastOneFloor), "Maze Manager needs at least one floor.")]
public MazeGrid[] mazes;
[BoxGroup("Generation")]
[MinValue(0.001f)]
public float floorHeight = 3.5f;
[BoxGroup("Generation")]
[MinValue(0)]
public int connectionsPerFloor = 2;
[BoxGroup("Generation")]
[SerializeField] private AlgorithmType selectedAlgorithm;
[BoxGroup("Generation/Grid Size")]
[PropertyRange(5, 200)]
[SerializeField] private int width = 30;
[BoxGroup("Generation/Grid Size")]
[PropertyRange(5, 200)]
[SerializeField] private int depth = 30;
[BoxGroup("Animation")]
[SerializeField] private bool animateGeneration = true;
[BoxGroup("Animation")]
[ShowIf(nameof(animateGeneration))]
[PropertyRange(1, 500)]
[LabelText("Generation Speed (Cells/Frame)")]
[SerializeField] private int generationSpeed = 50;
public static int cellsProcessedThisFrame;
[BoxGroup("Animation")]
[ShowIf(nameof(animateGeneration))]
public MazeRenderer.CellAnimationType cellAnimationType = MazeRenderer.CellAnimationType.ScaleUp;
[BoxGroup("Progress")]
[ProgressBar(0, 100)]
[ShowInInspector, ReadOnly]
private float completionPercentage;
[BoxGroup("References")]
[Required]
[SerializeField] private MazeRenderer mazeRenderer;
[BoxGroup("Rooms (Phase 2)")]
public bool generateRooms = true;
[BoxGroup("Rooms (Phase 2)")]
[ShowIf(nameof(generateRooms))]
public int numberOfRooms = 2;
[BoxGroup("Rooms (Phase 2)")]
[ShowIf(nameof(generateRooms))]
public Vector2Int minRoomSize = new Vector2Int(2, 2);
[BoxGroup("Rooms (Phase 2)")]
[ShowIf(nameof(generateRooms))]
public Vector2Int maxRoomSize = new Vector2Int(4, 4);
[BoxGroup("References")]
[Required]
[SerializeField] private Transform mazeContainer;
[FoldoutGroup("Manhole Prefabs")]
public GameObject straightManHoleLadder;
[FoldoutGroup("Manhole Prefabs")]
public GameObject straightManHoleUp;
[FoldoutGroup("Manhole Prefabs")]
public GameObject deadendManHoleLadder;
[FoldoutGroup("Manhole Prefabs")]
public GameObject deadendManHoleUp;
[ShowInInspector]
[ReadOnly]
[BoxGroup("Runtime")]
private int FloorCount => mazes?.Length ?? 0;
[ShowInInspector]
[ReadOnly]
[BoxGroup("Runtime")]
private string CurrentGrid => _grid == null ? "None" : $"{_grid.Width}x{_grid.Depth}, Level {_grid.Level}";
private MazeGrid _grid;
private Coroutine _generationCoroutine;
private HashSet<Vector3Int> _modifiedCells = new HashSet<Vector3Int>();
private void Start()
{
Regenerate();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
Regenerate();
}
}
[ContextMenu("Clear Maze")]
[Button("Clear Maze", ButtonSizes.Large)]
public void ClearMaze()
{
if (_generationCoroutine != null)
{
StopCoroutine(_generationCoroutine);
_generationCoroutine = null;
}
if (mazeRenderer != null)
{
mazeRenderer.Clear();
}
completionPercentage = 0f;
_modifiedCells?.Clear();
}
[ContextMenu("Regenerate")]
[Button("Regenerate Maze", ButtonSizes.Large)]
public void Regenerate()
{
if (mazeRenderer == null)
{
Debug.LogError("MazeManager needs a MazeRenderer reference before regenerating.", this);
return;
}
if (mazeContainer == null)
{
Debug.LogError("MazeManager needs a maze container reference before regenerating.", this);
return;
}
if (mazes == null || mazes.Length == 0)
{
mazes = new MazeGrid[1];
}
ClearMaze();
mazeRenderer.currentAnimationType = cellAnimationType;
if (animateGeneration)
{
_generationCoroutine = StartCoroutine(GenerateMazeRoutine());
}
else
{
GenerateMazeInstant();
}
}
private void GenerateMazeInstant()
{
_modifiedCells.Clear();
completionPercentage = 0f;
for (int i = 0; i < mazes.Length; i++)
{
mazes[i] = new MazeGrid(width, depth);
mazes[i].Level = i;
CarveRooms(mazes[i]);
IMazeAlgorithm algorithmForFloor = GetAlgorithm(selectedAlgorithm);
algorithmForFloor.Generate(mazes[i]);
}
GenerateConnections();
for (int i = 0; i < mazes.Length; i++)
{
mazeRenderer.Initialize(mazes[i], mazeContainer, i == 0);
}
if (mazes.Length > 0) _grid = mazes[0];
completionPercentage = 100f;
}
private IEnumerator GenerateMazeRoutine()
{
_modifiedCells.Clear();
completionPercentage = 0f;
for (int i = 0; i < mazes.Length; i++)
{
mazes[i] = new MazeGrid(width, depth);
mazes[i].Level = i;
int floorIndex = i;
mazes[i].OnCellChanged += (x, z, type) =>
{
if (type != MazeCellType.Wall)
{
_modifiedCells.Add(new Vector3Int(x, floorIndex, z));
int totalCells = width * depth * mazes.Length;
// Approximate the progress to reach roughly 100% since algorithms don't visit all cells
float fillRatio = 0.6f;
completionPercentage = Mathf.Clamp((_modifiedCells.Count / ((float)totalCells * fillRatio)) * 100f, 0, 99f);
}
};
CarveRooms(mazes[i]);
mazeRenderer.Initialize(mazes[i], mazeContainer, i == 0);
IMazeAlgorithm algorithmForFloor = GetAlgorithm(selectedAlgorithm);
cellsProcessedThisFrame = 0;
yield return StartCoroutine(algorithmForFloor.GenerateStepByStep(mazes[i], generationSpeed));
}
GenerateConnections();
if (mazes.Length > 0) _grid = mazes[0];
completionPercentage = 100f;
_generationCoroutine = null;
}
private void GenerateConnections()
{
// Step 2: Create connections between adjacent floors
for (int i = 0; i < mazes.Length - 1; i++)
{
MazeGrid currentFloor = mazes[i];
MazeGrid nextFloor = mazes[i + 1];
List<Vector2Int> possibleConnections = new List<Vector2Int>();
for (int z = 0; z < depth; z++)
{
for (int x = 0; x < width; x++)
{
// Check if both floors have a corridor at this position
bool isCurrentFloorPath = currentFloor.GetCell(x, z) == MazeCellType.Corridor;
bool isNextFloorPath = nextFloor.GetCell(x, z) == MazeCellType.Corridor;
if (isCurrentFloorPath && isNextFloorPath)
{
possibleConnections.Add(new Vector2Int(x, z));
}
}
}
ShuffleList(possibleConnections);
int connectionsMade = 0;
foreach (Vector2Int pos in possibleConnections)
{
if (connectionsMade >= connectionsPerFloor) break;
int x = pos.x;
int z = pos.y;
// Set stair cells
currentFloor.SetCell(x, z, MazeCellType.StairsUp);
nextFloor.SetCell(x, z, MazeCellType.StairsDown);
connectionsMade++;
}
}
}
private void CarveRooms(MazeGrid grid)
{
if (!generateRooms) return;
for (int i = 0; i < numberOfRooms; i++)
{
int w = Random.Range(minRoomSize.x, maxRoomSize.x + 1);
int d = Random.Range(minRoomSize.y, maxRoomSize.y + 1);
int startX = Random.Range(1, width - w - 1);
int startZ = Random.Range(1, depth - d - 1);
for (int x = startX; x < startX + w; x++)
{
for (int z = startZ; z < startZ + d; z++)
{
grid.SetCell(x, z, MazeCellType.Room);
}
}
// Carve guaranteed door to seed pathfinding
if (Random.value > 0.5f)
{
int doorX = Random.Range(startX, startX + w);
int doorZ = Random.value > 0.5f ? startZ + d : startZ - 1;
grid.SetCell(doorX, doorZ, MazeCellType.Corridor);
}
else
{
int doorX = Random.value > 0.5f ? startX + w : startX - 1;
int doorZ = Random.Range(startZ, startZ + d);
grid.SetCell(doorX, doorZ, MazeCellType.Corridor);
}
}
}
private void ShuffleList<T>(List<T> list)
{
for (int i = 0; i < list.Count; i++)
{
T temp = list[i];
int randomIndex = Random.Range(i, list.Count);
list[i] = list[randomIndex];
list[randomIndex] = temp;
}
}
private IMazeAlgorithm GetAlgorithm(AlgorithmType type)
{
return type switch
{
AlgorithmType.Recursive => new RecursiveAlgorithm(),
AlgorithmType.Wilsons => new WilsonsAlgorithm(),
AlgorithmType.Prims => new PrimsAlgorithm(),
AlgorithmType.Crawler => new CrawlerAlgorithm(),
AlgorithmType.NoiseRecursive => new NoiseRecursiveGenerator(),
_ => new RecursiveAlgorithm()
};
}
[Button("Find Scene References")]
private void FindSceneReferences()
{
if (mazeRenderer == null)
{
mazeRenderer = GetComponentInChildren<MazeRenderer>();
}
if (mazeContainer == null)
{
mazeContainer = transform;
}
}
private bool HasAtLeastOneFloor(MazeGrid[] floors)
{
return floors != null && floors.Length > 0;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 3607adabe0c29c34591af73b414eb17a

View File

@@ -1,489 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Responsible for the visual representation of the maze.
/// Handles spawning, pooling, and animations with safety checks.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class MazeRenderer : MonoBehaviour
{
[BoxGroup("Visuals")]
[Required]
[InlineEditor]
[SerializeField] private MazeVisualProfile visualProfile;
[BoxGroup("Visuals")]
[MinValue(0.001f)]
public float floorHeight = 3.5f;
public float Scale => visualProfile != null ? visualProfile.scale : 1f;
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public enum CellAnimationType { None, ScaleUp, DropDown, SpinIn }
[HideInInspector]
public CellAnimationType currentAnimationType = CellAnimationType.ScaleUp;
[ShowInInspector]
[ReadOnly]
[BoxGroup("Runtime")]
private int SpawnedCellCount => _spawnedCells.Count;
[ShowInInspector]
[ReadOnly]
[BoxGroup("Runtime")]
private int RenderedFloorCount => _grids.Count;
private readonly Dictionary<Vector3Int, GameObject> _spawnedCells = new Dictionary<Vector3Int, GameObject>();
private Transform _container;
private List<MazeGrid> _grids = new List<MazeGrid>();
public void Initialize(MazeGrid grid, Transform container, bool clearExisting = true)
{
if (visualProfile == null)
{
Debug.LogError("MazeRenderer needs a MazeVisualProfile before it can render.", this);
return;
}
if (grid == null)
{
Debug.LogError("MazeRenderer received a null MazeGrid.", this);
return;
}
if (clearExisting)
{
Clear();
}
_container = container;
if (!_grids.Contains(grid))
{
_grids.Add(grid);
grid.OnCellChanged += (x, z, type) => HandleCellChanged(grid, x, z, type);
}
// Initial render
for (int z = 0; z < grid.Depth; z++)
{
for (int x = 0; x < grid.Width; x++)
{
UpdateCellVisual(grid, x, z, grid.GetCell(x, z), false);
}
}
}
public void Clear()
{
StopAllCoroutines();
foreach (var cell in _spawnedCells.Values)
{
if (cell == null) continue;
if (Application.isPlaying)
Destroy(cell);
else
DestroyImmediate(cell);
}
_spawnedCells.Clear();
foreach (var grid in _grids)
{
// Note: We can't easily unsubscribe because the lambda captures 'grid'.
// In a production environment, we should use a proper event handler method.
}
_grids.Clear();
}
[Button("Clear Spawned Maze")]
private void ClearFromInspector()
{
Clear();
}
private void HandleCellChanged(MazeGrid grid, int x, int z, MazeCellType type)
{
UpdateCellVisual(grid, x, z, type, true);
UpdateNeighborVisual(grid, x + 1, z);
UpdateNeighborVisual(grid, x - 1, z);
UpdateNeighborVisual(grid, x, z + 1);
UpdateNeighborVisual(grid, x, z - 1);
}
private void UpdateNeighborVisual(MazeGrid grid, int x, int z)
{
if (grid != null && grid.IsInBounds(x, z))
{
if (IsPath(grid, x, z))
{
MazeCellType type = grid.GetCell(x, z);
UpdateCellVisual(grid, x, z, type, false);
}
}
}
private void UpdateCellVisual(MazeGrid grid, int x, int z, MazeCellType type, bool animate)
{
Vector3Int posKey = new Vector3Int(x, grid.Level, z);
if (_spawnedCells.TryGetValue(posKey, out GameObject oldObj))
{
if (oldObj != null) DestroyImmediate(oldObj);
_spawnedCells.Remove(posKey);
}
if (type == MazeCellType.Wall) return;
float logicalSpacing = visualProfile.nodeSpacing; // Distances between Nodes
float halfSpacing = logicalSpacing / 2f;
float safeScale = Mathf.Max(0.001f, visualProfile.scale);
float spacingScale = logicalSpacing * safeScale;
float yOffset = grid.Level * floorHeight;
Vector3 localPos = new Vector3(x * spacingScale, yOffset, z * spacingScale);
GameObject cellParent = new GameObject($"Cell_{x}_{grid.Level}_{z}");
cellParent.transform.SetParent(_container);
cellParent.transform.localPosition = localPos;
bool spawnedAnything = false;
if (type == MazeCellType.Corridor || type == MazeCellType.Processing || type == MazeCellType.StairsUp || type == MazeCellType.StairsDown)
{
// 1. Spawn Node (Intersection, Corner, T, DeadEnd, or Stairs)
GameObject nodePrefab;
Quaternion nodeRot;
Vector3 nodeOffset = Vector3.zero;
if (type == MazeCellType.StairsUp || type == MazeCellType.StairsDown)
{
nodePrefab = visualProfile.GetPrefab(type);
nodeRot = Quaternion.Euler(0, visualProfile.stairsOffset, 0);
}
else
{
(nodePrefab, nodeRot, nodeOffset) = GetNodePrefabAndRotation(grid, x, z);
}
if (nodePrefab != null)
{
GameObject node = Instantiate(nodePrefab, cellParent.transform);
node.transform.localPosition = nodeOffset * safeScale;
node.transform.localRotation = nodeRot;
node.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
// 2. Spawn Edge X (Right path)
if (IsPath(grid, x + 1, z))
{
GameObject edgePrefab = visualProfile.corridorStraight;
if (edgePrefab != null)
{
GameObject edgeX = Instantiate(edgePrefab, cellParent.transform);
edgeX.transform.localPosition = new Vector3(halfSpacing * safeScale, 0, 0); // half units offset right
edgeX.transform.localRotation = Quaternion.Euler(0, 90f, 0); // pointing along X
edgeX.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
}
// 3. Spawn Edge Z (Top path)
if (IsPath(grid, x, z + 1))
{
GameObject edgePrefab = visualProfile.corridorStraight;
if (edgePrefab != null)
{
GameObject edgeZ = Instantiate(edgePrefab, cellParent.transform);
edgeZ.transform.localPosition = new Vector3(0, 0, halfSpacing * safeScale); // half units offset forward
edgeZ.transform.localRotation = Quaternion.identity; // pointing along Z
edgeZ.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
}
}
else if (type == MazeCellType.Room)
{
// Spawn Floor
if (visualProfile.roomFloorPrefab != null)
{
GameObject floor = Instantiate(visualProfile.roomFloorPrefab, cellParent.transform);
floor.transform.localPosition = Vector3.zero;
floor.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
// Spawn Ceiling
if (visualProfile.roomCeilingPrefab != null)
{
GameObject ceiling = Instantiate(visualProfile.roomCeilingPrefab, cellParent.transform);
ceiling.transform.localPosition = new Vector3(0, floorHeight, 0);
ceiling.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
// Spawn Room Edges (Walls or Doors)
MazeCellType top = grid.IsInBounds(x, z + 1) ? grid.GetCell(x, z + 1) : MazeCellType.Wall;
SpawnRoomEdge(cellParent, top, new Vector3(0, 0, halfSpacing * safeScale), 0f, safeScale);
MazeCellType right = grid.IsInBounds(x + 1, z) ? grid.GetCell(x + 1, z) : MazeCellType.Wall;
SpawnRoomEdge(cellParent, right, new Vector3(halfSpacing * safeScale, 0, 0), 90f, safeScale);
MazeCellType bottom = grid.IsInBounds(x, z - 1) ? grid.GetCell(x, z - 1) : MazeCellType.Wall;
SpawnRoomEdge(cellParent, bottom, new Vector3(0, 0, -halfSpacing * safeScale), 180f, safeScale);
MazeCellType left = grid.IsInBounds(x - 1, z) ? grid.GetCell(x - 1, z) : MazeCellType.Wall;
SpawnRoomEdge(cellParent, left, new Vector3(-halfSpacing * safeScale, 0, 0), 270f, safeScale);
spawnedAnything = true; // Always true if it reaches here
}
else
{
// Non-corridor logic (Start, End, etc)
GameObject prefab = visualProfile.GetPrefab(type);
if (prefab != null)
{
GameObject obj = Instantiate(prefab, cellParent.transform);
obj.transform.localPosition = Vector3.zero;
obj.transform.localRotation = Quaternion.identity;
obj.transform.localScale = Vector3.one * safeScale;
spawnedAnything = true;
}
}
if (!spawnedAnything)
{
DestroyImmediate(cellParent);
return;
}
_spawnedCells[posKey] = cellParent;
if (animate && visualProfile.animationDuration > 0)
{
StartCoroutine(AnimateCell(cellParent.transform));
}
}
// =================================================================================
// THUẬT TOÁN BITMASK AUTO-TILING
// =================================================================================
private (GameObject, Quaternion, Vector3) GetNodePrefabAndRotation(MazeGrid grid, int x, int z)
{
bool top = IsPath(grid, x, z + 1);
bool right = IsPath(grid, x + 1, z);
bool bottom = IsPath(grid, x, z - 1);
bool left = IsPath(grid, x - 1, z);
int mask = 0;
if (top) mask += 1;
if (right) mask += 2;
if (bottom) mask += 4;
if (left) mask += 8;
GameObject prefabToSpawn = null;
float yRotation = 0f;
Vector3 offset = Vector3.zero;
// Push dead ends to the boundary where edges end
float endOffset = visualProfile.deadEndShift;
switch (mask)
{
case 1:
prefabToSpawn = visualProfile.corridorDeadEnd;
yRotation = 0f;
offset = new Vector3(0, 0, endOffset);
break;
case 2:
prefabToSpawn = visualProfile.corridorDeadEnd;
yRotation = 90f;
offset = new Vector3(endOffset, 0, 0);
break;
case 4:
prefabToSpawn = visualProfile.corridorDeadEnd;
yRotation = 180f;
offset = new Vector3(0, 0, -endOffset);
break;
case 8:
prefabToSpawn = visualProfile.corridorDeadEnd;
yRotation = 270f;
offset = new Vector3(-endOffset, 0, 0);
break;
case 5:
prefabToSpawn = visualProfile.corridorStraight;
yRotation = 0f;
break;
case 10:
prefabToSpawn = visualProfile.corridorStraight;
yRotation = 90f;
break;
case 3:
prefabToSpawn = visualProfile.corridorCorner;
yRotation = 0f;
break;
case 6:
prefabToSpawn = visualProfile.corridorCorner;
yRotation = 90f;
break;
case 12:
prefabToSpawn = visualProfile.corridorCorner;
yRotation = 180f;
break;
case 9:
prefabToSpawn = visualProfile.corridorCorner;
yRotation = 270f;
break;
case 11:
prefabToSpawn = visualProfile.corridorTJunction;
yRotation = 0f;
break;
case 7:
prefabToSpawn = visualProfile.corridorTJunction;
yRotation = 90f;
break;
case 14:
prefabToSpawn = visualProfile.corridorTJunction;
yRotation = 180f;
break;
case 13:
prefabToSpawn = visualProfile.corridorTJunction;
yRotation = 270f;
break;
case 15:
prefabToSpawn = visualProfile.corridorCross;
yRotation = 0f;
break;
default:
prefabToSpawn = visualProfile.corridorDeadEnd;
yRotation = 0f;
break;
}
float finalRotation = yRotation;
if (prefabToSpawn == visualProfile.corridorTJunction) finalRotation += visualProfile.tJunctionOffset;
if (prefabToSpawn == visualProfile.corridorDeadEnd) finalRotation += visualProfile.deadEndOffset;
if (prefabToSpawn == visualProfile.corridorCorner) finalRotation += visualProfile.cornerOffset;
if (prefabToSpawn == null) prefabToSpawn = visualProfile.corridorPrefab;
return (prefabToSpawn, Quaternion.Euler(0, finalRotation, 0), offset);
}
private void SpawnRoomEdge(GameObject parent, MazeCellType neighborType, Vector3 offset, float yRot, float safeScale)
{
if (neighborType == MazeCellType.Room)
return; // Open space to another room cell
GameObject prefabToSpawn = null;
if (neighborType == MazeCellType.Corridor || neighborType == MazeCellType.Processing || neighborType == MazeCellType.Start || neighborType == MazeCellType.End)
{
prefabToSpawn = visualProfile.roomDoorwayPrefab;
}
else
{
prefabToSpawn = visualProfile.roomWallPrefab;
}
if (prefabToSpawn != null)
{
GameObject edge = Instantiate(prefabToSpawn, parent.transform);
edge.transform.localPosition = offset;
edge.transform.localRotation = Quaternion.Euler(0, yRot, 0);
edge.transform.localScale = Vector3.one * safeScale;
}
}
private bool IsPath(MazeGrid grid, int x, int z)
{
if (grid == null || !grid.IsInBounds(x, z)) return false;
MazeCellType type = grid.GetCell(x, z);
return type == MazeCellType.Corridor
|| type == MazeCellType.Processing
|| type == MazeCellType.Start
|| type == MazeCellType.End
|| type == MazeCellType.Path
|| type == MazeCellType.StairsUp
|| type == MazeCellType.StairsDown;
}
// =================================================================================
// ANIMATION
// =================================================================================
private IEnumerator AnimateCell(Transform target)
{
if (target == null) yield break;
if (currentAnimationType == CellAnimationType.None) yield break;
float duration = Mathf.Max(0.01f, visualProfile.animationDuration);
float elapsed = 0;
Vector3 finalScale = target.localScale;
Vector3 finalPosition = target.localPosition;
Quaternion finalRotation = target.localRotation;
if (currentAnimationType == CellAnimationType.ScaleUp)
{
target.localScale = Vector3.one * 0.001f;
}
else if (currentAnimationType == CellAnimationType.DropDown)
{
target.localPosition = finalPosition + Vector3.up * 5f;
}
else if (currentAnimationType == CellAnimationType.SpinIn)
{
target.localScale = Vector3.one * 0.001f;
target.localRotation = finalRotation * Quaternion.Euler(0, 180, 0);
}
while (elapsed < duration)
{
if (target == null) yield break;
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / duration);
if (currentAnimationType == CellAnimationType.ScaleUp)
{
float s = Mathf.Sin(t * Mathf.PI * 0.5f);
target.localScale = finalScale * Mathf.Max(0.001f, s);
}
else if (currentAnimationType == CellAnimationType.DropDown)
{
float s = Mathf.Sin(t * Mathf.PI * 0.5f);
target.localPosition = Vector3.Lerp(finalPosition + Vector3.up * 5f, finalPosition, s);
}
else if (currentAnimationType == CellAnimationType.SpinIn)
{
float s = Mathf.Sin(t * Mathf.PI * 0.5f);
target.localScale = finalScale * Mathf.Max(0.001f, s);
target.localRotation = Quaternion.Lerp(finalRotation * Quaternion.Euler(0, 180, 0), finalRotation, s);
}
yield return null;
}
if (target != null)
{
target.localScale = finalScale;
target.localPosition = finalPosition;
target.localRotation = finalRotation;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: f30df611110713742ab984f5bead5d88

View File

@@ -1,147 +0,0 @@
using Sirenix.OdinInspector;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
[CreateAssetMenu(fileName = "MazeVisualProfile", menuName = "BABA_YAGA/Maze/Visual Profile")]
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class MazeVisualProfile : ScriptableObject
{
[BoxGroup("Rotation Offsets")]
public float tJunctionOffset = 0f;
[BoxGroup("Rotation Offsets")]
public float cornerOffset = 0f;
[BoxGroup("Rotation Offsets")]
public float deadEndOffset = 0f;
[BoxGroup("Rotation Offsets")]
public float stairsOffset = 0f;
[BoxGroup("Cell Prefabs")]
[Required]
public GameObject wallPrefab;
[BoxGroup("Cell Prefabs")]
[Required]
public GameObject corridorPrefab;
[BoxGroup("Cell Prefabs")]
public GameObject processingPrefab;
[BoxGroup("Cell Prefabs")]
public GameObject pathPrefab;
[BoxGroup("Cell Prefabs")]
public GameObject startPrefab;
[BoxGroup("Cell Prefabs")]
public GameObject endPrefab;
[BoxGroup("Cell Prefabs")]
[Required]
public GameObject stairUpPrefab;
[BoxGroup("Cell Prefabs")]
[Required]
public GameObject stairDownPrefab;
[BoxGroup("Corridor Pieces")]
[Required]
public GameObject corridorStraight;
[BoxGroup("Corridor Pieces")]
[Required]
public GameObject corridorCorner;
[BoxGroup("Corridor Pieces")]
[Required]
public GameObject corridorTJunction;
[BoxGroup("Corridor Pieces")]
[Required]
public GameObject corridorCross;
[BoxGroup("Corridor Pieces")]
[Required]
public GameObject corridorDeadEnd;
[BoxGroup("Room Pieces (Phase 2)")]
public GameObject roomFloorPrefab;
[BoxGroup("Room Pieces (Phase 2)")]
public GameObject roomWallPrefab;
[BoxGroup("Room Pieces (Phase 2)")]
public GameObject roomCeilingPrefab;
[BoxGroup("Room Pieces (Phase 2)")]
public GameObject roomDoorwayPrefab;
[BoxGroup("Visualization")]
[MinValue(0.001f)]
public float scale = 0.167f;
[BoxGroup("Visualization")]
[MinValue(1f)]
[InfoBox("The physical distance between each grid cell. Default is 6 based on 3x3 intersections and 3x2 halls.")]
public float nodeSpacing = 6f;
[BoxGroup("Visualization")]
[InfoBox("How far to push dead-end caps from the center so they touch the hallway edge. Default is 1.0.")]
public float deadEndShift = 1.0f;
[BoxGroup("Visualization")]
[MinValue(0f)]
public float animationDuration = 0.25f;
[ShowInInspector]
[ReadOnly]
[BoxGroup("Validation")]
private int MissingRequiredPrefabCount
{
get
{
var count = 0;
if (wallPrefab == null) count++;
if (corridorPrefab == null) count++;
if (stairUpPrefab == null) count++;
if (stairDownPrefab == null) count++;
if (corridorStraight == null) count++;
if (corridorCorner == null) count++;
if (corridorTJunction == null) count++;
if (corridorCross == null) count++;
if (corridorDeadEnd == null) count++;
return count;
}
}
public GameObject GetPrefab(MazeCellType type)
{
return type switch
{
MazeCellType.Wall => wallPrefab,
MazeCellType.Corridor => corridorPrefab,
MazeCellType.Processing => processingPrefab,
MazeCellType.Path => pathPrefab,
MazeCellType.Start => startPrefab,
MazeCellType.End => endPrefab,
MazeCellType.StairsUp => stairUpPrefab,
MazeCellType.StairsDown => stairDownPrefab,
_ => null
};
}
[Button("Log Missing Required Prefabs")]
private void LogMissingRequiredPrefabs()
{
if (MissingRequiredPrefabCount == 0)
{
Debug.Log($"{name}: all required maze prefabs are assigned.", this);
return;
}
Debug.LogWarning($"{name}: {MissingRequiredPrefabCount} required maze prefab reference(s) are missing.", this);
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: d3ff96571406a624381b7b0e596a4d1b

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 05fdc25279e7ac148a44fde646c93546
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,65 +0,0 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze.Native
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze.Native", sourceAssembly: "Opsive.UltimateCharacterController")]
public class NativeNoiseProvider : IDisposable
{
private const string DLL_NAME = "BackroomsNoise";
[DllImport(DLL_NAME)]
private static extern IntPtr CreateNoiseGenerator(int seed, float frequency, int noiseType);
[DllImport(DLL_NAME)]
private static extern float GetNoiseValue(IntPtr handle, float x, float z);
[DllImport(DLL_NAME)]
private static extern void GetNoiseBuffer(IntPtr handle, float startX, float startZ, int width, int depth, float[] buffer);
[DllImport(DLL_NAME)]
private static extern void DestroyNoiseGenerator(IntPtr handle);
private IntPtr _handle;
public bool IsInitialized => _handle != IntPtr.Zero;
public NativeNoiseProvider(int seed, float frequency = 0.01f, int noiseType = 0)
{
try
{
_handle = CreateNoiseGenerator(seed, frequency, noiseType);
}
catch (DllNotFoundException)
{
Debug.LogWarning($"Native library '{DLL_NAME}' not found. Ensure it is compiled and placed in Plugins folder.");
}
}
public float GetNoise(float x, float z)
{
if (!IsInitialized) return 0f;
return GetNoiseValue(_handle, x, z);
}
public void FillBuffer(float startX, float startZ, int width, int depth, float[] buffer)
{
if (!IsInitialized || buffer == null) return;
GetNoiseBuffer(_handle, startX, startZ, width, depth, buffer);
}
public void Dispose()
{
if (IsInitialized)
{
DestroyNoiseGenerator(_handle);
_handle = IntPtr.Zero;
}
}
~NativeNoiseProvider()
{
Dispose();
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 4fd030227a1b87a4f8826f9b317fbf87

View File

@@ -1,159 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Baba_yaga.GameSetup.Maze.Extensions;
using Baba_yaga.GameSetup.Maze.Native;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Advanced generator that combines C++ Native Noise with a Recursive Backtracking algorithm.
/// Creates a hybrid layout of large rooms and chaotic corridors.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class NoiseRecursiveGenerator : IMazeAlgorithm
{
private readonly List<MapLocation> _directions = MapLocation.Directions;
private float[] _noiseMap;
private int _seed = 1337;
// Thresholds
private const float RoomThreshold = 0.5f;
private const float CorridorThreshold = -0.3f;
private const int DeadEndNeighbourThreshold = 2;
public void Generate(MazeGrid grid)
{
InitializeNoise(grid);
// Step 1: Pre-place rooms based on noise peaks
for (int z = 0; z < grid.Depth; z++)
{
for (int x = 0; x < grid.Width; x++)
{
float noise = GetNoiseAt(x, z, grid.Width);
if (noise > RoomThreshold)
{
grid.SetCell(x, z, MazeCellType.Corridor);
}
}
}
// Step 2: Run recursive carving in the "connectable" zones
// We start from a few points to ensure coverage
for (int i = 0; i < 5; i++)
{
int startX = Random.Range(1, grid.Width - 1);
int startZ = Random.Range(1, grid.Depth - 1);
GenerateRecursive(grid, startX, startZ);
}
}
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
{
InitializeNoise(grid);
// Visual feedback for noise pre-placement
for (int z = 0; z < grid.Depth; z++)
{
for (int x = 0; x < grid.Width; x++)
{
float noise = GetNoiseAt(x, z, grid.Width);
if (noise > RoomThreshold)
{
grid.SetCell(x, z, MazeCellType.Processing);
}
}
if (z % 5 == 0) yield return null;
}
for (int z = 0; z < grid.Depth; z++)
{
for (int x = 0; x < grid.Width; x++)
{
if (grid.GetCell(x, z) == MazeCellType.Processing)
grid.SetCell(x, z, MazeCellType.Corridor);
}
}
yield return GenerateRecursiveStepByStep(grid, 5, 5, cellsPerFrame);
}
private void InitializeNoise(MazeGrid grid)
{
_noiseMap = new float[grid.Width * grid.Depth];
using (var provider = new NativeNoiseProvider(_seed, 0.05f))
{
if (provider.IsInitialized)
{
provider.FillBuffer(0, 0, grid.Width, grid.Depth, _noiseMap);
}
else
{
// Fallback to Unity Perlin
for (int z = 0; z < grid.Depth; z++)
{
for (int x = 0; x < grid.Width; x++)
{
_noiseMap[z * grid.Width + x] = Mathf.PerlinNoise(x * 0.1f, z * 0.1f) * 2f - 1f;
}
}
}
}
}
private float GetNoiseAt(int x, int z, int width)
{
if (_noiseMap == null) return 0f;
return _noiseMap[z * width + x];
}
private void GenerateRecursive(MazeGrid grid, int x, int z)
{
if (!grid.IsInBounds(x, z)) return;
if (grid.GetCell(x, z) != MazeCellType.Wall) return;
if (GetNoiseAt(x, z, grid.Width) < CorridorThreshold) return;
if (grid.GetCell(x, z) == MazeCellType.Corridor) return;
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) return;
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
shuffledDirs.Shuffle();
foreach (var dir in shuffledDirs)
{
GenerateRecursive(grid, x + dir.x, z + dir.z);
}
}
private IEnumerator GenerateRecursiveStepByStep(MazeGrid grid, int x, int z, int cellsPerFrame)
{
if (!grid.IsInBounds(x, z)) yield break;
if (grid.GetCell(x, z) != MazeCellType.Wall) yield break;
if (GetNoiseAt(x, z, grid.Width) < CorridorThreshold) yield break;
if (grid.GetCell(x, z) == MazeCellType.Corridor) yield break;
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) yield break;
grid.SetCell(x, z, MazeCellType.Processing);
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
shuffledDirs.Shuffle();
foreach (var dir in shuffledDirs)
{
yield return GenerateRecursiveStepByStep(grid, x + dir.x, z + dir.z, cellsPerFrame);
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 22e17049420e98f43a692fd3e7d7d261

View File

@@ -1,112 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class PrimsAlgorithm : IMazeAlgorithm
{
private const int InitialX = 2;
private const int InitialZ = 2;
private const int MaxIterations = 10000;
private const int TargetCorridorNeighbours = 1;
public void Generate(MazeGrid grid)
{
int x = InitialX;
int z = InitialZ;
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> walls = GetNeighbouringWalls(grid, x, z);
int iterations = 0;
while (walls.Count > 0 && iterations < MaxIterations)
{
int rIndex = Random.Range(0, walls.Count);
MapLocation w = walls[rIndex];
walls.RemoveAt(rIndex);
if (grid.CountSquareNeighbours(w.x, w.z, MazeCellType.Corridor) == TargetCorridorNeighbours)
{
grid.SetCell(w.x, w.z, MazeCellType.Corridor);
foreach (var nw in GetNeighbouringWalls(grid, w.x, w.z))
{
if (!walls.Contains(nw)) walls.Add(nw);
}
}
iterations++;
}
}
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
{
int x = InitialX;
int z = InitialZ;
grid.SetCell(x, z, MazeCellType.Corridor);
yield return null;
List<MapLocation> walls = GetNeighbouringWalls(grid, x, z);
foreach(var w in walls) grid.SetCell(w.x, w.z, MazeCellType.Processing);
int iterations = 0;
while (walls.Count > 0 && iterations < MaxIterations)
{
int rIndex = Random.Range(0, walls.Count);
MapLocation w = walls[rIndex];
walls.RemoveAt(rIndex);
if (grid.CountSquareNeighbours(w.x, w.z, MazeCellType.Corridor) == TargetCorridorNeighbours)
{
grid.SetCell(w.x, w.z, MazeCellType.Corridor);
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
foreach (var nw in GetNeighbouringWalls(grid, w.x, w.z))
{
if (grid.GetCell(nw.x, nw.z) == MazeCellType.Wall)
{
grid.SetCell(nw.x, nw.z, MazeCellType.Processing);
walls.Add(nw);
}
}
}
else
{
// If it's no longer a candidate, turn it back to Wall
grid.SetCell(w.x, w.z, MazeCellType.Wall);
}
iterations++;
}
}
private List<MapLocation> GetNeighbouringWalls(MazeGrid grid, int x, int z)
{
List<MapLocation> neighbours = new List<MapLocation>();
foreach (var dir in MapLocation.Directions)
{
int nx = x + dir.x;
int nz = z + dir.z;
// Correction
nx = x + dir.x;
nz = z + dir.z;
if (grid.IsInBounds(nx, nz))
{
MazeCellType type = grid.GetCell(nx, nz);
if (type == MazeCellType.Wall || type == MazeCellType.Processing)
{
neighbours.Add(new MapLocation(nx, nz));
}
}
}
return neighbours;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: edcdd3c0aa9656a4797b83cc675aa629

View File

@@ -1,77 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Baba_yaga.GameSetup.Maze.Extensions;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class RecursiveAlgorithm : IMazeAlgorithm
{
private const int StartX = 5;
private const int StartZ = 5;
private const int DeadEndNeighbourThreshold = 2;
private readonly List<MapLocation> _directions = MapLocation.Directions;
public void Generate(MazeGrid grid)
{
GenerateRecursive(grid, StartX, StartZ);
}
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
{
yield return GenerateRecursiveStepByStep(grid, StartX, StartZ, cellsPerFrame);
}
private void GenerateRecursive(MazeGrid grid, int x, int z)
{
if (grid.GetCell(x, z) != MazeCellType.Wall) return;
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) return;
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
shuffledDirs.Shuffle();
foreach (var dir in shuffledDirs)
{
int nx = x + dir.x;
int nz = z + dir.z;
if (grid.IsInBounds(nx, nz))
{
GenerateRecursive(grid, nx, nz);
}
}
}
private IEnumerator GenerateRecursiveStepByStep(MazeGrid grid, int x, int z, int cellsPerFrame)
{
if (grid.GetCell(x, z) != MazeCellType.Wall) yield break;
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) yield break;
grid.SetCell(x, z, MazeCellType.Processing);
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
shuffledDirs.Shuffle();
foreach (var dir in shuffledDirs)
{
int nx = x + dir.x;
int nz = z + dir.z;
if (grid.IsInBounds(nx, nz))
{
yield return GenerateRecursiveStepByStep(grid, nx, nz, cellsPerFrame);
}
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 2460c0e9379da9741b3d3387aa6c7a8e

View File

@@ -1,182 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Baba_yaga.GameSetup.Maze
{
/// <summary>
/// Wilson's Algorithm implementation based on the original provided logic.
/// Ensures paths are sparse and correctly finalized using specific neighbor constraints.
/// </summary>
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.GameSetup.Maze", sourceAssembly: "Opsive.UltimateCharacterController")]
public class WilsonsAlgorithm : IMazeAlgorithm
{
private const int MinBoundary = 2;
private const int MaxIterationSafety = 5000;
private const int MaxWalkSteps = 5000;
private readonly List<MapLocation> _directions = MapLocation.Directions;
private List<MapLocation> _notUsed = new List<MapLocation>();
public void Generate(MazeGrid grid)
{
// 1. Create a starting finalized cell (Type.Corridor represents state 2)
int x = Random.Range(MinBoundary, grid.Width - 1);
int z = Random.Range(MinBoundary, grid.Depth - 1);
grid.SetCell(x, z, MazeCellType.Corridor);
int safety = 0;
while (GetAvailableCells(grid) > 1 && safety < MaxIterationSafety)
{
RandomWalkSync(grid);
safety++;
}
}
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
{
int x = Random.Range(MinBoundary, grid.Width - 1);
int z = Random.Range(MinBoundary, grid.Depth - 1);
grid.SetCell(x, z, MazeCellType.Corridor);
yield return null;
int safety = 0;
while (GetAvailableCells(grid) > 1 && safety < MaxIterationSafety)
{
yield return RandomWalk(grid, cellsPerFrame);
safety++;
}
}
/// <summary>
/// Counts neighbors that are already part of the finalized maze (State 2 / Corridor).
/// </summary>
private int CountFinalizedNeighbours(MazeGrid grid, int x, int z)
{
int count = 0;
foreach (var d in _directions)
{
if (grid.GetCell(x + d.x, z + d.z) == MazeCellType.Corridor)
{
count++;
}
}
return count;
}
private int GetAvailableCells(MazeGrid grid)
{
_notUsed.Clear();
for (int z = 1; z < grid.Depth - 1; z++)
{
for (int x = 1; x < grid.Width - 1; x++)
{
if (CountFinalizedNeighbours(grid, x, z) == 0)
{
_notUsed.Add(new MapLocation(x, z));
}
}
}
return _notUsed.Count;
}
private void RandomWalkSync(MazeGrid grid)
{
if (_notUsed.Count == 0) return;
List<MapLocation> inWalk = new List<MapLocation>();
int rStartIndex = Random.Range(0, _notUsed.Count);
int cx = _notUsed[rStartIndex].x;
int cz = _notUsed[rStartIndex].z;
inWalk.Add(new MapLocation(cx, cz));
int loop = 0;
bool validPath = false;
while (cx > 0 && cx < grid.Width - 1 && cz > 0 && cz < grid.Depth - 1 && loop < MaxWalkSteps && !validPath)
{
// Mark as temporary walk (State 0 / Processing)
// Note: We don't set grid cell here in sync mode to avoid triggering events unnecessarily
// but we keep track of neighbors.
if (CountFinalizedNeighbours(grid, cx, cz) > 1) break;
MapLocation rd = _directions[Random.Range(0, _directions.Count)];
int nx = cx + rd.x;
int nz = cz + rd.z;
// User's original constraint: CountSquareNeighbours (nx, nz) < 2
if (CountFinalizedNeighbours(grid, nx, nz) < 2)
{
cx = nx;
cz = nz;
inWalk.Add(new MapLocation(cx, cz));
}
validPath = CountFinalizedNeighbours(grid, cx, cz) == 1;
loop++;
}
if (validPath)
{
foreach (MapLocation m in inWalk)
grid.SetCell(m.x, m.z, MazeCellType.Corridor);
}
}
private IEnumerator RandomWalk(MazeGrid grid, int cellsPerFrame)
{
if (_notUsed.Count == 0) yield break;
List<MapLocation> inWalk = new List<MapLocation>();
int rStartIndex = Random.Range(0, _notUsed.Count);
int cx = _notUsed[rStartIndex].x;
int cz = _notUsed[rStartIndex].z;
inWalk.Add(new MapLocation(cx, cz));
int loop = 0;
bool validPath = false;
while (cx > 0 && cx < grid.Width - 1 && cz > 0 && cz < grid.Depth - 1 && loop < MaxWalkSteps && !validPath)
{
grid.SetCell(cx, cz, MazeCellType.Processing); // State 0
MazeManager.cellsProcessedThisFrame++;
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
{
MazeManager.cellsProcessedThisFrame = 0;
yield return null;
}
if (CountFinalizedNeighbours(grid, cx, cz) > 1) break;
MapLocation rd = _directions[Random.Range(0, _directions.Count)];
int nx = cx + rd.x;
int nz = cz + rd.z;
if (CountFinalizedNeighbours(grid, nx, nz) < 2)
{
cx = nx;
cz = nz;
inWalk.Add(new MapLocation(cx, cz));
}
validPath = CountFinalizedNeighbours(grid, cx, cz) == 1;
loop++;
}
if (validPath)
{
foreach (MapLocation m in inWalk)
{
grid.SetCell(m.x, m.z, MazeCellType.Corridor); // State 2
}
}
else
{
foreach (MapLocation m in inWalk)
grid.SetCell(m.x, m.z, MazeCellType.Wall); // State 1
}
inWalk.Clear();
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 61156f8986612ca49a0672ad5542380f

View File

@@ -0,0 +1,30 @@
using UnityEngine;
using System.Collections.Generic;
public class CameraJumpPoints : MonoBehaviour
{
[System.Serializable]
public class JumpPoint
{
public string name = "New Point";
public Transform target;
public KeyCode key = KeyCode.None;
public bool ctrl;
public bool alt;
public bool shift;
public string GetKeyString()
{
if (key == KeyCode.None) return "None";
string s = "";
if (ctrl) s += "Ctrl+";
if (alt) s += "Alt+";
if (shift) s += "Shift+";
s += key.ToString();
return s;
}
}
[Tooltip("List of camera bookmarks. Add a point, assign a target transform, and click the shortcut button to record a key binding.")]
public List<JumpPoint> points = new List<JumpPoint>();
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 212b1bae8c7de584f8dfd3e9cc45a6cb

View File

@@ -74,6 +74,8 @@ MonoBehaviour:
- globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-786488-0 - globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-786488-0
- globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-747234399-0 - globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-747234399-0
- globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-598933323-0 - globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-598933323-0
- globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-1896629830-0
- globalObjectIdString: GlobalObjectId_V1-2-eda5fe9b4dec586498dcf6d3f2e63088-907742040-0
values: values:
- colorIndex: 9 - colorIndex: 9
iconNameOrGuid: ScriptableObject Icon iconNameOrGuid: ScriptableObject Icon
@@ -99,3 +101,7 @@ MonoBehaviour:
iconNameOrGuid: LightmapParameters Icon iconNameOrGuid: LightmapParameters Icon
- colorIndex: 0 - colorIndex: 0
iconNameOrGuid: Light Icon iconNameOrGuid: Light Icon
- colorIndex: 9
iconNameOrGuid: MeshCollider Icon
- colorIndex: 0
iconNameOrGuid: Camera Icon