LoginSignup
26
22

More than 3 years have passed since last update.

Unityでデスクトップマスコットのためにウィンドウ透過した

Last updated at Posted at 2018-02-26

はじめに

最近、趣味でデスクトップマスコットを作成しています。
その過程で必要なのがウィンドウ透過です。
作る過程で結構詰まったのでメモしておきます。

開発環境

  • Unity 2017.4.15f1
  • Microsoft Visual Studio
  • Windows 10 Home

開発&実行

以下のようなコードを記述しました。

WindowTransparent.cs
using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class WindowTransparent : MonoBehaviour
{
    [DllImport("user32.dll")]
    private static extern int GetForegroundWindow();

    [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
    private static extern Boolean SetLayeredWindowAttributes(int hwnd, uint crKey, byte bAlpha, uint dwFlags);
    [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
    private static extern int GetWindowLong(int hWnd, int nIndex);
    [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
    private static extern int SetWindowLong(int hWnd, int nIndex, int dwNewLong);

    const int LWA_COLORKEY = 0x1; // SetLayeredWindowAttributesで第2引数を使う場合
    const int LWA_ALPHA = 0x2; // SetLayeredWindowAttributesで第3引数を使う場合
    const int GWL_EXSTYLE = -20; // 拡張ウィンドウスタイルを書き換えるためのオフセット
    const int WS_EX_LAYERED = 0x80000;

    const uint TRANSPARENT_COLOR = 0x00000000; // 透過する色

    void Start()
    {

#if UNITY_EDITOR

#else

        int handle = GetForegroundWindow(); // ウィンドウを指定

        int extStyle = GetWindowLong(handle, GWL_EXSTYLE); // ウィンドウの情報を取得
        SetWindowLong(handle, GWL_EXSTYLE, extStyle | WS_EX_LAYERED); // ウィンドウの属性を変更
        SetLayeredWindowAttributes(handle, TRANSPARENT_COLOR, 0, LWA_COLORKEY); // ウィンドウの特定の色を透過

#endif

    }

}

Unity Editorで実行するとめんどくさいことになるので
ビルドしたプログラムでのみ透過するようにしています。
また、透過するウィンドウは実行時の最前面にあるウィンドウになっています。

上記コードで実行する際には
* MainCameraのClearFlagsをSolid Color
* MainCameraのBackgroundを黒(#00000000)
にする必要があります。
unity_desktopchar.png

また, ウィンドウを装飾するためにWindowsAPIを使用しているのでuser32.dllが参照できる状態にしておく必要があります。
Unityアプリケーションでdllファイルを参照する場合はAssetsフォルダ直下にPluginsフォルダを作成してdllファイルを入れておくよいです[参考]。今回はuser32.dllをいれておきます
(上記コードを試してうまくいかない場合はこちらも試してみてください)

最後に

UIのボタンに指定の色が含まれていて少し透過されたりすると
たまにボタンがきかなくなることがあったので調整が必要そうです。
また、デスクトップマスコットにするにはウィンドウのフレームを消したり、
透過したウィンドウを終了する方法を考えたりしないといけないですね。

参考

https://answers.unity.com/questions/869378/viewing-desktop-in-scene.html
http://www.pinvoke.net/default.aspx/user32.setlayeredwindowattributes
http://blog.goo.ne.jp/hiro239415/e/6860f82ef2939e3e14268e96e0479edc

26
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
22