Skip to content

Commit

Permalink
Merge pull request #7 from kirurobo/develop
Browse files Browse the repository at this point in the history
まだパッケージ化やその上での動作検証はできていませんが、長いこと更新できていなかったことと、Unity 2019 も使われていそうなためマージします。
  • Loading branch information
kirurobo authored Jun 7, 2020
2 parents 3356542 + ac87d48 commit 1913c0a
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 79 deletions.
158 changes: 113 additions & 45 deletions Scripts/Editor/WindowControllerEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,78 +40,146 @@ public override void OnInspectorGUI()
{
base.OnInspectorGUI();

// 推奨設定のチェック
if (!isWarningDismissed)
{
// 自動調整ボタンを表示させるならtrueとなる
bool showButton = false;

if (!PlayerSettings.runInBackground)
{
EditorGUILayout.HelpBox("'Run in background' is recommended.", MessageType.Warning);
showButton = true;
}

if (!PlayerSettings.resizableWindow)
{
EditorGUILayout.HelpBox("'Resizable window' is recommended.", MessageType.Warning);
showButton = true;
}
EditorGUILayout.Space();

#if UNITY_2018_1_OR_NEWER
if (PlayerSettings.fullScreenMode != FullScreenMode.Windowed)
{
EditorGUILayout.HelpBox("It is recommmended to select 'Windowed' in fullscreen mode.", MessageType.Warning);
showButton = true;
}
bool enableValidation = EditorGUILayout.Foldout(!isWarningDismissed, "Player Settings validation");

if (showButton)
{
GUI.backgroundColor = Color.green;
if (GUILayout.Button("Apply all recommended settings"))
// チェックするかどうかを記憶
if (enableValidation == isWarningDismissed)
{
PlayerSettings.runInBackground = true;
PlayerSettings.resizableWindow = true;
PlayerSettings.fullScreenMode = FullScreenMode.Windowed;
isWarningDismissed = !enableValidation;
}
}
#else
if (PlayerSettings.defaultIsFullScreen)
{
EditorGUILayout.HelpBox("'Default is full screen' is not recommended.", MessageType.Warning);
showButton = true;
}

// 推奨設定のチェック
//if (!isWarningDismissed)
if (enableValidation)
{
// Player Settings をチェックし、非推奨があれば警告メッセージを得る
string[] warnings = ValidatePlayerSettings();

// チェックに引っかかればボタンを表示
if (showButton)
if (warnings.Length > 0)
{

// 枠を作成
//EditorGUILayout.BeginVertical(GUI.skin.box);
//GUILayout.Label("Player Settings validation");

// 警告メッセージを表示
foreach (var message in warnings)
{
EditorGUILayout.HelpBox(message, MessageType.Warning);
}

// 推奨設定をすべて適用するボタン
GUI.backgroundColor = Color.green;
if (
GUILayout.Button(
"✔ Apply all recommended settings",
GUILayout.MinHeight(30f)
GUILayout.MinHeight(20f)
))
{
PlayerSettings.runInBackground = true;
PlayerSettings.resizableWindow = true;
PlayerSettings.defaultIsFullScreen = false;
ApplyRecommendedSettings();
}

// チェックを今後無視するボタン
GUI.backgroundColor = Color.red;
if (
GUILayout.Button(
"✘ Dismiss this validation",
GUILayout.MinHeight(30f)
"✘ Mute this validation",
GUILayout.MinHeight(20f)
))
{
isWarningDismissed = true;
//SaveSettings();
}

EditorGUILayout.Space();
//EditorGUILayout.EndVertical();
}
else
{
GUI.color = Color.green;
GUILayout.Label("OK!");
}
}
}

/// <summary>
/// Player設定を確認し、推奨設定になっていない項目のメッセージ一覧を得る
/// </summary>
/// <returns></returns>
private string[] ValidatePlayerSettings()
{
// 警告メッセージのリスト
List<string> warnings = new List<string>();

if (!PlayerSettings.runInBackground)
{
warnings.Add("'Run in background' is highly recommended.");
}

if (!PlayerSettings.resizableWindow)
{
warnings.Add("'Resizable window' is recommended.");
}

#if UNITY_2018_1_OR_NEWER
// Unity 2018 からはフルスクリーン指定の仕様が変わった
if (PlayerSettings.fullScreenMode != FullScreenMode.Windowed)
{
warnings.Add("Chose 'Windowed' in 'Fullscreen Mode'.");
}
#else
if (PlayerSettings.defaultIsFullScreen)
{
warnings.Add("'Default is full screen' is not recommended.");
}
#endif

// ↓Unity 2019.1.6未満だと useFlipModelSwapchain は無いはず
// なので除外のため書き連ねてあるが、ここまでサポートしなくて良い気もする。
#if UNITY_2019_1_6
#elif UNITY_2019_1_5
#elif UNITY_2019_1_4
#elif UNITY_2019_1_3
#elif UNITY_2019_1_2
#elif UNITY_2019_1_1
#elif UNITY_2019_1_0
#elif UNITY_2019_1_OR_NEWER
// Unity 2019.1.7 以降であれば、Player 設定 の Use DXGI Flip... 無効化を推奨
if (PlayerSettings.useFlipModelSwapchain)
{
warnings.Add("Disable 'Use DXGI Flip Mode Swapchain' to make the window transparent.");
}
#endif

return warnings.ToArray();
}

/// <summary>
/// 推奨設定を一括で適用
/// </summary>
private void ApplyRecommendedSettings()
{
#if UNITY_2018_1_OR_NEWER
PlayerSettings.fullScreenMode = FullScreenMode.Windowed;
#else
PlayerSettings.defaultIsFullScreen = false;
#endif
PlayerSettings.runInBackground = true;
PlayerSettings.resizableWindow = true;

#if UNITY_2019_1_6
#elif UNITY_2019_1_5
#elif UNITY_2019_1_4
#elif UNITY_2019_1_3
#elif UNITY_2019_1_2
#elif UNITY_2019_1_1
#elif UNITY_2019_1_0
#elif UNITY_2019_1_OR_NEWER
PlayerSettings.useFlipModelSwapchain = false;
#endif

}

// 参考 http://baba-s.hatenablog.com/entry/2017/09/17/135018
Expand Down
112 changes: 94 additions & 18 deletions Scripts/UniWinApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ public override string ToString()
}
}

/// <summary>
/// 透明化の方式
/// </summary>
public enum TransparentType
{
None = 0,
DWM = 1,
LayereredWindows = 2,
}


/// <summary>
/// このウィンドウのハンドル
Expand Down Expand Up @@ -142,6 +152,17 @@ public override string ToString()
/// </summary>
public Vector2 OriginalWindowSize;

/// <summary>
/// ウィンドウ透過方式
/// </summary>
public TransparentType TransparentMethod = TransparentType.DWM;
private TransparentType currentTransparentType = TransparentType.DWM;

/// <summary>
/// Layered Windows で透過する色
/// </summary>
public Color32 ChromakeyColor = new Color32(1, 0, 1, 0);

/// <summary>
/// 元のウィンドウスタイル
/// </summary>
Expand Down Expand Up @@ -518,26 +539,41 @@ public void EnableTransparent(bool enable)
// 枠無しウィンドウにする
EnableBorderless(true);

EnableTransparentByDWM();

// ウィンドウ再描画
WinApi.ShowWindow(hWnd, WinApi.SW_SHOW);
SetSize(GetSize());
switch (TransparentMethod)
{
case TransparentType.DWM:
EnableTransparentByDWM();
break;
case TransparentType.LayereredWindows:
EnableTransparentBySetLayered();
break;
}
}
else
{
DisableTransparentByDWM();
// 現在の指定ではなく、透過にした時点の指定に基づいて無効化
switch (currentTransparentType)
{
case TransparentType.DWM:
DisableTransparentByDWM();
break;
case TransparentType.LayereredWindows:
DisableTransparentBySetLayered();
break;
}

// ウィンドウスタイルを戻す
// 枠ありウィンドウにする
EnableBorderless(false);

// 操作の透過をやめる
EnableClickThrough(false);

// サイズ変更イベントを発生させる
SetSize(GetSize());
}

currentTransparentType = TransparentMethod;

// サイズ変更イベントを発生させる
SetSize(GetSize());

// ウィンドウ再描画
WinApi.ShowWindow(hWnd, WinApi.SW_SHOW);
}
Expand All @@ -556,6 +592,43 @@ private void DisableTransparentByDWM()
DwmApi.DwmExtendFrameIntoClientArea(hWnd, margins);
}

/// <summary>
/// SetLayeredWindowsAttributes によって指定色を透過させる
/// </summary>
private void EnableTransparentBySetLayered()
{
#if UNITY_EDITOR
// エディタの場合、設定すると描画が更新されなくなってしまう
#else
Color32 color32 = ChromakeyColor;
WinApi.COLORREF cref = new WinApi.COLORREF(color32.r, color32.g, color32.b);
WinApi.SetLayeredWindowAttributes(hWnd, cref, 0xFF, WinApi.LWA_COLORKEY);

long exstyle = this.CurrentWindowExStyle;
exstyle |= WinApi.WS_EX_LAYERED;
this.CurrentWindowExStyle = exstyle;
WinApi.SetWindowLong(hWnd, WinApi.GWL_EXSTYLE, this.CurrentWindowExStyle);
#endif
}

/// <summary>
/// SetLayeredWindowsAttributes によって指定色を透過させる
/// </summary>
private void DisableTransparentBySetLayered()
{
#if UNITY_EDITOR
// エディタの場合、設定すると描画が更新されなくなってしまう
#else
WinApi.COLORREF cref = new WinApi.COLORREF(0, 0, 0);
WinApi.SetLayeredWindowAttributes(hWnd, cref, 0xFF, 0x00);

long exstyle = this.CurrentWindowExStyle;
exstyle &= ~WinApi.WS_EX_LAYERED;
this.CurrentWindowExStyle = exstyle;
WinApi.SetWindowLong(hWnd, WinApi.GWL_EXSTYLE, this.CurrentWindowExStyle);
#endif
}

/// <summary>
/// ウィンドウの枠を消去/戻す
/// </summary>
Expand Down Expand Up @@ -592,6 +665,9 @@ public void EnableClickThrough(bool isClickThrough)
{
if (!IsActive) return;

// Layered Window での透過時は、操作透過はOSで行われる
if (currentTransparentType == TransparentType.LayereredWindows) return;

#if UNITY_EDITOR
// エディタの場合は操作の透過はやめておく
//if (isClickThrough)
Expand Down Expand Up @@ -674,7 +750,7 @@ public static string GetUnityProcessName()
return file;
}

#region マウス操作関連
#region マウス操作関連
/// <summary>
/// マウスカーソルを指定座標へ移動させる
/// </summary>
Expand Down Expand Up @@ -753,19 +829,19 @@ static public void SendMouseDown(int button)
0, 0, 0, IntPtr.Zero
);
}
#endregion
#endregion

#region キー操作関連
#region キー操作関連
/// <summary>
/// キーコードを送ります
/// </summary>
public void SendKey(KeyCode code)
{
WinApi.PostMessage(this.hWnd, WinApi.WM_IME_CHAR, (long)code, IntPtr.Zero);
}
#endregion
#endregion

#region ファイルドロップ関連
#region ファイルドロップ関連
/// <summary>
/// ファイルドロップ時に発生するイベント
/// </summary>
Expand Down Expand Up @@ -950,9 +1026,9 @@ public void Reset()
RestoreWindowState();
}

#endregion
#endregion

#region File open dialog
#region File open dialog

public string ShowOpenFileDialog(string filter = "All files|*.*")
{
Expand Down Expand Up @@ -980,7 +1056,7 @@ public string ShowOpenFileDialog(string filter = "All files|*.*")
}
return null;
}
#endregion
#endregion
}

}
Loading

0 comments on commit 1913c0a

Please sign in to comment.