unity 制作透明背景客户端程序

获取指定窗口,修改窗口类型,把边框去掉,


using System;

using System.Runtime.InteropServices;

using UnityEngine;

public class WindowCtrl : MonoBehaviour
{
    [SerializeField]

    private Material m_Material;

    [SerializeField]

    private string strProduct;//要控制的窗口名字,需要和Build->BuildSetting->PlayerSetting->ProductName 一致,


    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }
    private enum WindowSizeType
    {
        Null,
        Normal,
        MinSize,
        MaxSize
    }


    //private WindowSizeType windowSize = WindowSizeType.Normal;


    // Define function signatures to import from Windows APIs
    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);


    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();


    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);


    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);


    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);//设置此窗体为活动窗体


    [DllImport("user32.dll")]
    public static extern bool ReleaseCapture();
    [DllImport("user32.dll")]
    public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);


    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);




    // Definitions of window styles
    const int GWL_STYLE = -16;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;
    const uint WS_BORDER =  0x00800000; 
    const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
    const int SW_SHOWMAXIMIZED = 3; //{最大化, 激活} 


    /// <summary>
    /// 当前窗口句柄
    /// </summary>
    private IntPtr currWnd;


    /// <summary>
    /// 上次点击的时刻
    /// </summary>
    private float lastTime;


    /// <summary>
    /// 点击次数
    /// </summary>
    private float clickCount;


    /// <summary>
    /// 鼠标按下时间
    /// </summary>
    private float pressTime;


    /// <summary>
    /// 鼠标是否在此界面
    /// </summary>
    private bool isFocus;


    /// <summary>
    /// 屏幕的宽和高
    /// </summary>
    private float ScreenHeight;
    //private float ScreenWidth;


    void Start()
    {
        ScreenHeight = Screen.height;
        //ScreenWidth = Screen.width;


        //#if UNITY_EDITOR
        var margins = new MARGINS() { cxLeftWidth = -1 };


        ////// Get a handle to the window
        //////IntPtr currWnd = GetActiveWindow();
        currWnd = FindWindow(null, strProduct);


        ////// Set properties of the window
        ////// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx
        SetWindowLong(currWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);


        ////// Extend the window into the client area
        //////See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa969512%28v=vs.85%29.aspx 
        DwmExtendFrameIntoClientArea(currWnd, ref margins);
        //#endif
    }


    // Pass the output of the camera to the custom material
    // for chroma replacement
    //void OnRenderImage(RenderTexture from,RenderTexture to)
    //{
    //    //Graphics.Blit(from, to, m_Material);
    //}


    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (ScreenHeight - Input.mousePosition.y > 30)//30 表示距离屏幕顶部多少的区域是可以拖动的区域
            {
                return;
            }


            pressTime = 0f;
            isFocus = true;


            {
                float currTime = Time.realtimeSinceStartup;


                if (currTime - lastTime < 0.3)
                {
                    clickCount++;
                    if (clickCount == 1)
                    {
                        ShowWindow(currWnd, SW_SHOWMAXIMIZED);
                    }
                }
                else
                {
                    clickCount = 0;
                }
                lastTime = currTime;
            }
        }


        if (isFocus && pressTime >= 0.3f)
        { //这样做为了区分界面上面其它需要滑动的操作
            ReleaseCapture();
            SendMessage(currWnd, 0xA1, 0x02, 0);
            SendMessage(currWnd, 0x0202, 0, 0);
        }


        if (isFocus)
            pressTime += Time.deltaTime;


        if (Input.GetMouseButtonUp(0))
        {
            pressTime = 0f;
            isFocus = false;
        }
    }




    private void SetWindowSize(WindowSizeType type)
    {
        int temp = 0;
        switch (type)
        {
            case WindowSizeType.Normal:///双击全屏
                {
                    temp = 3;
                    //windowSize = WindowSizeType.MaxSize;
                }
                break;
            case WindowSizeType.MinSize:///最小尺寸
                {
                    temp = 2;
                    //windowSize = WindowSizeType.MinSize;
                }
                break;
            case WindowSizeType.MaxSize:///双击恢复
                {
                    //windowSize = WindowSizeType.Normal;
                    temp = 1;
                }
                break;
            default:
                break;
        }
        ShowWindow(currWnd, temp);
    }

}

创建C#脚本,复制上边代码,把脚本挂在摄像机上,把摄像机设置为 Solid Color模式,颜色设置为黑色 透明;

可能还要添加灯光,把模型显得明亮点,防止渲染出错

还有一个shader文档 ,下边贴上:

Shader "Custom/ChromakeyTransparent" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_TransparentColourKey("Transparent Colour Key", Color) = (0,0,0,1)
_TransparencyTolerance("Transparency Tolerance", Float) = 0.01

}

SubShader{
Pass{
Tags{ "RenderType" = "Opaque" }
LOD 200

CGPROGRAM

#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"


struct a2v
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};


struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};


v2f vert(a2v input)
{
v2f output;
output.pos = UnityObjectToClipPos(input.pos);
output.uv = input.uv;
return output;
};


sampler2D _MainTex;
float3 _TransparentColourKey;
float _TransparencyTolerance;

float4 frag(v2f input) : SV_Target
{
// What is the colour that *would* be rendered here?
float4 colour = tex2D(_MainTex, input.uv);


// Calculate the different in each component from the chosen transparency colour
float deltaR = abs(colour.r - _TransparentColourKey.r);
float deltaG = abs(colour.g - _TransparentColourKey.g);
float deltaB = abs(colour.b - _TransparentColourKey.b);


// If colour is within tolerance, write a transparent pixel
if (deltaR< _TransparencyTolerance && deltaG < _TransparencyTolerance && deltaB < _TransparencyTolerance)
{
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}


// Otherwise, return the regular colour
return colour;
}
ENDCG
}
}
}

新建shader,复制上边代码,新建材质球,选用创建的shader,把新建的材质拖拽到挂在摄像机上的脚本上,打包客户端即可。

记录一下。



猜你喜欢

转载自blog.csdn.net/Keep_Rise/article/details/81032586
今日推荐