diff --git a/TinkStateSharp.sln b/TinkStateSharp.sln
index b6b188a..aeb9c2b 100644
--- a/TinkStateSharp.sln
+++ b/TinkStateSharp.sln
@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinkState-Unity-Test", "pro
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinkState-Godot", "projects\TinkState-Godot\TinkState-Godot.csproj", "{CD1EE987-C509-4BC5-B996-F7EAAF4BA868}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TinkState-Unity-Editor", "projects\TinkState-Unity-Editor\TinkState-Unity-Editor.csproj", "{A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}"
+EndProject
Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -102,6 +104,18 @@ Global
{CD1EE987-C509-4BC5-B996-F7EAAF4BA868}.Release|x64.Build.0 = Release|Any CPU
{CD1EE987-C509-4BC5-B996-F7EAAF4BA868}.Release|x86.ActiveCfg = Release|Any CPU
{CD1EE987-C509-4BC5-B996-F7EAAF4BA868}.Release|x86.Build.0 = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|x64.Build.0 = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Debug|x86.Build.0 = Debug|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|x64.ActiveCfg = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|x64.Build.0 = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|x86.ActiveCfg = Release|Any CPU
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6B383783-3B6F-4685-A506-1E502392E83B} = {C6990338-31DB-4CD2-BC63-DA0C25A8F043}
@@ -109,5 +123,6 @@ Global
{FBE6AC15-3025-45FA-A8EA-FBFD05A7B25F} = {C6990338-31DB-4CD2-BC63-DA0C25A8F043}
{7CC48BB6-A797-449D-B681-44A364271C97} = {C6990338-31DB-4CD2-BC63-DA0C25A8F043}
{CD1EE987-C509-4BC5-B996-F7EAAF4BA868} = {C6990338-31DB-4CD2-BC63-DA0C25A8F043}
+ {A2B35BAB-77D6-4DC7-8DF8-6E7DD9F9FAA4} = {C6990338-31DB-4CD2-BC63-DA0C25A8F043}
EndGlobalSection
EndGlobal
diff --git a/projects/TinkState-Unity-Editor/TinkState-Unity-Editor.csproj b/projects/TinkState-Unity-Editor/TinkState-Unity-Editor.csproj
new file mode 100644
index 0000000..933e7bd
--- /dev/null
+++ b/projects/TinkState-Unity-Editor/TinkState-Unity-Editor.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net6.0
+ 9.0
+ Nadako.TinkState.Unity.Editor
+
+
+
+ false
+
+
+
+
+
+
+
+
+ ../../unity-dlls/UnityEngine.dll
+
+
+ ../../unity-dlls/UnityEditor.dll
+
+
+
+
+
+
+
diff --git a/src/TinkState-Unity/Editor.meta b/src/TinkState-Unity/Editor.meta
new file mode 100644
index 0000000..a94dd8c
--- /dev/null
+++ b/src/TinkState-Unity/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 586b0f7f7e5a04897a5ef1ee5d372501
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef b/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef
new file mode 100644
index 0000000..0719d7d
--- /dev/null
+++ b/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef
@@ -0,0 +1,6 @@
+{
+ "name": "Nadako.TinkState.Unity.Editor",
+ "references": [
+ "Nadako.TinkState"
+ ]
+}
diff --git a/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef.meta b/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef.meta
new file mode 100644
index 0000000..88ad551
--- /dev/null
+++ b/src/TinkState-Unity/Editor/Nadako.TinkState.Unity.Editor.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 6e5d6eeef1bcd4ecfb82ac50ecc0b280
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/TinkState-Unity/Editor/ObservableTrackerWindow.cs b/src/TinkState-Unity/Editor/ObservableTrackerWindow.cs
new file mode 100644
index 0000000..33ceb89
--- /dev/null
+++ b/src/TinkState-Unity/Editor/ObservableTrackerWindow.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using TinkState.Internal;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace TinkState.Editor
+{
+ public class ObservableTrackerWindow : EditorWindow
+ {
+ readonly List data = new();
+
+ ListView listView;
+
+ [MenuItem("Window/Observable Tracker")]
+ public static void Open()
+ {
+ var window = GetWindow();
+ window.titleContent = new GUIContent("Observable Tracker");
+ }
+
+ void OnEnable()
+ {
+ ObservableTracker.EnableTracking = true;
+ }
+
+ void OnDisable()
+ {
+ ObservableTracker.EnableTracking = false;
+ }
+
+ public void CreateGUI()
+ {
+ const string uxmlGUID = "bc0d80c10c9ac4d5ab4a26571a0e49e3";
+ var treeAsset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(uxmlGUID));
+ var tree = treeAsset.Instantiate();
+ tree.style.flexGrow = 1;
+ rootVisualElement.Add(tree);
+
+ var stackTraceView = tree.Q