Skip to content

Instantly share code, notes, and snippets.

@WhiteNoise
Last active June 17, 2017 00:09
Show Gist options
  • Save WhiteNoise/fb24f8eda24ad1a3d838f3bea1e3ea4e to your computer and use it in GitHub Desktop.
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).
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
}
@simpleshadow
Copy link

simpleshadow commented Jun 16, 2017

@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.

// NOTE: Put in your own path to virtual desktop here:

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment