Last active
June 17, 2017 00:09
-
-
Save WhiteNoise/fb24f8eda24ad1a3d838f3bea1e3ea4e to your computer and use it in GitHub Desktop.
Unity Editor script for showing Virtual Desktop when Unity stops playing (for the HTC Vive). It allows you to stay in VR to edit code (without removing the headset).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Reflection; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using UnityEditor; | |
using UnityEngine; | |
using System.Security; | |
/// <summary> | |
/// MyVDPlugin is an editor behavior that re-launches virtual desktop when unity finishes running. | |
/// | |
/// Copyright 2015 - Guy Godin | |
/// http://www.vrdesktop.net/ | |
/// </summary> | |
[InitializeOnLoad] | |
public class MyVDPlugin : MonoBehaviour | |
{ | |
#region Static Fields | |
private static readonly MethodInfo _getMainGameViewMethod = Type.GetType("UnityEditor.GameView,UnityEditor").GetMethod("GetMainGameView", BindingFlags.NonPublic | BindingFlags.Static); | |
private static bool _isPlaying = false; | |
private static bool isChecked = false; | |
// NOTE: Put in your own path to virtual desktop here: | |
// | |
private const string virtualDesktopPath = "D:/SteamLibrary/steamapps/common/Virtual Desktop/Virtual Desktop.exe"; | |
private const string MENU_NAME = "Virtual Desktop/Show After Stop"; | |
#endregion | |
#region Static Constructor | |
static MyVDPlugin() | |
{ | |
MyVDPlugin.isChecked = EditorPrefs.GetBool(MyVDPlugin.MENU_NAME, false); | |
EditorApplication.playmodeStateChanged += OnPlaymodeStateChanged; | |
EditorApplication.update += OnUpdate; | |
isChecked = EditorPrefs.GetBool(MyVDPlugin.MENU_NAME, isChecked); | |
EditorApplication.delayCall += () => { | |
Menu.SetChecked(MyVDPlugin.MENU_NAME, isChecked); | |
}; | |
} | |
#endregion | |
#region Static Properties | |
public static bool IsPlaying | |
{ | |
get { return _isPlaying; } | |
set | |
{ | |
if (value != _isPlaying) | |
{ | |
_isPlaying = value; | |
if (!value && isChecked) | |
{ | |
StartApp(); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Static Methods | |
[MenuItem(MyVDPlugin.MENU_NAME)] | |
private static void ToggleAction() | |
{ | |
isChecked = !isChecked; | |
/// Toggling action | |
Menu.SetChecked(MyVDPlugin.MENU_NAME, isChecked); | |
EditorPrefs.SetBool(MyVDPlugin.MENU_NAME, isChecked); | |
} | |
private static EditorWindow GetMainGameView() | |
{ | |
// Execute the private GetMainGameView method | |
return (EditorWindow)_getMainGameViewMethod.Invoke(null, null); | |
} | |
private static void StartApp() | |
{ | |
var myProcess = new Process(); | |
myProcess.StartInfo.FileName = virtualDesktopPath; | |
myProcess.Start(); | |
} | |
#endregion | |
#region Event Handlers | |
private static void OnPlaymodeStateChanged() | |
{ | |
// Keep internal flag as the event is raised before and after the state changes | |
IsPlaying = EditorApplication.isPlaying; | |
} | |
private static void OnUpdate() | |
{ | |
if (EditorApplication.isPlaying && Input.GetKey(KeyCode.Escape)) | |
{ | |
// Exit Playmode when user hits Escape | |
EditorApplication.isPlaying = false; | |
} | |
} | |
#endregion | |
#region External Methods | |
[DllImport("user32.dll")] | |
[SuppressUnmanagedCodeSecurity] | |
private static extern IntPtr GetActiveWindow(); | |
[DllImport("user32.dll")] | |
[SuppressUnmanagedCodeSecurity] | |
private static extern IntPtr ChildWindowFromPointEx(IntPtr hWndParent, POINT Point, WindowFromPointFlags flags); | |
#endregion | |
#region Structures | |
[StructLayout(LayoutKind.Sequential)] | |
private struct POINT | |
{ | |
public int X; | |
public int Y; | |
public POINT(int x, int y) | |
{ | |
X = x; | |
Y = y; | |
} | |
} | |
#endregion | |
#region Enums | |
[Flags] | |
private enum WindowFromPointFlags | |
{ | |
CWP_ALL = 0x0000, | |
CWP_SKIPINVISIBLE = 0x0001, | |
CWP_SKIPDISABLED = 0x0002, | |
CWP_SKIPTRANSPARENT = 0x0004 | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@WhiteNoise Was hoping this would work for Oculus DK2 but doesn't seem to. After stopping Unity play, the headset remains black and requires a full restart of Virtual Desktop.
Any idea how I might go about adding support for Oculus?
This thread makes me think it's not possible unless Oculus adds support. :\
EDIT: Ah, a clue.
Getting somewhere. I'm able to return to Virtual Desktop, but still requiring I click on it twice (?) from the task bar on the physical desktop before it returns to the headset. Works fine if I position my mouse over the task bar shortcut before starting play, but still be nice if it launched on its own.