데스크톱 애완동물의 투명한 효과와 프로그램에 직접 들어가기

11850 단어 Unity

데스크탑 애완동물의 투명성을 위한 Unity


주의: 윈도우즈 플랫폼에만 적용
직접 코드를 붙여라, 사실 이 코드들도 내가 쓴 것이 아니다.인터넷을 사용했습니다.선배들 구덩이 밟아줘서 고마워요.
실현된 사고방식은 이렇다. 카메라를 순수한 색으로 만들어 파헤친다.어떻게 된 건지 나도 잘 모르겠어.만약 아는 것이 있다면 나에게 좀 가르쳐 주기를 바란다.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System;
using UnityEngine;
using System.Diagnostics;

public class WindowManager : MonoBehaviour
{
    private static WindowManager instance;

    public static WindowManager Instance
    {
        get
        {
            return instance;
        }
    }
    // Use this for initialization
    [SerializeField]
    private Material m_Material;
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }
    // Define function signatures to import from Windows APIs
    [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);

    public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetParent(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);


    [DllImport("kernel32.dll")]  
    public static extern void SetLastError(uint dwErrCode);


    // Definitions of window styles
    const int GWL_STYLE = -16;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;
    public const int width = 300;
    public const int height = 300;
    void Start()
    {
        SetWindowScreen(width, height);
        var margins = new MARGINS() { cxLeftWidth = -1 };
        var hwnd = GetProcessWnd();
        SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
        DwmExtendFrameIntoClientArea(hwnd, ref margins);

    }

    void SetWindowScreen(int width, int height)
    {
        Screen.SetResolution(width, height, false);
    }

    void OnRenderImage(RenderTexture from, RenderTexture to)
    {
        Graphics.Blit(from, to, m_Material);
    }

    public static IntPtr GetProcessWnd()
    {
        IntPtr ptrWnd = IntPtr.Zero;
        uint pid = (uint)Process.GetCurrentProcess().Id;  //      ID  

        bool bResult = EnumWindows(new WNDENUMPROC(delegate (IntPtr hwnd, uint lParam)
       {
           uint id = 0;

           if (GetParent(hwnd) == IntPtr.Zero)
           {
               GetWindowThreadProcessId(hwnd, ref id);
               if (id == lParam)    //               
               {
                   ptrWnd = hwnd;   //          
                   SetLastError(0);    //        
                   return false;   //    false          
               }
           }

           return true;

       }), pid);
        return (!bResult && Marshal.GetLastWin32Error() == 0) ? ptrWnd : IntPtr.Zero;
    }

}

나는 단지 다른 사람의 코드를 수정하고 다른 것을 설정했을 뿐이다.
이 스크립트를 카메라에 걸어두지만, 재질 공이 필요합니다. shader를 사용하여 배경색을 제거해야 합니다.
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
        }
    }
}

재료 구의 색상은 카메라의 배경색과 동일하게 설정해야 합니다.(구체적으로 무엇 때문인지 나도 잘 모르겠다)
실행 가능한 프로그램으로 포장한 후 더블 클릭 프로그램은 선택 해상도 인터페이스에 들어갑니다.하지만 이러고 싶지 않아요. 두 번 클릭하면 바로 애완동물 인터페이스에 들어가고 싶어요.
PlayerSetting->Resolution에서 Display Resolution Dialog를 Disabled로 설정하면 됩니다.

좋은 웹페이지 즐겨찾기