first commit
This commit is contained in:
149
Assets/02_Scripts/Editor/DesktopOverlaySetup.cs
Normal file
149
Assets/02_Scripts/Editor/DesktopOverlaySetup.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
/// <summary>
|
||||
/// 투명 데스크톱 오버레이 검증에 필요한 프로젝트 설정을 일괄 적용한다.
|
||||
/// 일부 항목은 인스펙터에 노출되지 않아 스크립트로 설정한다.
|
||||
/// </summary>
|
||||
public static class DesktopOverlaySetup
|
||||
{
|
||||
const BuildTarget Target = BuildTarget.StandaloneWindows64;
|
||||
|
||||
[MenuItem("Tools/Desktop Overlay/1. Apply Transparent Window Settings")]
|
||||
public static void Apply()
|
||||
{
|
||||
// useFlipModelSwapchain 은 D3D11 전용이므로 API 를 고정한다.
|
||||
PlayerSettings.SetUseDefaultGraphicsAPIs(Target, false);
|
||||
PlayerSettings.SetGraphicsAPIs(Target, new[] { GraphicsDeviceType.Direct3D11 });
|
||||
|
||||
PlayerSettings.useFlipModelSwapchain = false; // DWM 투명도의 전제 조건
|
||||
|
||||
PlayerSettings.fullScreenMode = FullScreenMode.Windowed;
|
||||
PlayerSettings.runInBackground = true;
|
||||
PlayerSettings.visibleInBackground = true;
|
||||
PlayerSettings.resizableWindow = false;
|
||||
PlayerSettings.forceSingleInstance = true;
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("[DesktopOverlaySetup] Player Settings 적용 완료.");
|
||||
LogCurrent();
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Desktop Overlay/2. Log Current Settings")]
|
||||
public static void LogCurrent()
|
||||
{
|
||||
var apis = PlayerSettings.GetGraphicsAPIs(Target);
|
||||
var apiList = string.Join(", ", System.Array.ConvertAll(apis, a => a.ToString()));
|
||||
|
||||
Debug.Log(
|
||||
"[DesktopOverlaySetup] 현재 값 (괄호 안이 기대값)\n" +
|
||||
$" Graphics APIs = [{apiList}] (Direct3D11)\n" +
|
||||
$" Auto Graphics API = {PlayerSettings.GetUseDefaultGraphicsAPIs(Target)} (False)\n" +
|
||||
$" useFlipModelSwapchain = {PlayerSettings.useFlipModelSwapchain} (False)\n" +
|
||||
$" fullScreenMode = {PlayerSettings.fullScreenMode} (Windowed)\n" +
|
||||
$" runInBackground = {PlayerSettings.runInBackground} (True)\n" +
|
||||
$" visibleInBackground = {PlayerSettings.visibleInBackground} (True)"
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HDR 32비트 컬러 버퍼(R11G11B10_UFloat)에는 알파 채널이 없어서
|
||||
/// 카메라를 알파 0으로 클리어해도 저장되지 않는다. HDR 을 끄고
|
||||
/// URP 의 Alpha Processing 을 켠다.
|
||||
/// </summary>
|
||||
[MenuItem("Tools/Desktop Overlay/3. Fix URP Alpha Settings")]
|
||||
public static void FixUrpAlpha()
|
||||
{
|
||||
var guids = AssetDatabase.FindAssets("t:UniversalRenderPipelineAsset");
|
||||
if (guids.Length == 0)
|
||||
{
|
||||
Debug.LogError("[DesktopOverlaySetup] URP Asset 을 찾지 못했습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
var asset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
|
||||
if (asset == null) continue;
|
||||
|
||||
var so = new SerializedObject(asset);
|
||||
bool changed = false;
|
||||
|
||||
changed |= SetValue(so, "m_SupportsHDR", 0); // 알파 있는 R8G8B8A8 로
|
||||
changed |= SetValue(so, "m_AllowPostProcessAlphaOutput", 1); // Alpha Processing 켜기
|
||||
changed |= SetValue(so, "m_HDRColorBufferPrecision", 1); // HDR 쓸 경우 대비: 64bit(알파 있음)
|
||||
|
||||
if (changed)
|
||||
{
|
||||
so.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(asset);
|
||||
Debug.Log($"[DesktopOverlaySetup] 수정됨: {path}");
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("[DesktopOverlaySetup] URP 알파 설정 완료. 다시 빌드하세요.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 런타임 CreatePrimitive 는 빌드에서 Built-in 기본 머티리얼을 잡아 분홍색이 된다.
|
||||
/// 에디터에서 URP 머티리얼을 가진 큐브를 씬에 넣어 빌드 포함을 보장한다.
|
||||
/// </summary>
|
||||
[MenuItem("Tools/Desktop Overlay/4. Add Test Cube To Scene")]
|
||||
public static void AddTestCube()
|
||||
{
|
||||
var existing = GameObject.Find("AlphaTestCube");
|
||||
if (existing != null) Object.DestroyImmediate(existing);
|
||||
|
||||
var shader = Shader.Find("Universal Render Pipeline/Lit")
|
||||
?? Shader.Find("Universal Render Pipeline/Unlit");
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogError("[DesktopOverlaySetup] URP 셰이더를 찾지 못했습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
cube.name = "AlphaTestCube";
|
||||
|
||||
var cam = Camera.main;
|
||||
cube.transform.position = cam != null
|
||||
? cam.transform.position + cam.transform.forward * 5f
|
||||
: new Vector3(0f, 1f, 0f);
|
||||
|
||||
const string matPath = "Assets/99_Settings/AlphaTestCubeMat.mat";
|
||||
var mat = new Material(shader) { color = new Color(0.2f, 0.8f, 1f) };
|
||||
AssetDatabase.CreateAsset(mat, matPath);
|
||||
cube.GetComponent<Renderer>().sharedMaterial =
|
||||
AssetDatabase.LoadAssetAtPath<Material>(matPath);
|
||||
|
||||
EditorSceneManager.MarkSceneDirty(cube.scene);
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log("[DesktopOverlaySetup] AlphaTestCube 추가됨. 씬을 저장(Ctrl+S)하세요.");
|
||||
}
|
||||
|
||||
static bool SetValue(SerializedObject so, string propName, int value)
|
||||
{
|
||||
var p = so.FindProperty(propName);
|
||||
if (p == null)
|
||||
{
|
||||
Debug.LogWarning($"[DesktopOverlaySetup] 프로퍼티 없음: {propName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p.propertyType == SerializedPropertyType.Boolean)
|
||||
{
|
||||
if (p.boolValue == (value != 0)) return false;
|
||||
p.boolValue = value != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.intValue == value) return false;
|
||||
p.intValue = value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/Editor/DesktopOverlaySetup.cs.meta
Normal file
2
Assets/02_Scripts/Editor/DesktopOverlaySetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 955d1f72698f38145b86f717b5deb478
|
||||
Reference in New Issue
Block a user