first commit

This commit is contained in:
2026-08-25 00:55:37 +09:00
commit 8d1881749c
72 changed files with 3250 additions and 0 deletions

49
.gitattributes vendored Normal file
View File

@@ -0,0 +1,49 @@
## Unity ##
*.cs diff=csharp text
*.cginc text
*.shader text
*.mat merge=unityyamlmerge eol=lf
*.physicsMaterial2D merge=unityyamlmerge eol=lf
*.physicMaterial merge=unityyamlmerge eol=lf
*.meta merge=unityyamlmerge eol=lf
*.controller merge=unityyamlmerge eol=lf
## git-lfs ##
*.anim filter=lfs diff=lfs merge=lfs -text
*.asset filter=lfs diff=lfs merge=lfs -text
*.prefab filter=lfs diff=lfs merge=lfs -text
*.unity filter=lfs diff=lfs merge=lfs -text
#Image
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
#Audio
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
#Video
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
#3D Object
*.FBX filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
#ETC
*.a filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.unitypackage filter=lfs diff=lfs merge=lfs -text
*.aif filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text
*.bytes filter=lfs diff=lfs merge=lfs -text
*.hdr filter=lfs diff=lfs merge=lfs -text
*.cubemap filter=lfs diff=lfs merge=lfs -text

94
.gitignore vendored Normal file
View File

@@ -0,0 +1,94 @@
# ---> Unity
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Recordings can get excessive in size
/[Rr]ecordings/
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
# IDE settings (자동 생성 — 사용자별 설정)
.vscode/
.idea/
# OS generated files
.DS_Store
Thumbs.db
desktop.ini
# Crash dumps
*.dmp
mono_crash*
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.slnx
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.unitypackage.meta
*.app
# Crashlytics generated file
crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*
Assets/XR/AndroidXR/AndroidXRSettingsInitializer*
ProjectSettings/Packages/com.unity.learn.iet-framework/Settings.json
ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
*.log

8
Assets/01_Scenes.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0bbe59e1b1f0faa42bd1612283c9ccb2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/01_Scenes/MainScene.unity LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 99c9720ab356a0642a771bea13969a05
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/02_Scripts.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4fb015c28b636ab4ba6788a0a01caa2c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 15429132f9c27c644aa551641388b8b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
using UnityEngine;
public class Util : MonoBehaviour
{
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 40dfdf8b856822a43ae5f1301397d774

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a436952b5e1b3b4c8f81fe7e31f7a68
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,215 @@
using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// 창 전체를 기본적으로 클릭 통과 상태로 두고, OS 커서가 캐릭터 콜라이더 위에
/// 있을 때만 통과를 해제해 클릭을 받는다.
///
/// Unity 의 Input 은 창 밖 좌표를 모르므로 GetCursorPos 로 OS 커서를 직접 읽어
/// 창 기준 좌표로 변환한 뒤 레이캐스트한다.
///
/// 최상위 창의 클릭 통과에는 WS_EX_TRANSPARENT 만으로는 부족하고 WS_EX_LAYERED 가
/// 반드시 함께 필요하다(실측 확인). LAYERED 는 DwmExtendFrameIntoClientArea 기반
/// 투명도와 공존하며, SetLayeredWindowAttributes 호출은 필요하지 않았다.
///
/// LAYERED 는 init 시 한 번만 걸고, 매 프레임 토글하는 것은 TRANSPARENT 뿐이다.
/// </summary>
[RequireComponent(typeof(TransparentWindow))]
public class ClickThroughHitTest : MonoBehaviour
{
// 아래 필드들은 Windows 빌드에서만 쓰이므로 에디터 컴파일 시 CS0414 가 뜬다
#pragma warning disable 0414
[Header("히트테스트")]
[Tooltip("비우면 같은 오브젝트의 Camera 를 사용")]
[SerializeField] Camera hitTestCamera;
[SerializeField] LayerMask interactableLayers = ~0;
[SerializeField] float maxRayDistance = 500f;
// WS_EX_NOACTIVATE: 클릭해도 창이 포커스를 가져가지 않는다.
// 포커스 없이 Unity 가 클릭을 받을 수 있을지 우려했으나, 실측 결과 클릭은
// 정상 수신된다. 사용자가 쓰던 앱의 포커스를 뺏지 않는 쪽이 데스크톱 비서로서
// 명백히 낫기 때문에 항상 켠다.
//
// SerializeField 가 아닌 이유: 씬에 예전 false 값이 직렬화돼 있어
// 인스펙터 값이 코드 기본값을 이겨버린다. 런타임 토글은 Ctrl+Alt+N 으로 유지.
bool useNoActivate = true;
[Header("검증용")]
[SerializeField] bool showDebugHud = true;
[Tooltip("커서가 캐릭터 위에 있으면 살짝 커지게 해서 히트테스트를 눈으로 확인")]
[SerializeField] bool visualizeHover = true;
[SerializeField] float hoverScale = 1.15f;
#pragma warning restore 0414
TransparentWindow window;
Transform hovered;
Vector3 hoveredBaseScale;
GUIStyle hudStyle;
/// <summary>현재 OS 커서가 캐릭터 위에 있는지.</summary>
public bool IsOverCharacter { get; private set; }
int clickCount;
uint currentExStyle;
string lastAction = "-";
void Awake()
{
window = GetComponent<TransparentWindow>();
if (hitTestCamera == null) hitTestCamera = GetComponent<Camera>();
if (hitTestCamera == null) hitTestCamera = Camera.main;
}
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
// true = 클릭이 뒤 창으로 통과하는 상태
bool clickThrough = true;
bool styleInitialized;
bool prevN;
void Update()
{
if (!window.IsReady || window.Hwnd == System.IntPtr.Zero) return;
if (!styleInitialized)
{
ApplyBaseStyle();
styleInitialized = true;
}
PollNoActivateToggle();
IsOverCharacter = HitTest(out var hit);
SetClickThrough(!IsOverCharacter);
UpdateHoverVisual(IsOverCharacter ? hit.transform : null);
var mouse = Mouse.current;
if (IsOverCharacter && mouse != null && mouse.leftButton.wasPressedThisFrame)
{
clickCount++;
lastAction = $"클릭: {hit.transform.name}";
Debug.Log($"[ClickThroughHitTest] 캐릭터 클릭됨: {hit.transform.name}");
}
currentExStyle = Win32.GetWindowLongW(window.Hwnd, Win32.GWL_EXSTYLE);
}
/// <summary>Ctrl+Alt+N 으로 NOACTIVATE 를 켜고 끈다. 재빌드 없이 클릭 수신 여부를 비교하기 위함.</summary>
void PollNoActivateToggle()
{
if (!Win32.IsKeyDown(Win32.VK_CONTROL) || !Win32.IsKeyDown(Win32.VK_MENU))
{
prevN = false;
return;
}
bool now = Win32.IsKeyDown(Win32.VK_N);
if (now && !prevN)
{
useNoActivate = !useNoActivate;
ApplyBaseStyle();
lastAction = $"NOACTIVATE = {useNoActivate}";
Debug.Log($"[ClickThroughHitTest] NOACTIVATE = {useNoActivate}");
}
prevN = now;
}
void ApplyBaseStyle()
{
uint ex = Win32.GetWindowLongW(window.Hwnd, Win32.GWL_EXSTYLE);
ex |= Win32.WS_EX_LAYERED; // 클릭 통과의 전제. 한 번만 걸고 유지한다.
if (useNoActivate) ex |= Win32.WS_EX_NOACTIVATE;
else ex &= ~Win32.WS_EX_NOACTIVATE;
if (clickThrough) ex |= Win32.WS_EX_TRANSPARENT;
else ex &= ~Win32.WS_EX_TRANSPARENT;
Win32.SetWindowLongW(window.Hwnd, Win32.GWL_EXSTYLE, ex);
Win32.SetWindowPos(window.Hwnd, Win32.HWND_TOPMOST, 0, 0, 0, 0,
Win32.SWP_NOMOVE | Win32.SWP_NOSIZE | Win32.SWP_NOACTIVATE | Win32.SWP_FRAMECHANGED);
}
bool HitTest(out RaycastHit hit)
{
hit = default;
if (hitTestCamera == null) return false;
if (!Win32.GetCursorPos(out var pt)) return false;
if (!Win32.GetWindowRect(window.Hwnd, out var rc)) return false;
int w = rc.Width, h = rc.Height;
if (w <= 0 || h <= 0) return false;
// 창 기준 좌표 (좌상단 원점, Y 아래로)
int localX = pt.x - rc.left;
int localY = pt.y - rc.top;
if (localX < 0 || localY < 0 || localX >= w || localY >= h) return false;
// Unity 화면 좌표 (좌하단 원점, Y 위로)
float ux = localX * (Screen.width / (float)w);
float uy = (h - localY) * (Screen.height / (float)h);
var ray = hitTestCamera.ScreenPointToRay(new Vector3(ux, uy, 0f));
return Physics.Raycast(ray, out hit, maxRayDistance, interactableLayers);
}
void SetClickThrough(bool enable)
{
if (enable == clickThrough) return;
clickThrough = enable;
uint ex = Win32.GetWindowLongW(window.Hwnd, Win32.GWL_EXSTYLE);
if (enable) ex |= Win32.WS_EX_TRANSPARENT;
else ex &= ~Win32.WS_EX_TRANSPARENT;
Win32.SetWindowLongW(window.Hwnd, Win32.GWL_EXSTYLE, ex);
}
#endif
void UpdateHoverVisual(Transform target)
{
if (!visualizeHover) return;
if (hovered == target) return;
if (hovered != null) hovered.localScale = hoveredBaseScale;
hovered = target;
if (hovered != null)
{
hoveredBaseScale = hovered.localScale;
hovered.localScale = hoveredBaseScale * hoverScale;
}
}
void OnGUI()
{
if (!showDebugHud) return;
if (hudStyle == null)
{
hudStyle = new GUIStyle(GUI.skin.label) { fontSize = 16, richText = false };
}
bool layered = (currentExStyle & 0x00080000) != 0;
bool transparent = (currentExStyle & 0x00000020) != 0;
string text =
$"NOACTIVATE: {useNoActivate} [Ctrl+Alt+N 전환]\n" +
$"ExStyle: 0x{currentExStyle:X8} LAYERED={layered} TRANSPARENT={transparent}\n" +
$"OverCharacter: {IsOverCharacter} 클릭 횟수: {clickCount}\n" +
$"마지막: {lastAction}\n" +
$"[Ctrl+Alt+Q 종료]";
var rect = new Rect(14f, 14f, 900f, 160f);
// 배경 없이도 읽히도록 그림자를 먼저 깐다
hudStyle.normal.textColor = Color.black;
GUI.Label(new Rect(rect.x + 1f, rect.y + 1f, rect.width, rect.height), text, hudStyle);
hudStyle.normal.textColor = Color.white;
GUI.Label(rect, text, hudStyle);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5ca4ab0faf560dd4f8fcf2d3093dceb7

View File

@@ -0,0 +1,40 @@
using UnityEngine;
/// <summary>
/// 전역 종료 핫키. 기본 Ctrl+Alt+Q.
///
/// 작업표시줄에서 숨겨진 데다 WS_EX_NOACTIVATE 까지 붙으면 창이 포커스를
/// 받지 못해 Unity 의 키 입력이 들어오지 않는다. GetAsyncKeyState 는 포커스와
/// 무관하게 전역 키 상태를 읽으므로, 메시지 루프나 wndproc 후킹 없이
/// 확실한 탈출구가 된다.
/// </summary>
public class GlobalExitHotkey : MonoBehaviour
{
// 아래 필드들은 Windows 빌드에서만 쓰이므로 에디터 컴파일 시 CS0414 가 뜬다
#pragma warning disable 0414
[Tooltip("A-Z 한 글자. Ctrl+Alt 와 조합된다")]
[SerializeField] char exitKey = 'Q';
[SerializeField] bool requireCtrl = true;
[SerializeField] bool requireAlt = true;
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
bool quitting;
void Update()
{
if (quitting) return;
if (requireCtrl && !Win32.IsKeyDown(Win32.VK_CONTROL)) return;
if (requireAlt && !Win32.IsKeyDown(Win32.VK_MENU)) return;
int vk = char.ToUpperInvariant(exitKey);
if (!Win32.IsKeyDown(vk)) return;
quitting = true;
Debug.Log("[GlobalExitHotkey] 종료 핫키 감지. 종료합니다.");
Application.Quit();
}
#endif
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 83652a9ef9463bc4aabdd81cc62a3954

View File

@@ -0,0 +1,148 @@
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering.Universal;
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
using System;
#endif
/// <summary>
/// 창을 테두리 없는 최상단 투명 창으로 만든다.
/// 작업표시줄과 Alt+Tab 에서도 숨긴다.
/// 에디터에서는 아무것도 하지 않는다 (에디터 창이 사라지는 사고 방지).
/// </summary>
[RequireComponent(typeof(Camera))]
public class TransparentWindow : MonoBehaviour
{
[Header("창 동작")]
[Tooltip("창을 가상 데스크톱 전체로 확장. 클릭 통과가 동작하는 것을 확인한 뒤 켤 것")]
[SerializeField] bool spanVirtualDesktop = false;
[Tooltip("작업표시줄 / Alt+Tab 에서 숨김 (WS_EX_TOOLWINDOW)")]
[SerializeField] bool hideFromTaskbar = true;
[Header("검증용")]
[Tooltip("런타임 큐브 생성. 씬에 AlphaTestCube 가 있으면 그쪽이 우선한다")]
[SerializeField] bool spawnTestCube = false;
[Tooltip("URP 포스트프로세싱 비활성화")]
[SerializeField] bool forceDisablePostProcessing = true;
[Tooltip("포커스가 있을 때 Esc 로 종료. NOACTIVATE 를 켜면 동작하지 않으므로 GlobalExitHotkey 를 함께 쓸 것")]
[SerializeField] bool quitOnEscape = true;
Camera cam;
Transform testCube;
/// <summary>플레이어 창 핸들. 준비되기 전에는 Zero.</summary>
public System.IntPtr Hwnd { get; private set; } = System.IntPtr.Zero;
/// <summary>Win32 스타일 적용이 끝났는지.</summary>
public bool IsReady { get; private set; }
void Awake()
{
cam = GetComponent<Camera>();
// 알파 0 클리어 — 투명의 출발점
cam.clearFlags = CameraClearFlags.SolidColor;
cam.backgroundColor = new Color(0f, 0f, 0f, 0f);
if (forceDisablePostProcessing)
{
var urp = cam.GetUniversalAdditionalCameraData();
if (urp != null) urp.renderPostProcessing = false;
}
Application.runInBackground = true;
// 씬에 큐브가 있으면 그것을 쓰고, 없을 때만 런타임 생성
var inScene = GameObject.Find("AlphaTestCube");
if (inScene != null) testCube = inScene.transform;
else if (spawnTestCube) CreateTestCube();
}
void Start()
{
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
StartCoroutine(ApplyWindowStyle());
#else
Debug.Log("[TransparentWindow] 에디터에서는 Win32 적용을 건너뜁니다. 빌드해서 테스트하세요.");
#endif
}
void Update()
{
if (testCube != null) testCube.Rotate(new Vector3(30f, 45f, 15f) * Time.deltaTime);
// 포커스가 있을 때만 동작하는 보조 탈출구
if (quitOnEscape)
{
var kb = Keyboard.current;
if (kb != null && kb.escapeKey.wasPressedThisFrame) Application.Quit();
}
}
void CreateTestCube()
{
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "AlphaTestCube";
cube.transform.position = transform.position + transform.forward * 5f;
testCube = cube.transform;
}
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
IEnumerator ApplyWindowStyle()
{
int x = 0, y = 0, w = Screen.width, h = Screen.height;
if (spanVirtualDesktop)
{
x = Win32.GetSystemMetrics(Win32.SM_XVIRTUALSCREEN);
y = Win32.GetSystemMetrics(Win32.SM_YVIRTUALSCREEN);
w = Win32.GetSystemMetrics(Win32.SM_CXVIRTUALSCREEN);
h = Win32.GetSystemMetrics(Win32.SM_CYVIRTUALSCREEN);
Screen.SetResolution(w, h, FullScreenMode.Windowed);
}
// SetResolution 은 프레임 끝에 반영되므로 스타일 적용 전에 기다린다
yield return null;
yield return new WaitForEndOfFrame();
yield return null;
IntPtr hwnd = Win32.GetActiveWindow();
if (hwnd == IntPtr.Zero) hwnd = Win32.FindWindowW(null, Application.productName);
if (hwnd == IntPtr.Zero)
{
Debug.LogError("[TransparentWindow] HWND 를 찾지 못했습니다.");
yield break;
}
// 타이틀바 / 테두리 제거
Win32.SetWindowLongW(hwnd, Win32.GWL_STYLE, Win32.WS_POPUP | Win32.WS_VISIBLE);
if (hideFromTaskbar)
{
uint ex = Win32.GetWindowLongW(hwnd, Win32.GWL_EXSTYLE);
ex = (ex | Win32.WS_EX_TOOLWINDOW) & ~Win32.WS_EX_APPWINDOW;
Win32.SetWindowLongW(hwnd, Win32.GWL_EXSTYLE, ex);
// TOOLWINDOW 변경은 hide/show 해야 작업표시줄에 반영된다
Win32.ShowWindow(hwnd, Win32.SW_HIDE);
Win32.ShowWindow(hwnd, Win32.SW_SHOW);
}
// 픽셀 단위 알파 투명
var margins = new Win32.MARGINS { cxLeftWidth = -1, cxRightWidth = -1, cyTopHeight = -1, cyBottomHeight = -1 };
int hr = Win32.DwmExtendFrameIntoClientArea(hwnd, ref margins);
Debug.Log($"[TransparentWindow] DwmExtendFrameIntoClientArea hr=0x{hr:X8} (0 이면 성공)");
Win32.SetWindowPos(hwnd, Win32.HWND_TOPMOST, x, y, w, h,
Win32.SWP_FRAMECHANGED | Win32.SWP_SHOWWINDOW);
Hwnd = hwnd;
IsReady = true;
Debug.Log($"[TransparentWindow] 적용 완료: {x},{y} {w}x{h}");
}
#endif
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e3227c6d05a07a640bb1d96118c0a82e

View File

@@ -0,0 +1,371 @@
using UnityEngine;
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
using System;
using System.Runtime.InteropServices;
#endif
/// <summary>
/// 시스템 트레이 아이콘과 우클릭 메뉴.
///
/// WS_EX_TOOLWINDOW 로 작업표시줄에서 사라졌기 때문에 종료/제어 수단이 필요하다.
///
/// 구현 노트: Shell_NotifyIcon 은 콜백 메시지를 받을 창이 필요한데, Unity 창의
/// 윈도우 프로시저를 SetWindowLongPtr 로 가로채는 것은 관리 델리게이트 수명과
/// 재진입 문제가 있어 위험하다. 대신 전용 창을 따로 만들어 거기에 아이콘을 걸고,
/// PeekMessage 를 그 창으로 한정해 직접 펌핑한다. Unity 의 메시지 루프는 건드리지 않는다.
///
/// HWND_MESSAGE(메시지 전용 창)를 쓰지 않는 이유: 메시지 전용 창은 브로드캐스트
/// 메시지를 받지 못해 TaskbarCreated 재등록이 동작하지 않고, z-order 가 없어
/// SetForegroundWindow 가 실패해 팝업 메뉴가 제대로 닫히지 않는다.
/// 대신 WS_EX_TOOLWINDOW + WS_POPUP 인 일반 최상위 창을 만들되 표시하지 않는다.
/// </summary>
public class TrayIcon : MonoBehaviour
{
[SerializeField] string tooltip = "MyCharacterAgent";
[SerializeField] bool verboseLog = true;
TransparentWindow window;
void Awake()
{
window = GetComponent<TransparentWindow>();
if (window == null) window = FindFirstObjectByType<TransparentWindow>();
}
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
const string ClassName = "MyCharacterAgentTrayWnd";
const int ID_TOGGLE = 1;
const int ID_EXIT = 2;
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
// GC 가 델리게이트를 수거하면 네이티브 쪽에서 죽은 포인터를 호출하게 되므로
// 반드시 static 필드로 붙잡아 둔다.
static WndProcDelegate wndProcHolder;
IntPtr trayHwnd = IntPtr.Zero;
bool iconAdded;
bool characterVisible = true;
uint taskbarCreatedMsg;
bool cleaned;
// wndproc 에서 세우고 Update 에서 처리한다. TrackPopupMenu 는 중첩 메시지 루프를
// 돌리므로 메시지 처리 도중이 아니라 프레임의 안전한 지점에서 부르는 편이 낫다.
bool pendingMenu;
bool pendingToggle;
bool pendingReAdd;
void Start()
{
StartCoroutine(CreateWhenReady());
}
System.Collections.IEnumerator CreateWhenReady()
{
// 보이기/숨기기가 Unity 창 핸들을 쓰므로 창 준비를 기다린다.
float deadline = Time.realtimeSinceStartup + 5f;
while ((window == null || !window.IsReady) && Time.realtimeSinceStartup < deadline)
yield return null;
// 창 생성 전에 등록해야 wndproc 이 첫 브로드캐스트부터 인식할 수 있다.
// (탐색기가 재시작되면 트레이 아이콘이 사라지므로 재등록이 필요하다)
taskbarCreatedMsg = RegisterWindowMessageW("TaskbarCreated");
if (!CreateTrayWindow()) yield break;
AddIcon();
}
bool CreateTrayWindow()
{
IntPtr hInstance = GetModuleHandleW(null);
wndProcHolder = WndProc;
var wc = new WNDCLASSEXW
{
cbSize = Marshal.SizeOf(typeof(WNDCLASSEXW)),
lpfnWndProc = Marshal.GetFunctionPointerForDelegate(wndProcHolder),
hInstance = hInstance,
lpszClassName = ClassName,
};
// 이미 등록된 클래스여도 무시하고 창 생성을 시도한다.
RegisterClassExW(ref wc);
// WS_VISIBLE 를 주지 않으므로 화면에 나타나지 않는다.
// WS_EX_TOOLWINDOW 로 작업표시줄/Alt+Tab 에도 뜨지 않는다.
trayHwnd = CreateWindowExW(Win32.WS_EX_TOOLWINDOW, ClassName, string.Empty,
Win32.WS_POPUP, 0, 0, 0, 0,
IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero);
if (trayHwnd == IntPtr.Zero)
{
Debug.LogError($"[TrayIcon] 트레이용 창 생성 실패. err={Marshal.GetLastWin32Error()}");
return false;
}
return true;
}
/// <summary>
/// 우리 창의 윈도우 프로시저. Unity 메인 스레드의 DispatchMessage 에서 호출된다.
/// </summary>
IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == WM_TRAYICON)
{
uint ev = (uint)(lParam.ToInt64() & 0xFFFF);
// 아이콘 위로 마우스가 지나가기만 해도 WM_MOUSEMOVE 가 계속 온다.
// 상시 구동되는 앱이라 그대로 찍으면 로그가 끝없이 커진다.
if (verboseLog && ev != WM_MOUSEMOVE)
Debug.Log($"[TrayIcon] WM_TRAYICON ev=0x{ev:X4}");
if (ev == WM_RBUTTONUP || ev == WM_CONTEXTMENU) pendingMenu = true;
else if (ev == WM_LBUTTONDBLCLK) pendingToggle = true;
return IntPtr.Zero;
}
if (taskbarCreatedMsg != 0 && msg == taskbarCreatedMsg)
{
pendingReAdd = true;
return IntPtr.Zero;
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
IntPtr LoadAppIcon()
{
try
{
string exe = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
IntPtr icon = ExtractIconW(GetModuleHandleW(null), exe, 0);
if (icon != IntPtr.Zero && icon != new IntPtr(1)) return icon;
}
catch (Exception e)
{
Debug.LogWarning($"[TrayIcon] exe 아이콘 추출 실패, 기본 아이콘 사용: {e.Message}");
}
return LoadIconW(IntPtr.Zero, new IntPtr(IDI_APPLICATION));
}
void AddIcon()
{
var data = new NOTIFYICONDATAW
{
cbSize = Marshal.SizeOf(typeof(NOTIFYICONDATAW)),
hWnd = trayHwnd,
uID = 1,
uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP,
uCallbackMessage = WM_TRAYICON,
hIcon = LoadAppIcon(),
szTip = tooltip,
};
iconAdded = Shell_NotifyIconW(NIM_ADD, ref data);
if (iconAdded) Debug.Log("[TrayIcon] 트레이 아이콘 등록됨");
else Debug.LogError("[TrayIcon] Shell_NotifyIcon(NIM_ADD) 실패");
}
void Update()
{
if (trayHwnd == IntPtr.Zero) return;
// Unity 펌프가 우리 창 메시지를 대부분 처리하지만, 놓치는 경우를 대비한 보조 펌프.
// 처리는 전적으로 wndproc 이 하므로 여기서는 디스패치만 한다(이중 처리 방지).
while (PeekMessageW(out MSG msg, trayHwnd, 0, 0, PM_REMOVE))
{
TranslateMessage(ref msg);
DispatchMessageW(ref msg);
}
if (pendingReAdd) { pendingReAdd = false; AddIcon(); }
if (pendingToggle) { pendingToggle = false; ToggleCharacter(); }
if (pendingMenu) { pendingMenu = false; ShowContextMenu(); }
}
void ShowContextMenu()
{
IntPtr menu = CreatePopupMenu();
if (menu == IntPtr.Zero) return;
AppendMenuW(menu, MF_STRING, ID_TOGGLE, characterVisible ? "캐릭터 숨기기" : "캐릭터 보이기");
AppendMenuW(menu, MF_SEPARATOR, 0, null);
AppendMenuW(menu, MF_STRING, ID_EXIT, "종료");
Win32.GetCursorPos(out var pt);
// 트레이 메뉴 관용구: 앞으로 가져와야 메뉴 밖 클릭 시 정상적으로 닫힌다.
SetForegroundWindow(trayHwnd);
int cmd = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_NONOTIFY,
pt.x, pt.y, 0, trayHwnd, IntPtr.Zero);
PostMessageW(trayHwnd, WM_NULL, IntPtr.Zero, IntPtr.Zero);
DestroyMenu(menu);
if (verboseLog) Debug.Log($"[TrayIcon] 메뉴 선택 결과 cmd={cmd}");
if (cmd == ID_EXIT)
{
Debug.Log("[TrayIcon] 메뉴에서 종료 선택");
Application.Quit();
}
else if (cmd == ID_TOGGLE)
{
ToggleCharacter();
}
}
void ToggleCharacter()
{
if (window == null || !window.IsReady) return;
characterVisible = !characterVisible;
Win32.ShowWindow(window.Hwnd, characterVisible ? Win32.SW_SHOW : Win32.SW_HIDE);
if (characterVisible)
{
// SW_SHOW 후 최상단 속성이 풀릴 수 있어 다시 걸어준다.
Win32.SetWindowPos(window.Hwnd, Win32.HWND_TOPMOST, 0, 0, 0, 0,
Win32.SWP_NOMOVE | Win32.SWP_NOSIZE | Win32.SWP_NOACTIVATE);
}
}
void RemoveIcon()
{
if (!iconAdded) return;
var data = new NOTIFYICONDATAW
{
cbSize = Marshal.SizeOf(typeof(NOTIFYICONDATAW)),
hWnd = trayHwnd,
uID = 1,
};
Shell_NotifyIconW(NIM_DELETE, ref data);
iconAdded = false;
}
// 정리를 빠뜨리면 종료 후에도 유령 아이콘이 트레이에 남는다.
void OnApplicationQuit() => Cleanup();
void OnDestroy() => Cleanup();
void Cleanup()
{
if (cleaned) return;
cleaned = true;
RemoveIcon();
if (trayHwnd != IntPtr.Zero)
{
DestroyWindow(trayHwnd);
trayHwnd = IntPtr.Zero;
}
UnregisterClassW(ClassName, GetModuleHandleW(null));
wndProcHolder = null;
}
// ---------------- P/Invoke (트레이 전용) ----------------
const int IDI_APPLICATION = 32512;
const uint NIM_ADD = 0x00000000;
const uint NIM_DELETE = 0x00000002;
const uint NIF_MESSAGE = 0x00000001;
const uint NIF_ICON = 0x00000002;
const uint NIF_TIP = 0x00000004;
const uint WM_NULL = 0x0000;
const uint WM_MOUSEMOVE = 0x0200;
const uint WM_LBUTTONDBLCLK = 0x0203;
const uint WM_RBUTTONUP = 0x0205;
const uint WM_CONTEXTMENU = 0x007B;
const uint WM_APP = 0x8000;
const uint WM_TRAYICON = WM_APP + 1;
const uint PM_REMOVE = 0x0001;
const uint MF_STRING = 0x0000;
const uint MF_SEPARATOR = 0x0800;
const uint TPM_RIGHTBUTTON = 0x0002;
const uint TPM_RETURNCMD = 0x0100;
const uint TPM_NONOTIFY = 0x0080;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct WNDCLASSEXW
{
public int cbSize;
public uint style;
public IntPtr lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
[MarshalAs(UnmanagedType.LPWStr)] public string lpszMenuName;
[MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName;
public IntPtr hIconSm;
}
[StructLayout(LayoutKind.Sequential)]
struct MSG
{
public IntPtr hwnd;
public uint message;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public Win32.POINT pt;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct NOTIFYICONDATAW
{
public int cbSize;
public IntPtr hWnd;
public uint uID;
public uint uFlags;
public uint uCallbackMessage;
public IntPtr hIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szTip;
public uint dwState;
public uint dwStateMask;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string szInfo;
public uint uVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string szInfoTitle;
public uint dwInfoFlags;
public Guid guidItem;
public IntPtr hBalloonIcon;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern IntPtr GetModuleHandleW(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] static extern ushort RegisterClassExW(ref WNDCLASSEXW lpwcx);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] static extern bool UnregisterClassW(string lpClassName, IntPtr hInstance);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr CreateWindowExW(uint dwExStyle, string lpClassName, string lpWindowName,
uint dwStyle, int x, int y, int nWidth, int nHeight,
IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
[DllImport("user32.dll")] static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern IntPtr DefWindowProcW(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern bool PeekMessageW(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[DllImport("user32.dll")] static extern bool TranslateMessage(ref MSG lpMsg);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern IntPtr DispatchMessageW(ref MSG lpMsg);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern bool PostMessageW(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern uint RegisterWindowMessageW(string lpString);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern IntPtr LoadIconW(IntPtr hInstance, IntPtr lpIconName);
[DllImport("shell32.dll", CharSet = CharSet.Unicode)] static extern IntPtr ExtractIconW(IntPtr hInst, string lpszExeFileName, int nIconIndex);
[DllImport("shell32.dll", CharSet = CharSet.Unicode)] static extern bool Shell_NotifyIconW(uint dwMessage, ref NOTIFYICONDATAW lpData);
[DllImport("user32.dll")] static extern IntPtr CreatePopupMenu();
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern bool AppendMenuW(IntPtr hMenu, uint uFlags, int uIDNewItem, string lpNewItem);
[DllImport("user32.dll")] static extern bool DestroyMenu(IntPtr hMenu);
[DllImport("user32.dll")] static extern int TrackPopupMenu(IntPtr hMenu, uint uFlags, int x, int y, int nReserved, IntPtr hWnd, IntPtr prcRect);
[DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr hWnd);
#endif
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a951781c3ff22c04193a69b7db01010f

View File

@@ -0,0 +1,84 @@
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
using System;
using System.Runtime.InteropServices;
/// <summary>
/// 데스크톱 오버레이에 필요한 Win32 선언 모음.
/// 선언 자체는 무해하며, 실제 호출부에서 에디터 여부를 가드한다.
/// </summary>
internal static class Win32
{
public const int GWL_STYLE = -16;
public const int GWL_EXSTYLE = -20;
public const uint WS_POPUP = 0x80000000;
public const uint WS_VISIBLE = 0x10000000;
public const uint WS_EX_TOOLWINDOW = 0x00000080; // 작업표시줄/Alt+Tab 에서 숨김
public const uint WS_EX_APPWINDOW = 0x00040000;
public const uint WS_EX_TRANSPARENT = 0x00000020; // 마우스 히트테스트 통과
public const uint WS_EX_NOACTIVATE = 0x08000000; // 클릭해도 포커스를 뺏지 않음
public const uint WS_EX_LAYERED = 0x00080000; // 최상위 창의 클릭 통과에 필요
public const uint LWA_COLORKEY = 0x00000001;
public const uint LWA_ALPHA = 0x00000002;
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public const uint SWP_NOSIZE = 0x0001;
public const uint SWP_NOMOVE = 0x0002;
public const uint SWP_NOACTIVATE = 0x0010;
public const uint SWP_FRAMECHANGED = 0x0020;
public const uint SWP_SHOWWINDOW = 0x0040;
public const int SM_XVIRTUALSCREEN = 76;
public const int SM_YVIRTUALSCREEN = 77;
public const int SM_CXVIRTUALSCREEN = 78;
public const int SM_CYVIRTUALSCREEN = 79;
public const int SW_HIDE = 0;
public const int SW_SHOW = 5;
public const int VK_SHIFT = 0x10;
public const int VK_CONTROL = 0x11;
public const int VK_MENU = 0x12; // Alt
public const int VK_1 = 0x31;
public const int VK_2 = 0x32;
public const int VK_3 = 0x33;
public const int VK_N = 0x4E;
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x, y;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left, top, right, bottom;
public int Width => right - left;
public int Height => bottom - top;
}
[DllImport("user32.dll")] public static extern IntPtr GetActiveWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindowW(string lpClassName, string lpWindowName);
[DllImport("user32.dll")] public static extern uint GetWindowLongW(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")] public static extern uint SetWindowLongW(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll")] public static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")] public static extern short GetAsyncKeyState(int vKey);
[DllImport("user32.dll")] public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags);
[DllImport("dwmapi.dll")] public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
public static bool IsKeyDown(int vKey) => (GetAsyncKeyState(vKey) & 0x8000) != 0;
}
#endif

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 014f94e37c2e5de4bb0fbe5e0831e18b

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 16af5d21b8812db41a6f5dbe27a02530
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 955d1f72698f38145b86f717b5deb478

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: df326b119a49c5b45993089b9bfdbf09
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
using UnityEngine;
public class GameManager : MonoBehaviour
{
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8a04fd99999327e4b8dc1d3f13f1116e

8
Assets/99_Settings.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 709f11a7f3c4041caa4ef136ea32d874
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AlphaTestCubeMat
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.2, g: 0.8, b: 1, a: 1}
- _Color: {r: 0.19999996, g: 0.8, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &4714984517812359127
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
version: 10

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9b1d5b32bbd5c8d488855b469aadd1c6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ab09877e2e707104187f6f83e2f62510
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 052faaac586de48259a63d0c4782560b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
generateWrapperCode: 0
wrapperCodePath:
wrapperClassName:
wrapperCodeNamespace:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e6cbd92db86f4b18aec3ed561671858
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 65bc7dbf4170f435aa868c779acfb082
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4b83569d67af61e458304325a23e5dfd
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f288ae1f4751b564a96ac7587541f7a2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 10fc4df2da32a41aaa32d77bc913491c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 18dc0cd2c080841dea60987a38ce93fa
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

49
Packages/manifest.json Normal file
View File

@@ -0,0 +1,49 @@
{
"dependencies": {
"com.unity.ai.navigation": "2.0.14",
"com.unity.collab-proxy": "2.12.4",
"com.unity.ide.rider": "3.0.40",
"com.unity.ide.visualstudio": "2.0.26",
"com.unity.inputsystem": "1.20.0",
"com.unity.multiplayer.center": "1.0.1",
"com.unity.render-pipelines.universal": "17.3.0",
"com.unity.test-framework": "1.6.0",
"com.unity.timeline": "1.8.12",
"com.unity.ugui": "2.0.0",
"com.unity.visualscripting": "1.9.12",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.adaptiveperformance": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vectorgraphics": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}

472
Packages/packages-lock.json Normal file
View File

@@ -0,0 +1,472 @@
{
"dependencies": {
"com.unity.ai.navigation": {
"version": "2.0.14",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.ai": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.burst": {
"version": "1.8.30",
"depth": 2,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.12.4",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "2.6.8",
"depth": 2,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.29",
"com.unity.mathematics": "1.3.2",
"com.unity.test-framework": "1.4.6",
"com.unity.nuget.mono-cecil": "1.11.6",
"com.unity.test-framework.performance": "3.0.3"
},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "2.0.5",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.ide.rider": {
"version": "3.0.40",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.26",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33"
},
"url": "https://packages.unity.com"
},
"com.unity.inputsystem": {
"version": "1.20.0",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.uielements": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.mathematics": {
"version": "1.3.3",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.multiplayer.center": {
"version": "1.0.1",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.uielements": "1.0.0"
}
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.6",
"depth": 3,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.render-pipelines.core": {
"version": "17.3.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.burst": "1.8.14",
"com.unity.mathematics": "1.3.2",
"com.unity.ugui": "2.0.0",
"com.unity.collections": "2.4.3",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.render-pipelines.universal": {
"version": "17.3.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.3.0",
"com.unity.shadergraph": "17.3.0",
"com.unity.render-pipelines.universal-config": "17.0.3"
}
},
"com.unity.render-pipelines.universal-config": {
"version": "17.0.3",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.0.3"
}
},
"com.unity.searcher": {
"version": "4.9.5",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.shadergraph": {
"version": "17.3.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.render-pipelines.core": "17.3.0",
"com.unity.searcher": "4.9.3"
}
},
"com.unity.test-framework": {
"version": "1.6.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.ext.nunit": "2.0.3",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.test-framework.performance": {
"version": "3.5.0",
"depth": 3,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.8.12",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "2.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.visualscripting": {
"version": "1.9.12",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "2.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.modules.accessibility": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.adaptiveperformance": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.subsystems": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.hierarchycore": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.hierarchycore": "1.0.0",
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vectorgraphics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
m_EditorVersion: 6000.3.22f1
m_EditorVersionWithRevision: 6000.3.22f1 (1c726e1fb402)

Binary file not shown.

View File

@@ -0,0 +1,121 @@
{
"templatePinStates": [],
"dependencyTypeInfos": [
{
"userAdded": false,
"type": "UnityEngine.AnimationClip",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.Animations.AnimatorController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.AnimatorOverrideController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.Audio.AudioMixerController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.ComputeShader",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Cubemap",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.GameObject",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.LightingDataAsset",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.LightingSettings",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Material",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.MonoScript",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.PhysicsMaterial",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.PhysicsMaterial2D",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.VolumeProfile",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.SceneAsset",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Shader",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.ShaderVariantCollection",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Texture",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Texture2D",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Timeline.TimelineAsset",
"defaultInstantiationMode": 0
}
],
"defaultDependencyTypeInfo": {
"userAdded": false,
"type": "<default_scene_template_dependencies>",
"defaultInstantiationMode": 1
},
"newSceneOverride": 0
}

Binary file not shown.

BIN
ProjectSettings/TagManager.asset LFS Normal file

Binary file not shown.

BIN
ProjectSettings/TimeManager.asset LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
ProjectSettings/VFXManager.asset LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
ProjectSettings/XRSettings.asset LFS Normal file

Binary file not shown.