diff --git a/BeefSpace.toml b/BeefSpace.toml
index eb3b248..a5b2774 100644
--- a/BeefSpace.toml
+++ b/BeefSpace.toml
@@ -1,6 +1,5 @@
FileVersion = 1
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}}
-Unlocked = ["corlib"]
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
[Workspace]
diff --git a/GlitchyEditor/BeefProj.toml b/GlitchyEditor/BeefProj.toml
index 8b6c0f8..bb200ed 100644
--- a/GlitchyEditor/BeefProj.toml
+++ b/GlitchyEditor/BeefProj.toml
@@ -7,4 +7,14 @@ TargetType = "BeefGUIApplication"
StartupObject = "GlitchyEngine.Program"
[Configs.Debug.Win64]
-DebugCommandArguments = "\"D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor\\SandboxProject\""
+PostBuildCmds = ["CopyFilesIfNewer(\"$(WorkspaceDir)/bin/vswhere.exe\", \"$(TargetDir)\")"]
+DebugCommandArguments = "\"D:\\Development\\Git\\SingleStateToOrbit\""
+
+[Configs.Release.Win64]
+PostBuildCmds = ["CopyFilesIfNewer(\"$(WorkspaceDir)/bin/vswhere.exe\", \"$(TargetDir)\")"]
+
+[Configs.Paranoid.Win64]
+PostBuildCmds = ["CopyFilesIfNewer(\"$(WorkspaceDir)/bin/vswhere.exe\", \"$(TargetDir)\")"]
+
+[Configs.Test.Win64]
+PostBuildCmds = ["CopyFilesIfNewer(\"$(WorkspaceDir)/bin/vswhere.exe\", \"$(TargetDir)\")"]
diff --git a/GlitchyEditor/resources/ProjectTemplate/.gitignore b/GlitchyEditor/resources/ProjectTemplate/.gitignore
index 4144d89..7e0e7b8 100644
--- a/GlitchyEditor/resources/ProjectTemplate/.gitignore
+++ b/GlitchyEditor/resources/ProjectTemplate/.gitignore
@@ -1 +1,401 @@
+# Ignore user Settings
project_user.bon
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
diff --git a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/.gitignore b/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/.gitignore
deleted file mode 100644
index 8a30d25..0000000
--- a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/.gitignore
+++ /dev/null
@@ -1,398 +0,0 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
-
-# User-specific files
-*.rsuser
-*.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Mono auto generated files
-mono_crash.*
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-[Ww][Ii][Nn]32/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
-bld/
-[Bb]in/
-[Oo]bj/
-[Ll]og/
-[Ll]ogs/
-
-# Visual Studio 2015/2017 cache/options directory
-.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# Visual Studio 2017 auto generated files
-Generated\ Files/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUnit
-*.VisualState.xml
-TestResult.xml
-nunit-*.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# Benchmark Results
-BenchmarkDotNet.Artifacts/
-
-# .NET Core
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-# ASP.NET Scaffolding
-ScaffoldingReadMe.txt
-
-# StyleCop
-StyleCopReport.xml
-
-# Files built by Visual Studio
-*_i.c
-*_p.c
-*_h.h
-*.ilk
-*.meta
-*.obj
-*.iobj
-*.pch
-*.pdb
-*.ipdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*_wpftmp.csproj
-*.log
-*.tlog
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# Visual Studio Trace Files
-*.e2e
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# AxoCover is a Code Coverage Tool
-.axoCover/*
-!.axoCover/settings.json
-
-# Coverlet is a free, cross platform Code Coverage Tool
-coverage*.json
-coverage*.xml
-coverage*.info
-
-# Visual Studio code coverage results
-*.coverage
-*.coveragexml
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# Note: Comment the next line if you want to checkin your web deploy settings,
-# but database connection strings (with potential passwords) will be unencrypted
-*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# NuGet Symbol Packages
-*.snupkg
-# The packages folder can be ignored because of Package Restore
-**/[Pp]ackages/*
-# except build/, which is used as an MSBuild target.
-!**/[Pp]ackages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/[Pp]ackages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-*.appx
-*.appxbundle
-*.appxupload
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!?*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-orleans.codegen.cs
-
-# Including strong name files can present a security risk
-# (https://github.com/github/gitignore/pull/2483#issue-259490424)
-#*.snk
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-ServiceFabricBackup/
-*.rptproj.bak
-
-# SQL Server files
-*.mdf
-*.ldf
-*.ndf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-*.rptproj.rsuser
-*- [Bb]ackup.rdl
-*- [Bb]ackup ([0-9]).rdl
-*- [Bb]ackup ([0-9][0-9]).rdl
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-node_modules/
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
-*.vbw
-
-# Visual Studio 6 auto-generated project file (contains which files were open etc.)
-*.vbp
-
-# Visual Studio 6 workspace and project file (working project files containing files to include in project)
-*.dsw
-*.dsp
-
-# Visual Studio 6 technical files
-*.ncb
-*.aps
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# CodeRush personal settings
-.cr/personal
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
-
-# Tabs Studio
-*.tss
-
-# Telerik's JustMock configuration file
-*.jmconfig
-
-# BizTalk build output
-*.btp.cs
-*.btm.cs
-*.odx.cs
-*.xsd.cs
-
-# OpenCover UI analysis results
-OpenCover/
-
-# Azure Stream Analytics local run output
-ASALocalRun/
-
-# MSBuild Binary and Structured Log
-*.binlog
-
-# NVidia Nsight GPU debugger configuration file
-*.nvuser
-
-# MFractors (Xamarin productivity tool) working folder
-.mfractor/
-
-# Local History for Visual Studio
-.localhistory/
-
-# Visual Studio History (VSHistory) files
-.vshistory/
-
-# BeatPulse healthcheck temp database
-healthchecksdb
-
-# Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
-
-# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
-
-# Fody - auto-generated XML schema
-FodyWeavers.xsd
-
-# VS Code files for those working on multiple tools
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
-*.code-workspace
-
-# Local History for Visual Studio Code
-.history/
-
-# Windows Installer files from build outputs
-*.cab
-*.msi
-*.msix
-*.msm
-*.msp
-
-# JetBrains Rider
-*.sln.iml
diff --git a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/Properties/AssemblyInfo.cs b/GlitchyEditor/resources/ProjectTemplate/Properties/AssemblyInfo.cs
similarity index 100%
rename from GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/Properties/AssemblyInfo.cs
rename to GlitchyEditor/resources/ProjectTemplate/Properties/AssemblyInfo.cs
diff --git a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/TemplateProject.csproj b/GlitchyEditor/resources/ProjectTemplate/TemplateProject.csproj
similarity index 98%
rename from GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/TemplateProject.csproj
rename to GlitchyEditor/resources/ProjectTemplate/TemplateProject.csproj
index 700eefa..9334329 100644
--- a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/TemplateProject.csproj
+++ b/GlitchyEditor/resources/ProjectTemplate/TemplateProject.csproj
@@ -48,6 +48,7 @@
+
\ No newline at end of file
diff --git a/GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/TemplateProject.sln b/GlitchyEditor/resources/ProjectTemplate/TemplateProject.sln
similarity index 100%
rename from GlitchyEditor/resources/ProjectTemplate/Assets/Scripts/TemplateProject.sln
rename to GlitchyEditor/resources/ProjectTemplate/TemplateProject.sln
diff --git a/GlitchyEditor/resources/Templates/ScriptTemplate.cs b/GlitchyEditor/resources/Templates/ScriptTemplate.cs
new file mode 100644
index 0000000..df74a0e
--- /dev/null
+++ b/GlitchyEditor/resources/Templates/ScriptTemplate.cs
@@ -0,0 +1,24 @@
+using GlitchyEngine;
+using GlitchyEngine.Math;
+using System;
+
+using static GlitchyEngine.Math.Math;
+
+namespace [ProjectName];
+
+public class [EntityName] : Entity
+{
+ ///
+ /// OnCreate is called once before the first call to OnUpdate.
+ ///
+ void OnCreate()
+ {
+ }
+
+ ///
+ /// OnUpdate is called once every frame.
+ ///
+ void OnUpdate(float deltaTime)
+ {
+ }
+}
diff --git a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf
index 9a8bfc3..25d45b4 100644
--- a/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf
+++ b/GlitchyEditor/src/EditWindows/ContentBrowserWindow.bf
@@ -9,6 +9,7 @@ using GlitchyEngine.Math;
using GlitchyEngine.Content;
using GlitchyEngine;
using GlitchyEditor.Assets;
+using System.Diagnostics;
namespace GlitchyEditor.EditWindows
{
@@ -191,7 +192,17 @@ namespace GlitchyEditor.EditWindows
if (ImGui.MenuItem("Open C# Project..."))
{
- // TODO
+ String solutionPath = scope .();
+ Editor.Instance.CurrentProject.PathInProject(solutionPath, scope $"{Editor.Instance.CurrentProject.Name}.sln");
+
+ ProcessStartInfo psi = scope .();
+ psi.SetFileName("devenv");
+ psi.SetArguments(solutionPath);
+
+ scope SpawnedProcess().Start(psi);
+
+ /*if (Path.OpenFolder(solutionPath) case .Err)
+ Log.EngineLogger.Error("Failed to open file.");*/
}
}
@@ -399,7 +410,7 @@ namespace GlitchyEditor.EditWindows
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
// If we aren't the last entry and the next button won't fit on the same line we start a new line.
- if (entry != files.Back && expectedButtonRight < window_visible_x2)
+ if ((entry != files.Back || _showNewFile) && expectedButtonRight < window_visible_x2)
ImGui.SameLine();
ImGui.PopID();
@@ -462,7 +473,7 @@ namespace GlitchyEditor.EditWindows
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
{
- EntryDoubleClicked(entry);
+ OpenEntry(entry);
}
ImGui.TextUnformatted("..");
@@ -562,7 +573,7 @@ namespace GlitchyEditor.EditWindows
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
{
- EntryDoubleClicked(entry);
+ OpenEntry(entry);
}
if (_assetToRename == entry->Path)
@@ -773,7 +784,7 @@ namespace GlitchyEditor.EditWindows
}
}
- private void EntryDoubleClicked(TreeNode entry)
+ private void OpenEntry(TreeNode entry)
{
if (entry->IsDirectory)
{
@@ -782,7 +793,7 @@ namespace GlitchyEditor.EditWindows
else
{
if (Path.OpenFolder(entry->Path) case .Err)
- Log.EngineLogger.Error("Failed to open directory in file browser.");
+ Log.EngineLogger.Error("Failed to open file.");
}
}
}
diff --git a/GlitchyEditor/src/Editor.bf b/GlitchyEditor/src/Editor.bf
index b52aaa0..adf46ec 100644
--- a/GlitchyEditor/src/Editor.bf
+++ b/GlitchyEditor/src/Editor.bf
@@ -15,6 +15,8 @@ namespace GlitchyEditor
private EditorContentManager _contentManager;
+ private Project _currentProject;
+
private EntityHierarchyWindow _entityHierarchyWindow ~ delete _;
private ComponentEditWindow _componentEditWindow ~ delete _;
private EditorViewportWindow _sceneViewportWindow ~ delete _;
@@ -38,7 +40,13 @@ namespace GlitchyEditor
}
public EditorContentManager ContentManager => _contentManager;
-
+
+ public Project CurrentProject
+ {
+ get => _currentProject;
+ set => _currentProject = value;
+ }
+
public EntityHierarchyWindow EntityHierarchyWindow => _entityHierarchyWindow;
public ComponentEditWindow ComponentEditWindow => _componentEditWindow;
public EditorViewportWindow SceneViewportWindow => _sceneViewportWindow;
diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf
index 3ef2266..534a702 100644
--- a/GlitchyEditor/src/EditorLayer.bf
+++ b/GlitchyEditor/src/EditorLayer.bf
@@ -204,6 +204,34 @@ namespace GlitchyEditor
Log.EngineLogger.Error($"Failed to save script file to \"{path}\".");
return;
}
+
+ // Add to .csproj
+ String assetRelativePath = scope .();
+ Path.GetRelativePath(path, _currentProject.WorkspacePath, assetRelativePath);
+
+ String projectPath = scope .();
+ Editor.Instance.CurrentProject.PathInProject(projectPath, scope $"{Editor.Instance.CurrentProject.Name}.csproj");
+
+ String projectFile = scope .();
+ let loadProjectResult = File.ReadAllText(projectPath, projectFile, true);
+
+ if (loadProjectResult case .Err(let err))
+ {
+ Log.EngineLogger.Error($"Failed to open project file ({err}). Please add the file to the project manually.");
+ }
+
+ const String scriptFilesMarker = "";
+
+ int index = projectFile.IndexOf(scriptFilesMarker);
+ int lineEndIndex = projectFile.IndexOf('\n', index);
+ projectFile.Insert(lineEndIndex + 1, scope $" \n");
+
+ let saveProjectResult = File.WriteAllText(projectPath, projectFile);
+
+ if (saveProjectResult case .Err(let err))
+ {
+ Log.EngineLogger.Error($"Failed to edit project file ({err}). Please add the file to the project manually.");
+ }
}));
}
@@ -577,13 +605,14 @@ namespace GlitchyEditor
private static Result InitProject(Project project)
{
Try!(CopyTemplate(project));
-
- Try!(MoveFile(project, "Assets/Scripts/TemplateProject.sln", scope $"Assets/Scripts/{project.Name}.sln"));
- Try!(MoveFile(project, "Assets/Scripts/TemplateProject.csproj", scope $"Assets/Scripts/{project.Name}.csproj"));
- Try!(FixupTemplateFile(project, scope $"Assets/Scripts/{project.Name}.sln"));
- Try!(FixupTemplateFile(project, scope $"Assets/Scripts/{project.Name}.csproj"));
- Try!(FixupTemplateFile(project, scope $"Assets/Scripts/Properties/AssemblyInfo.cs"));
+ // Rename files within project
+ Try!(MoveFile(project, "TemplateProject.sln", scope $"{project.Name}.sln"));
+ Try!(MoveFile(project, "TemplateProject.csproj", scope $"{project.Name}.csproj"));
+
+ Try!(FixupTemplateFile(project, scope $"{project.Name}.sln"));
+ Try!(FixupTemplateFile(project, scope $"{project.Name}.csproj"));
+ Try!(FixupTemplateFile(project, scope $"Properties/AssemblyInfo.cs"));
return .Ok;
}
@@ -703,6 +732,11 @@ namespace GlitchyEditor
ImGui.Text($"The Project will be in:\n{target}");
+ if (Directory.Exists(target))
+ {
+ ImGui.TextColored(.(1, 0, 0, 1), "The directory is not empty!");
+ }
+
ImGui.NewLine();
ImGui.BeginDisabled(directory.IsWhiteSpace || projectName.IsWhiteSpace);
@@ -775,10 +809,12 @@ namespace GlitchyEditor
_currentProject = project;
+ _editor.CurrentProject = _currentProject;
+
String appAssemblyPath = scope String();
_contentManager.SetAssetDirectory(_currentProject.AssetsFolder);
- Path.Combine(appAssemblyPath, _currentProject.AssetsFolder, scope $"Scripts/bin/{_currentProject.Name}.dll");
+ _currentProject.PathInProject(appAssemblyPath, scope $"bin/{_currentProject.Name}.dll");
ScriptEngine.SetAppAssemblyPath(appAssemblyPath);
@@ -1288,6 +1324,7 @@ namespace GlitchyEditor
{
delete workspacePath;
@workspacePath.Remove();
+ continue;
}
if (ImGui.MenuItem(scope $"{i}: {workspacePath}"))
diff --git a/GlitchyEditor/src/EditorSettings.bf b/GlitchyEditor/src/EditorSettings.bf
index f6960f3..4919d90 100644
--- a/GlitchyEditor/src/EditorSettings.bf
+++ b/GlitchyEditor/src/EditorSettings.bf
@@ -3,6 +3,8 @@ using GlitchyEngine;
using Bon;
using GlitchyEditor;
using System.Collections;
+using System.IO;
+using System.Diagnostics;
namespace GlitchyEngine
{
@@ -10,16 +12,157 @@ namespace GlitchyEngine
{
[SettingContainer, BonInclude]
public readonly EditorSettings EditorSettings = new .() ~ delete _;
-
- public this()
+
+ [SettingContainer, BonInclude]
+ public readonly ScriptSettings ScriptSettings = new .() ~ delete _;
+
+ protected override void RegisterEventListeners()
{
OnApplySettings.Add(new (s, e) => EditorSettings.Apply());
+ OnApplySettings.Add(new (s, e) => ScriptSettings.Apply());
}
}
}
namespace GlitchyEditor;
+[Reflect]
+class ScriptSettings
+{
+ [Setting("Script", "Visual Studio path", "The path of the Visual Studio devenv.exe"), BonInclude]
+ public String VisualStudioPath ~ delete _;
+
+ public void Apply()
+ {
+ if (String.IsNullOrWhiteSpace(VisualStudioPath))
+ {
+ // TODO: Do later
+ //FildVisualStudio();
+ }
+ }
+
+ void FildVisualStudio()
+ {
+ // TODO: Find devenv.exe ourselves
+ String exeFile = scope .();
+ Environment.GetExecutableFilePath(exeFile);
+
+ String exeDirectory = scope .();
+ Path.GetDirectoryPath(exeFile, exeDirectory);
+
+ String vsWherePath = scope .();
+ Path.Combine(vsWherePath, exeDirectory, "vswhere.exe");
+
+ ProcessStartInfo processInfo = scope .();
+ processInfo.SetFileName(vsWherePath);
+ processInfo.UseShellExecute = true;
+ // Find the installation path of the latest visual studio
+ processInfo.SetArguments("-latest -property installationPath");
+ processInfo.RedirectStandardOutput = true;
+ //processInfo.CreateNoWindow = true;
+
+ String vsInstallDirectory = scope .();
+
+ {
+
+ Windows.FileHandle h = Windows.CreateFileA("vspath.tmp",
+ Windows.GENERIC_WRITE,
+ .ReadWrite,
+ null,
+ .Create,
+ 128,
+ .InvalidHandle);
+
+ //Windows.FileHandle h = (.)Windows.CreateFileMappingA(.InvalidHandle, null, 0x40, 4096, 4096, null);
+
+ Windows.ProcessInformation pi = .();
+ Windows.StartupInfo si = .();
+ Windows.IntBool ret = false;
+ int32 flags = Windows.CREATE_NO_WINDOW;
+
+ si.mCb = sizeof(Windows.StartupInfo);
+ si.mFlags |= Windows.STARTF_USESTDHANDLES;
+ si.mStdInput = .InvalidHandle;
+ si.mStdError = .InvalidHandle;
+ si.mStdOutput = h;
+
+ char8* cmd = scope $"{vsWherePath} -latest -property installationPath";
+ ret = Windows.CreateProcessA(null, cmd, null, null, true, flags, null, null, &si, &pi);
+
+ // Wait for the process for one second
+ Windows.WaitForSingleObject(pi.mProcess, 1000);
+
+ /*if ( ret )
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ return 0;
+ }*/
+
+
+ /*let process = scope SpawnedProcess();
+ process.AttachStandardOutput();
+ process.Start(processInfo);
+
+ while (!process.HasExited)
+ {
+
+ }
+
+ BufferedFileStream tmpFile = scope BufferedFileStream();
+ tmpFile.Open("vspath.tmp", .ReadWrite, .None, 4096, .DeleteOnClose);
+
+ //scope SpawnedProcess().Start(processInfo);
+
+ //tmpFile.Position = 0;
+
+ {
+ StreamReader reader = scope StreamReader(tmpFile);
+ reader.ReadToEnd(vsInstallDirectory);
+ }
+
+ tmpFile.Close();*/
+ }
+
+ if (VisualStudioPath == null)
+ VisualStudioPath = new String();
+ else
+ VisualStudioPath.Clear();
+
+ Path.Combine(VisualStudioPath, vsInstallDirectory, "Common7/IDE/devenv.exe");
+ }
+
+#if BF_PLATFORM_WINDOWS
+ void StartProgramm()
+ {
+ /*Windows.FileHandle h = (.)Windows.CreateFileMappingA(.InvalidHandle, null, 0x40, 4096, 4096, null);
+
+ Windows.ProcessInformation pi = .();
+ Windows.StartupInfo si = .();
+ Windows.IntBool ret = false;
+ uint32 flags = Windows.CREATE_NO_WINDOW;
+
+ si.mCb = sizeof(Windows.StartupInfo);
+ si.mFlags |= Windows.STARTF_USESTDHANDLES;
+ si.mStdInput = .InvalidHandle;
+ si.mStdError = .InvalidHandle;
+ si.mStdOutput = h;
+
+
+ ret = Windows.CreateProcessA(null, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
+
+ if ( ret )
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ return 0;
+ }
+
+ return -1;*/
+ }
+#endif
+}
+
[Reflect]
class EditorSettings
{
diff --git a/GlitchyEngine/src/Settings.bf b/GlitchyEngine/src/Settings.bf
index 66b26fe..e7cc89c 100644
--- a/GlitchyEngine/src/Settings.bf
+++ b/GlitchyEngine/src/Settings.bf
@@ -48,11 +48,16 @@ namespace GlitchyEngine
private List _userSettings ~ ClearAndDeleteItems!(_);
*/
- [AllowAppend]
public this()
{
/*List userSettings = append .();
_userSettings = userSettings;*/
+ RegisterEventListeners();
+ }
+
+ protected virtual void RegisterEventListeners()
+ {
+
}
public void Apply()
diff --git a/bin/vswhere.exe b/bin/vswhere.exe
index 582e828..2603826 100644
Binary files a/bin/vswhere.exe and b/bin/vswhere.exe differ