Spelunx Cavern SDK
 
Loading...
Searching...
No Matches
FullscreenGameView.cs
Go to the documentation of this file.
1#if UNITY_EDITOR
2using System;
3using System.Linq;
4using System.Reflection;
5using UnityEditor;
6using UnityEngine;
7
8namespace Spelunx.Fullscreen
9{
10 // Forked from https://github.com/JorGra/JG-UnityEditor-GameViewFullscreen
11 /// <summary>
12 /// When enabled or activated, tries to run the game view full screen by rendering the game view to a new window that is the size of the monitor, and hiding the toolbar.
13 /// Does not use the same API as a native fullscreen build, so performance will not be the same as "exclusive" fullscreen
14 /// </summary>
15 public static class FullscreenGameView
16 {
17 static readonly Type GameViewType = Type.GetType("UnityEditor.GameView,UnityEditor");
18 private static readonly Type HostViewType = Type.GetType("UnityEditor.HostView,UnityEditor");
19 private static readonly Type ContainerWindowType = Type.GetType("UnityEditor.ContainerWindow,UnityEditor");
20 private static readonly PropertyInfo ShowToolbarProperty = GameViewType.GetProperty("showToolbar", BindingFlags.Instance | BindingFlags.NonPublic);
21 // hack to prevent double-rendering while in fullscreen
22 private readonly static int DISPLAY_0 = 0; // target gameview display
23 private readonly static int DISPLAY_7 = 7; // display gameview doesn't render to
24 static EditorWindow instance;
25
26
27 private static PropertyInfo FindProperty(Type type, string propertyName)
28 {
29 return type?.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
30 }
31
32 private static MethodInfo FindMethod(Type type, string methodName, params Type[] args)
33 {
34 return args.Length == 0
35 ? type?.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
36 : type?.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, args, null);
37 }
38 private static EditorWindow GetMainGameView()
39 {
40 Type gameViewType = typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView");
41 if (gameViewType == null)
42 {
43 Debug.LogError("Unable to find the UnityEditor.GameView type.");
44 return null;
45 }
46 return EditorWindow.GetWindow(gameViewType);
47 }
48
49 private static void SetGameViewTargetDisplay(int displayIndex)
50 {
51 EditorWindow gameView = GetMainGameView();
52 if (gameView == null)
53 return;
54
55 FindMethod(gameView.GetType(), "SetTargetDisplay", typeof(int))?.Invoke(gameView, new object[] { displayIndex });
56 }
57
58 public static void EnterFullscreen()
59 {
60 if (GameViewType == null)
61 {
62 Debug.LogError("GameView type not found.");
63 return;
64 }
65
66 if (ShowToolbarProperty == null)
67 {
68 Debug.LogWarning("GameView.showToolbar property not found.");
69 }
70
71 if (instance != null)
72 {
73 instance.Close();
74 instance = null;
75 SetGameViewTargetDisplay(DISPLAY_0);
76 }
77 else
78 {
79 SetGameViewTargetDisplay(DISPLAY_7);
80 instance = (EditorWindow)ScriptableObject.CreateInstance(GameViewType);
81 var containerWindow = ScriptableObject.CreateInstance(ContainerWindowType);
82 var hostView = ScriptableObject.CreateInstance(HostViewType);
83
84 ShowToolbarProperty?.SetValue(instance, false);
85
86 Vector2 position = Vector2.zero;
87 Vector2 resolution = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height) / EditorGUIUtility.pixelsPerPoint;
88
89 FindProperty(HostViewType, "actualView")?.SetValue(hostView, instance);
90
91 var fullscreenRect = new Rect(position, resolution);
92 FindProperty(ContainerWindowType, "position")?.SetValue(containerWindow, fullscreenRect);
93 FindProperty(ContainerWindowType, "rootView")?.SetValue(containerWindow, hostView);
94
95 var showMethod = ContainerWindowType?.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
96 .FirstOrDefault(m => m.Name == "Show" && m.GetParameters().Length is 3 or 4 or 5);
97
98 showMethod?.Invoke(containerWindow, new object[] { 3, false, true, true, 0 }.Take(showMethod.GetParameters().Length).ToArray());
99
100 FindProperty(ContainerWindowType, "m_ShowMode")?.SetValue(containerWindow, 1);
101 FindProperty(ContainerWindowType, "m_DontSaveToLayout")?.SetValue(containerWindow, true);
102
103 FindMethod(ContainerWindowType, "SetMinMaxSizes", typeof(Vector2), typeof(Vector2))?.Invoke(containerWindow, new object[] { fullscreenRect.size, fullscreenRect.size });
104 }
105 }
106
107 public static void ExitFullscreen()
108 {
109 if (instance != null)
110 {
111 // To prevent error with closing hostview while game is running, wait for the next editor frame to actually close the instance
112 EditorApplication.delayCall += CloseFullscreenAfterDelay;
113 }
114 }
115
116
117 public static void SetFullscreen(bool fullscreen)
118 {
119 if (instance == null && fullscreen)
120 {
121 EnterFullscreen();
122 }
123 else if (instance != null && !fullscreen)
124 {
125 ExitFullscreen();
126 }
127 }
128
129 private static void CloseFullscreenAfterDelay()
130 {
131 instance.Close();
132 SetGameViewTargetDisplay(DISPLAY_0);
133 EditorApplication.delayCall -= CloseFullscreenAfterDelay;
134 }
135
136 }
137}
138#endif