<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>외장뇌모리</title>
    <link>https://progrunman.tistory.com/</link>
    <description>게으른 개발자의 기억 보관을 위한 외장기억장치</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 02:53:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>progrunman</managingEditor>
    <image>
      <title>외장뇌모리</title>
      <url>https://tistory1.daumcdn.net/tistory/3118715/attach/68667a3c20d0458c8ad78f5832c9201a</url>
      <link>https://progrunman.tistory.com</link>
    </image>
    <item>
      <title>윈도우11 네트워크 폴더공유 자격증명 안될때 해결책</title>
      <link>https://progrunman.tistory.com/81</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;## 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우11 네트워크 폴더공유시 정확한 계정정보를 입력했음에도 자격증명에서 잘못된 비밀번호로 접속불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## 원인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;윈도우11&lt;/b&gt;부터 윈도우설치시 네트워크 연결상태로 &lt;b&gt;MSA(MicroSoft Account) 연동이 강제&lt;/b&gt;되어 &lt;u&gt;로컬계정의 비밀번호가 없는 상태&lt;/u&gt;임에도 자격증명에서 MSA가 아닌 로컬계정 정보를 요구해서 발생하는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## 해결&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬계정의 비밀번호를 추가하여 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## 상세&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우11 재설치 후, 내부 네트워크망에서 폴더공유시 계속 자격증명이 잘못되었다고 접속이 안되는 문제가 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분명 MSA를 정확하게 입력하였음에도 비밀번호가 틀렸다고 나와서 곰곰히 생각해보니 로컬계정을 확인하는것 같았고, &lt;span style=&quot;color: #ee2323;&quot;&gt;설치 단계에서 로컬계정 비밀번호 설정을 한적이 없다&lt;/span&gt;는걸 깨닳았다. (윈도우11이 MSA계정의 앞 5글자로 로컬계정명을 자동으로 생성)&lt;br /&gt;이후, MSA에서 로그아웃하고 로컬계정에 접속해보니 비밀번호 설정이 안된것이 확인되었고, 비밀번호 설정 후 MSA로 재접속하여 폴더공유가 예전처럼 잘 되는것을 확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 윈도우키 + i : 설정창 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 좌측 &quot;계정&quot; 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 우측 &quot;사용자 정보&quot; 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-15 083403.png&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;924&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZixY6/dJMcagRo56G/DjanCkUY7KzOlLd5e5uV1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZixY6/dJMcagRo56G/DjanCkUY7KzOlLd5e5uV1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZixY6/dJMcagRo56G/DjanCkUY7KzOlLd5e5uV1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZixY6%2FdJMcagRo56G%2FDjanCkUY7KzOlLd5e5uV1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1187&quot; height=&quot;924&quot; data-filename=&quot;스크린샷 2025-11-15 083403.png&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;924&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 계정 설정의 Microsoft 계정에서 &quot;대신 로컬 계정으로 로그인&quot;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-11-15 083743.png&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;249&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ufrui/dJMb99Y20bU/IH2SFkDPkOj2c0IUQjMp91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ufrui/dJMb99Y20bU/IH2SFkDPkOj2c0IUQjMp91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ufrui/dJMb99Y20bU/IH2SFkDPkOj2c0IUQjMp91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fufrui%2FdJMb99Y20bU%2FIH2SFkDPkOj2c0IUQjMp91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1177&quot; height=&quot;249&quot; data-filename=&quot;화면 캡처 2025-11-15 083743.png&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 로컬계정 설정 (개인적으로는 사용자이름을 변경시 문제발생할까봐 그대로 유지하고 비밀번호만 추가)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-15 083817.png&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dExDcN/dJMcaaRbJe1/DKqGv3u1qzHhatvX9d7fv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dExDcN/dJMcaaRbJe1/DKqGv3u1qzHhatvX9d7fv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dExDcN/dJMcaaRbJe1/DKqGv3u1qzHhatvX9d7fv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdExDcN%2FdJMcaaRbJe1%2FDKqGv3u1qzHhatvX9d7fv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;665&quot; data-filename=&quot;스크린샷 2025-11-15 083817.png&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 MSA로 재접속시 로컬계정 로그인 문구는 아래와 같이 변경된다. (가끔 MSA인증이 잘 안될수도 있는데 재부팅하면 된다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-15 091236.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kMW0m/dJMcahQjsOe/TQJVMewXKwmR8KByYKZA61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kMW0m/dJMcahQjsOe/TQJVMewXKwmR8KByYKZA61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kMW0m/dJMcahQjsOe/TQJVMewXKwmR8KByYKZA61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkMW0m%2FdJMcahQjsOe%2FTQJVMewXKwmR8KByYKZA61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;857&quot; height=&quot;105&quot; data-filename=&quot;스크린샷 2025-11-15 091236.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후부터 폴더공유시 로컬계정 정보로 접속하거나 &quot;자격 증명 관리자&quot;의 &quot;Windows 자격 증명&quot;에 자격증명을 저장해놓고 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA로 자격증명이 되거나, 윈도우11 설치단계에 로컬계정도 세팅하도록 했으면 문제가 발생하지 않았을텐데 MS에서 왜 안고치는지는 의문이다.&lt;/p&gt;</description>
      <category>Programming/IDE, Tools, etc.</category>
      <category>Windows11</category>
      <category>공유</category>
      <category>네트워크</category>
      <category>윈도우11</category>
      <category>자격증명</category>
      <category>폴더공유</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/81</guid>
      <comments>https://progrunman.tistory.com/81#entry81comment</comments>
      <pubDate>Sat, 15 Nov 2025 09:22:14 +0900</pubDate>
    </item>
    <item>
      <title>락앤락 개인정보 유출</title>
      <link>https://progrunman.tistory.com/80</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;928&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGJ23i/btsK1llDURo/Eu505YTHtKy7ErvgMkQl70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGJ23i/btsK1llDURo/Eu505YTHtKy7ErvgMkQl70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGJ23i/btsK1llDURo/Eu505YTHtKy7ErvgMkQl70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGJ23i%2FbtsK1llDURo%2FEu505YTHtKy7ErvgMkQl70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;928&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;928&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;락앤락에서 개인정보 유출 문자가 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니 앞으로 언락앤언락이라고 부르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;털린 정보는... 그냥 다 털림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니, 그냥 털린 정도가 아니라 빤스부터 알몸까지 다털림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 미친놈들인가? 데이터를 어떻게 관리하면 저정도 수준까지 털릴 수 있지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 사이트 접속이 안되는데 접속되면 바로 탈퇴 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 앞으로 언락앤언락 제품은 1도 구매하지 않을 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가입된 각종 존만한 기업 사이트들은 모조리 탈퇴해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;존만한 기업들에 SW부서가 제대로일리가 없고, 대가리들이 보안에 투자할 생각도 없을테니..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이미 너무 심하게 털려버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;X발 머리부터 발끝까지 털려버려서 뭐 어떻게 할수가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이메일이나 비번 이런건 변경이라도 가능하지 나머지는 내가 다시 태어나지 않는이상 변경도 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디, 비번, 성별, 생년월일, CI, 휴대폰번호, 이름, 이메일, 주소, 자동로그인 연동정보라니.. 이게 말이냐 방구냐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 여기 왜 회원가입을 한거냐 X발 X같네&lt;/p&gt;</description>
      <category>취미/모두까기</category>
      <category>개또라이들인가</category>
      <category>락앤락</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/80</guid>
      <comments>https://progrunman.tistory.com/80#entry80comment</comments>
      <pubDate>Fri, 29 Nov 2024 19:50:36 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] uGUI</title>
      <link>https://progrunman.tistory.com/77</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity UI(uGUI)는 built-in으로 탑재된 &lt;u&gt;&lt;b&gt;GameObject기반&lt;/b&gt;&lt;/u&gt;의 UI 관련 패키지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GameObject기반이니 당연히 컴포넌트 기반으로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 &quot;제공되는 각기 다른 특성을 지닌 컴포넌트들을 사용해 Canvas게임오브젝트 아래에 자식 UI게임오브젝트들을 구성하면, Canvas 게임오브젝트는 자식까지 포함해 C++ 엔진과 연동해서 UI로 각 프레임에 그려주겠다&quot;이다. (C++로 작성된 핵심 컴포넌트는 Canvas, RectTransform, CanvasRenderer, CanvasGroup)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI Toolkit이라는 신규 UI시스템을 유니티에서 밀고는 있지만 아직은 uGUI가 지원범위도 넓고 안정적이라 실무 도입은 이른것 같다. &lt;b&gt;&lt;/b&gt;UI Toolkit으로 완전히 전환되는 시점은 모르겠지만 내부적으로 아래와 같이 진행되는 중인듯했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Unity_UI_Modules_References.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BxuXx/btr53CFSIZx/vzGoXQC1j7hMvgfMKa08Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BxuXx/btr53CFSIZx/vzGoXQC1j7hMvgfMKa08Tk/img.png&quot; data-alt=&quot;모듈 참조 관계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BxuXx/btr53CFSIZx/vzGoXQC1j7hMvgfMKa08Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBxuXx%2Fbtr53CFSIZx%2FvzGoXQC1j7hMvgfMKa08Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1144&quot; height=&quot;673&quot; data-filename=&quot;Unity_UI_Modules_References.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모듈 참조 관계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Graphic(C#)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity UI C# 라이브러리에서 제공하는 기본 클래스(&lt;b&gt;UnityEngine.UI.Graphic&lt;/b&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - UnityEngine.Graphic&lt;b&gt;s&lt;/b&gt; 와는 별개임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;u&gt;Canvas 시스템에서 렌더링 가능한&lt;/u&gt; 모든 Unity UI C# 클래스의 기본 클래스 (CanvasRenderer와 연동)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Image, Text, TMP_Text, etc&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Button의 경우 Selectable에서 파생되며 내부에 Image와 Text를 통해 화면을 그림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DoMeshGeneration() : UI는 Mesh로 이루어짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그래픽적 요소들을 설정 및 저장 (Canvas를 통해 계산되고 그려지기 위해)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 주요 클래스 관계도를 보면 Unity UI가 어떻게 동작하는지 대략적으로 이해 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGQHw3/btr5R0VcC8V/0YgZkAllN1uAEYGeadNt51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGQHw3/btr5R0VcC8V/0YgZkAllN1uAEYGeadNt51/img.png&quot; data-alt=&quot;주요 클래스 관계도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGQHw3/btr5R0VcC8V/0YgZkAllN1uAEYGeadNt51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGQHw3%2Fbtr5R0VcC8V%2F0YgZkAllN1uAEYGeadNt51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;847&quot; height=&quot;760&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주요 클래스 관계도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - UnityEngine : Canvas, RectTansform, CanvasRenderer와 같이 요소들을 계산하고 그려주는 핵심모듈(C++ interop)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - UnityEngine.EventSystem : UI상호작용 관련모듈&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - UnityEngine.UI : UI요소 관련모듈&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 화면표시나 레이아웃 구성, 사용자인터랙션이 필요한 UI컴포넌트(게임오브젝트)들을 Canvas로 모아서 C++ 엔진측에서 받아서 처리하는 시스템이다. UIBehaviour를 상속받아 Custom UI 컴포넌트도 제작이 가능할거라 예상된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Canvas(C++)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메시를 구성하여 렌더링 명령을 생성(Re-batch, Batch build)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 배치된 UI 요소를 나타내는 메시를 생성하고, UI 요소가 변경되면 메시를 재생성하고, UI가 실제로 표시되도록 GPU에 draw call을 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Canvas 단위로 배칭(batching)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 하위 Graphic 요소들을 하나의 버퍼로 만들어서 GPU에게 draw call&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 그렇기 때문에 하위 요소들에 변경이 발생시 Canvas 단위로 batch가 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - UI의 정적요소와 동적요소에 대해 캔버스를 분할하여 최적화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Canvas가 리배칭이 필요한 Geometry를 포함하면 Canvas는 dirty flag 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DrawRawMesh()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - NestedCanvas 리스트가 있다면 재귀로 이터레이트 돌면서 각각 DrawRawMesh()&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Nested Canvas&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 캔버스가 캔버스를 소유 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 자식은 부모의 속성을 상속 여부 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 각 자식 캔버스간에는 재구성 영향을 미치지 않음 (부모의 크기가 변경되는 경우는 예외)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Dirty flag&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층구조 시스템에서 하위 요소들의 업데이트 필요여부 체크에 주로 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LayoutDirty, VericesDirty, MaterialDirty&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Dirty -&amp;gt; Rebuild&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Rebuild&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- C# Graphics 컴포넌트의 레이아웃과 메시가 다시 계산되는 행위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- dirty에 따라 계층구조 깊이별로 정렬, 메시 재빌드, Canvas Renderer의 Material 업데이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모든 enabled 요소들의 메시를 재생성 : 완전 투명(alpha가 0)이라도 생성함에 유의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Batching을 기준으로 Material 재생성&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Batch building (Canvas)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity의 그래픽 파이프라인으로 보낼 적절한 렌더링 명령을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;캔버스가 dirty로 표시될 때까지 캐시되고 재사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 멀티스레드 연산(코어가 적은 모바일 SoC와 코어가 많은 데스크톱간 성능이 매우 다름)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Batching&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 동일한 캔버스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 동일한 material 및 sprite에셋 (atlas)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 동일한 Z 깊이의 RectTransform&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 동일한 마스크 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## RectTransform(C++)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Transform 파생클래스 (Transform과 마찬가지로 계층구조)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 모든 GameObject 및 Component는 Transform이 기본포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;span style=&quot;color: #ee2323;&quot;&gt;모든 UI object는 RectTransform이 기본포함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층구조(Hierarchy)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - object의 변경이 계층적으로 영향&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Re-parenting 비용 (부모 변경에 주의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - `OnBeforeTransformParentChanged`, `OnTransformParentChanged`, `OnTransformChildrenChanged`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 최적화 팁&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 중요한건 UI의 내부동작을 이해하고 그에맞게 최적화해서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;매 프레임 업데이트시 비용을 최소화&lt;/b&gt;&lt;/u&gt;&lt;/span&gt; 시키는것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UI프로파일러 활용(&quot;Window &amp;gt; Analysis &amp;gt; Profiler &amp;gt; Profiler Modules &amp;gt; UI, UI Details&quot;) : batching 깨지는거 확인 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 정적 Canvas와 동적 Canvas를 분리 (갱신비용 vs drawcall 비용 사이에 상황에 맞는 최적화 필요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 편의상 Nested canvas 활용 가능. &lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;단, 부모는 정적이어야함&lt;/u&gt;&lt;/span&gt;(부모에 변경 발생시 nested canvas에 대해 갱신 발생)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층구조 depth 낮게 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Unity GameObject 및 UI는 모두 계층구조로 이루어짐 (Transform, RectTransform)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - dirty flag 계산 및 여러 처리시 계층이 깊고 복잡할수록 비용이 커짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Re-parenting 주의 (e.g. 런타임에 부모 옮겨다니는 행위)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `LayoutGroup`에서 파생되는 컴포넌트들 사용시 요소들이 동적인 경우 비용이 많이 발생하니 주의필요(e.g. 스크롤 내부에 GridLayoutGroup 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Event 처리가 필요없는 Canvas는 raycast같은 유저입력 관련 옵션 끄기(or 관련 컴포넌트 제거)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기타 자세한 사항들은 참조링크 참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679836655395&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;사용자 인터페이스(UI) 생성 - Unity 매뉴얼&quot; data-og-description=&quot;Unity는 Unity 에디터에서 제작된 애플리케이션과 Unity 에디터를 위한 사용자 인터페이스(UI)를 생성하는 데 사용되는 다음의 세 가지 UI 시스템을 제공합니다.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbfaIP/hyR36eSTzH/HrjhLdsZTPVk0JS06O9zh0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/UIToolkits.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbfaIP/hyR36eSTzH/HrjhLdsZTPVk0JS06O9zh0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;사용자 인터페이스(UI) 생성 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Unity는 Unity 에디터에서 제작된 애플리케이션과 Unity 에디터를 위한 사용자 인터페이스(UI)를 생성하는 데 사용되는 다음의 세 가지 UI 시스템을 제공합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3#6013273eedbc2a3c362f8adb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679822013291&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Nested Canvas Optimization - 2019.3 - Unity Learn&quot; data-og-description=&quot;As covered in previous tutorials, Unity UI components are contained within a Canvas. In previous tutorials, we&amp;rsquo;ve added elements to our UI using only one Canvas. In this tutorial, we&amp;rsquo;ll learn that Unity not only supports multiple Canvases within a Scen&quot; data-og-host=&quot;learn.unity.com&quot; data-og-source-url=&quot;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3#6013273eedbc2a3c362f8adb&quot; data-og-url=&quot;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hzG08/hyR2Lca78A/oDNpB7VEUWOWbC8LgNd6HK/img.png?width=208&amp;amp;height=66&amp;amp;face=0_0_208_66,https://scrap.kakaocdn.net/dn/VJI4f/hyR2Ma6xYz/K4I97hXH0NSDLqlxoqvYiK/img.png?width=208&amp;amp;height=66&amp;amp;face=0_0_208_66&quot;&gt;&lt;a href=&quot;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3#6013273eedbc2a3c362f8adb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.unity.com/tutorial/nested-canvas-optimization-2019-3#6013273eedbc2a3c362f8adb&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hzG08/hyR2Lca78A/oDNpB7VEUWOWbC8LgNd6HK/img.png?width=208&amp;amp;height=66&amp;amp;face=0_0_208_66,https://scrap.kakaocdn.net/dn/VJI4f/hyR2Ma6xYz/K4I97hXH0NSDLqlxoqvYiK/img.png?width=208&amp;amp;height=66&amp;amp;face=0_0_208_66');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nested Canvas Optimization - 2019.3 - Unity Learn&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;As covered in previous tutorials, Unity UI components are contained within a Canvas. In previous tutorials, we&amp;rsquo;ve added elements to our UI using only one Canvas. In this tutorial, we&amp;rsquo;ll learn that Unity not only supports multiple Canvases within a Scen&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.unity.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://create.unity.com/Unity-UI-optimization-tips&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://create.unity.com/Unity-UI-optimization-tips&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679822101161&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity&quot; data-og-description=&quot;&amp;nbsp;More resources Squeezing Unity: Tips for raising performance (section on Unity UI starts at 23:38). Best practices: Optimizing Unity UI Unity UI Docs UI Profiler Tutorials(tutorials in section &amp;ldquo;Live Training: Shop UI with Runtime Scroll Lists&amp;rdquo; are in&quot; data-og-host=&quot;create.unity.com&quot; data-og-source-url=&quot;https://create.unity.com/Unity-UI-optimization-tips&quot; data-og-url=&quot;https://create.unity.com/Unity-UI-optimization-tips&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hjz9z/hyR32QWy6z/SoONP3alwXpq9qm8SQ2P7k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://create.unity.com/Unity-UI-optimization-tips&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://create.unity.com/Unity-UI-optimization-tips&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hjz9z/hyR32QWy6z/SoONP3alwXpq9qm8SQ2P7k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;More resources Squeezing Unity: Tips for raising performance (section on Unity UI starts at 23:38). Best practices: Optimizing Unity UI Unity UI Docs UI Profiler Tutorials(tutorials in section &amp;ldquo;Live Training: Shop UI with Runtime Scroll Lists&amp;rdquo; are in&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;create.unity.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://unity.com/how-to/unity-ui-optimization-tips&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://unity.com/how-to/unity-ui-optimization-tips&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679822165566&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity UI optimization tips&quot; data-og-description=&quot;Discover how to create optimized Unity UI Elements for your content.&quot; data-og-host=&quot;unity.com&quot; data-og-source-url=&quot;https://unity.com/how-to/unity-ui-optimization-tips&quot; data-og-url=&quot;https://unity.com/how-to/unity-ui-optimization-tips&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mGPEp/hyR2T88ppX/L0eV3HEAmq80yMMyw9EzN1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://unity.com/how-to/unity-ui-optimization-tips&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://unity.com/how-to/unity-ui-optimization-tips&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mGPEp/hyR2T88ppX/L0eV3HEAmq80yMMyw9EzN1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity UI optimization tips&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Discover how to create optimized Unity UI Elements for your content.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;unity.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=1e2mSCS7o1A&quot;&gt;https://www.youtube.com/watch?v=1e2mSCS7o1A&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=1e2mSCS7o1A&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/UJvoT/hyR2RJhqnz/BEc7K8lYfusCqNoURYk3lK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/1e2mSCS7o1A&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;</description>
      <category>Game/개발</category>
      <category>Batching</category>
      <category>Canvas</category>
      <category>Dirty</category>
      <category>Graphic</category>
      <category>ugui</category>
      <category>UI</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/77</guid>
      <comments>https://progrunman.tistory.com/77#entry77comment</comments>
      <pubDate>Sat, 25 Mar 2023 17:03:23 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Addressables (v1.19.19 기준 - Editor 2021.3)</title>
      <link>https://progrunman.tistory.com/75</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressables system(주소지정가능 시스템)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 런타임에 자산을 load 및 release 하기위한 API와 content를 구성 및 패키징하는 tools 및 scripts 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주소로 Asset을 로드하는 쉬운 방법 제공 (기존 직접참조, Resources폴더, AssetBundle의 상위호환 추상화 계층)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 자산 호스팅 위치를 코드수정 없이 유연하게 변경 가능(local, CDN 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Dependency management : content를 반환하기 전에 종속된 모든 mesh, shader, animation 등이 로드됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Memory management : reference를 자동으로 계산하고 profiler를 통한 메모리 프로파일링 기능 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 내부적으로 Weak reference 사용?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로컬 및 원격 배포용 자산을 쉽고 효율적으로 packing할 수 있도록 지원 (AssetBundles를 기반으로함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8qaFl/btr5pzLsppx/KCX37lJbPSsh8mLGbfIhvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8qaFl/btr5pzLsppx/KCX37lJbPSsh8mLGbfIhvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8qaFl/btr5pzLsppx/KCX37lJbPSsh8mLGbfIhvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8qaFl%2Fbtr5pzLsppx%2FKCX37lJbPSsh8mLGbfIhvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;464&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;### Package dependencies&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1545&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uxi3x/btr5t8lCGxB/SOGpsIiCK6eCZUuqwiTmK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uxi3x/btr5t8lCGxB/SOGpsIiCK6eCZUuqwiTmK0/img.png&quot; data-alt=&quot;실제 닷넷 어셈블리 참조관계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uxi3x/btr5t8lCGxB/SOGpsIiCK6eCZUuqwiTmK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUxi3x%2Fbtr5t8lCGxB%2FSOGpsIiCK6eCZUuqwiTmK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1545&quot; height=&quot;216&quot; data-origin-width=&quot;1545&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실제 닷넷 어셈블리 참조관계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TPLFn/btr5t9ERpkZ/352lK2BHLAPWl6ReKOoWk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TPLFn/btr5t9ERpkZ/352lK2BHLAPWl6ReKOoWk0/img.png&quot; data-alt=&quot;Dependency Assemblies&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TPLFn/btr5t9ERpkZ/352lK2BHLAPWl6ReKOoWk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTPLFn%2Fbtr5t9ERpkZ%2F352lK2BHLAPWl6ReKOoWk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;181&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dependency Assemblies&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;### 주요 키워드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Address : asset의 위치ID (location identifier) 문자열&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Label : 비슷한 아이템들의 런타임 로딩을 위해 제공되는 추가적인 Addressable Asset ID&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `AssetReference` : addressable asset에 대한 참조. 직접참조처럼 작동하지만 초기화가 지연되는 객체. 요청시 로드할 수 있는 Addressable로 GUID를 저장. 참조가 설정되었는지 `RuntimeKeyIsValid()`를 통해 확인가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `IResourceLocation` : 자산 및 해당 종속성을 로드하기 위한 정보가 포함된 중간 객체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AddressableAssetData 디렉토리 : 프로젝트의 Assets디렉토리에 저장되는 Addressable Asset metadata&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Asset group : build-time processing에 사용할 수 있는 Addressable Asset 집합 (Asset group schema로 정의됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressable Asset 추가 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스펙터에서 Addressable 체크박스를 체크시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인스펙터에서 `AssetReference`타입의 필드에 에셋 연결시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Addressables Groups창(Window &amp;gt; Asset Management &amp;gt; Addressables &amp;gt; Group)에 드래그&amp;amp;드랍으로 추가시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Addressable로 체크한 프로젝트 폴더에 에셋 추가시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressable 자산 로드시 내부 수행순서&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 해당 key에 대한 resource 위치 조회 (`IResourceLocation` key 제외)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 종속성(dependencies) 목록 수집&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 필요한 모든 원격(remote) AssetBundles 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. AssetBundles를 메모리에 로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 작업(operation)의 Result객체를 로드된 객체로 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 작업의 Status를 업데이트하고 `Completed` 이벤트 리스너를 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 주요 API&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### GameObject&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `GameObject.Instantiate` : 게임오브젝트 인스턴스화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `GameObject.Destory` : `GameObject.Instantiate`(또는 Addressables가 아닌 방식)로 생성된 객체 인스턴스 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Addressables&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자산로드 (LoadAssetAsync)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조카운트 1 증가(매 호출시마다). 최초 1회 로드후 기존 `Instantiate`로 다수의 객체를 참조카운트 증가 없이 인스턴스화할때 유용. (e.g. Object pooling)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.LoadAssetAsync&amp;lt;TObject&amp;gt;` : &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#loading-a-single-asset&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;단일 에셋 로드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.LoadAssetsAsync&amp;lt;TObject&amp;gt;` : &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#loading-multiple-assets&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여러 에셋 로드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `releaseDependenciesOnFailure` : 로드 오류 처리 방법 지정. &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;true면 오류 발생시 성공적으로 로드된 작업 및 자산도 모두 중단 및 해제&lt;/span&gt;&lt;/u&gt;. false면 오류발생한 자산만 null로 해서 모든 작업 완료 후 반환.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.Release` : 작업(operation) 및 관련 리소스 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.Release&amp;lt;TObject&amp;gt;` : 에셋 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자산인스턴스화 (InstantiateAsync)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조카운트 1 증가(매 호출시마다). 내부적으로 LoadAssetAsync 사용 및 인스턴스화함. persistent scene에 올라가는 manager 인스턴스와 같은 예에서 활용가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.InstantiateAsync` : 단일객체 로드 및 인스턴스화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - instantiationParameters : 다수의 인스턴스화에 동일한 인자값 사용시 해당 구조체를 통해 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - trackHandle : 작업핸들을 Addressables시스템에서 추적할지 여부. true시 `Addressables.ReleaseInstance`를 통해 자산 릴리즈 가능(또는 종속된 Scene 언로드시 자동해제됨). &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;false시 작업핸들을 직접 관리 및 해제 필요&lt;/u&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.ReleaseInstance` : `Addressables.InstantiateAsync`로 생성된 객체를 해제(release)하고 제거(destroy)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Scene로드 (LoadSceneAsync)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.LoadSceneAsync` : Scene 로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `activateOnLoad` : 로드가 완료되는 즉시 Scene을 활성화할지, `SceneInstance.ActivateAsync` 호출시까지 대기할지 여부 (AsyncOperation.allowSceneActivation과 동일. 기본값은 true. false설정시 Scene이 활성화될때까지 다른 Addressable에셋 로드를 포함하여&amp;nbsp; `AsyncOperation` 대기열(queue)이 차단됨에 유의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.UnloadSceneAsync` : `Addressables.LoadSceneAsync`를 통해 로드된 Scene 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### AssetReference&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 Scene 등에 미리 직렬화 구성하고 런타임에 Lazy 로드가 필요한 경우 사용. `Addressables`의 LoadAssetAsync, InstantiateAsync, LoadSceneAsync 및 Release API 지원(static method와 instance의 method 차이)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `assetReference.LoadAssetAsync&amp;lt;TObject&amp;gt;`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `assetReference.ReleaseAsset`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `assetReference.InstantiateAsync`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `assetReference.ReleaseInstance`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `assetReference.LoadSceneAsync`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressables시스템의 &lt;/b&gt;&lt;b&gt;참조 카운트 &lt;/b&gt;(&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#instantiating-objects-from-addressables&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;, &lt;a href=&quot;https://forum.unity.com/threads/release-asset-vs-release-instance.540640/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;포럼&lt;/a&gt;)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Addressables시스템은 참조카운팅을 사용하여 자산이 사용중인지 여부를 결정하기 때문에 로드(load)하거나 인스턴스화(instantiate)하는 모든 자산은 사용이 끝나면 해제(release)해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.LoadAssetAsync` : 참조카운트 1 증가 (이후 `Object.Instantiate` 사용시 카운트는 그대로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 로드된 자산 또는 작업핸들을 해제시 참조카운트가 0이되면 관련된 자산이 언로드되고 모든 인스턴스화된 복사본도 해당 하위 자산을 잃게됨(e.g. Scene에 GameObject는 존재하지만 의존하는 mesh나 texture는 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `Addressables.InstantiateAsync` : 호출시마다 참조카운트 1 증가. 해제시 개별적으로 `Addressables.ReleaseInstance` 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Scene 언로드시 내부적으로 trackHandle되는 `InstantiateAsync`로 생성된 addressable 인스턴스들은 자동으로 해제됨&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `LoadAssetAsync`를 통해 로드된 객체(texture, material, game object, etc)는 자동해제되지 않으므로 수동으로 `Release` 호출 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 여러 자산 로드시 개별&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#correlating-loaded-assets-to-their-keys&quot;&gt;자산 로드 순서 설정&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 한 operation에서 여러 자산을 로드할때 개별 자산이 로드되는 순서는 key 목록 순서와 반드시 동일하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key 목록 순서와 개별 자산 로드 순서를 동기화하고 싶다면 `IResourceLocation`을 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 비동기 작업(Operations) 핸들링 &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/AddressableAssetsAsyncOperationHandle.html#event-based-operation-handling&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;방법&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### Coroutines and IEnumerator&lt;/h4&gt;
&lt;pre id=&quot;code_1679564492959&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithIEnumerator : MonoBehaviour
{
    public string address;
    AsyncOperationHandle&amp;lt;GameObject&amp;gt; opHandle;

    public IEnumerator Start() {
        opHandle = Addressables.LoadAssetAsync&amp;lt;GameObject&amp;gt;(address);

        if (!opHandle.IsDone)
            yield return opHandle;

        if (opHandle.Status == AsyncOperationStatus.Succeeded) {
            Instantiate(opHandle.Result, transform);
        } else {
            Addressables.Release(opHandle);
        }
    }

    void OnDestroy() {
        Addressables.Release(opHandle);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### C# Event&lt;/h4&gt;
&lt;pre id=&quot;code_1679564546224&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithEvent : MonoBehaviour
{
    public string address;
    AsyncOperationHandle&amp;lt;GameObject&amp;gt; opHandle;

    void Start() {
        opHandle = Addressables.LoadAssetAsync&amp;lt;GameObject&amp;gt;(address);
        opHandle.Completed += Operation_Completed;
    }

    private void Operation_Completed(AsyncOperationHandle&amp;lt;GameObject&amp;gt; obj) {

        if (obj.Status == AsyncOperationStatus.Succeeded) {
            Instantiate(obj.Result, transform);
        } else {
            Addressables.Release(obj);
        }
    }

    void OnDestroy() {
        Addressables.Release(opHandle);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;### C# Task (async/await)&lt;/h4&gt;
&lt;pre id=&quot;code_1679564587969&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithTask : MonoBehaviour
{
    // Label or address strings to load
    public List&amp;lt;string&amp;gt; keys = new List&amp;lt;string&amp;gt;() { &quot;characters&quot;, &quot;animals&quot; };

    // Operation handle used to load and release assets
    AsyncOperationHandle&amp;lt;IList&amp;lt;GameObject&amp;gt;&amp;gt; loadHandle;

    public async void Start() {
        loadHandle = Addressables.LoadAssetsAsync&amp;lt;GameObject&amp;gt;(
            keys, // Either a single key or a List of keys 
            addressable =&amp;gt; {
            // Called for every loaded asset
            Debug.Log(addressable.name);
            }, Addressables.MergeMode.Union, // How to combine multiple labels 
            false); // Whether to fail if any asset fails to load

        // Wait for the operation to finish in the background
        await loadHandle.Task;

        // Instantiate the results
        float x = 0, z = 0;
        foreach (var addressable in loadHandle.Result) {
            if (addressable != null) {
                Instantiate&amp;lt;GameObject&amp;gt;(addressable,
                        new Vector3(x++ * 2.0f, 0, z * 2.0f),
                        Quaternion.identity,
                        transform); // make child of this object

                if (x &amp;gt; 9) {
                    x = 0;
                    z++;
                }
            }
        }
    }

    private void OnDestroy() {
        Addressables.Release(loadHandle); 
        // Release all the loaded assets associated with loadHandle
        // Note that if you do not make loaded addressables a child of this object,
        // then you will need to devise another way of releasing the handle when
        // all the individual addressables are destroyed.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Task방식 사용시 `Task`클래스의 method들 사용가능&lt;/p&gt;
&lt;pre id=&quot;code_1679564988613&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Load the Prefabs
var prefabOpHandle = Addressables.LoadAssetsAsync&amp;lt;GameObject&amp;gt;(
    keys, null, Addressables.MergeMode.Union, false);

// Load a Scene additively
var sceneOpHandle 
    = Addressables.LoadSceneAsync(nextScene, 
        UnityEngine.SceneManagement.LoadSceneMode.Additive);

await System.Threading.Tasks.Task.WhenAll(prefabOpHandle.Task, sceneOpHandle.Task);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Scene에서의 Addressabes&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Addressable로 지정된 Scene의 내부 자산들은 암시적으로 종속성이 부여되고 content 빌드를 만들때 Scene과 동일한 AssetBundle에 자산을 압축. 단, non-Addressable이 아닌 개별적으로 Addressable로 지정된 자산들은 속한 그룹에 따라 고유한 AssetBundle에 포함됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- non-Addressable로 지정된 Scene 내부에 배치된 Addressable자산은 암시적 종속성이 되어 built-in 데이터에 해당 자산의 사본이 포함됨에 유의 (이 경우, &lt;u&gt;AssetReference를 통해 장면에 미리 구성하고 런타임에 Lazy로드하는 방법 사용가능&lt;/u&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 둘 이상의 위치에서 사용되는 암시적 종속성은 여러 AssetBundle 및 Scene 내부에 복제될 수 있으므로 Analyze툴의 Check Duplicate Bundle Dependecies rule을 통해 중복을 찾고 제거 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressable자산 Profiling&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Event Viewer 활성화 : &quot;Window &amp;gt; Asset Management &amp;gt; Addressables &amp;gt; Settings&quot;의 Send Profiler Events 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Event Viewer 사용 : &quot;&lt;span&gt;Window &amp;gt; Asset Management &amp;gt; Addressables &amp;gt;&lt;span&gt; Event Viewer&lt;/span&gt;&lt;/span&gt;&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Addressables시스템을 통한 Contents 업데이트&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crwRqh/btr5qtEc5uV/sky6IKXrGKCsOqsoNMLNNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crwRqh/btr5qtEc5uV/sky6IKXrGKCsOqsoNMLNNk/img.png&quot; data-alt=&quot;업데이트 크기를 줄이기 위한 workflow&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crwRqh/btr5qtEc5uV/sky6IKXrGKCsOqsoNMLNNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrwRqh%2Fbtr5qtEc5uV%2Fsky6IKXrGKCsOqsoNMLNNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;430&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;업데이트 크기를 줄이기 위한 workflow&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Addressables은 코드가 아닌 content만 배포가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 코드 변경시에는 새로운 Player build와 Content build가 필요 (e.g. prefab의 monobehaviour컴포넌트가 참조하는 script)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Script API 변경없이 내부로직 변경 assembly를 재배포하는 방법은 가능한지 확인필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 메모리 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그룹화 및 종속성 관리를 통해 적절한 시점에 관련된 자산들이 효율적으로 메모리를 사용하고, 필요한 시점에 메모리에서 내려가서 메모리 관리가 효율적으로 되도록 구성 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Load시 Release 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Instantiate시 ReleaseInstance필요 : &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#instantiate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - instantiationParameters : 다수의 인스턴스화에 동일한 인자값 사용시 해당 구조체를 통해 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - trackHandle : 작업핸들을 Addressables시스템에서 추적할지 여부. true시 `Addressables.ReleaseInstance`를 통해 자산 릴리즈 가능. false시 작업핸들참조를 직접 저장 및 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 기타&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로드시 `WaitForCompletion`은 실행 스레드를 차단하고 동기적으로 대기. Unity 2020.1 이하 버전에서는 상황에 따라 효율적일 수도 있으나 Unity 2020.2 이상에서는 비동기 방식과 성능차이가 미미하기에 사용 지양&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Google PAD(Play Asset Delivery)와 연동하려면 아래 링크를 참조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://docs.unity3d.com/Manual/play-asset-delivery.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PAD API 공식매뉴얼&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://docs.unity3d.com/ScriptReference/Android.AndroidAssetPacks.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PAD API 공식문서&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://github.com/Unity-Technologies/Addressables-Sample/tree/master/Advanced/Play%20Asset%20Delivery/Assets/PlayAssetDelivery&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Addressables-PAD 연동 공식샘플&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://github.com/google/play-unity-plugins&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Google 공식 Unity plug-in&lt;/a&gt; : 단, Addressables가 아닌 레거시 AssetBundles시스템을 사용함에 &lt;a href=&quot;https://forum.unity.com/threads/help-with-addressables-and-play-asset-delivery-pad.1305399/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;유의&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 처음에는 로직 script 부분까지 라이브업데이트가 가능할거라 기대했는데 해당부분 수정은 전체를 재빌드 및 배포해야한다. (&lt;a href=&quot;https://forum.unity.com/threads/how-to-update-newly-build-the-c-script-in-the-game.1408705/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;포럼공식답변&lt;/a&gt;) 라이브 업데이트하는 다른 방법이야 많겠지만 ScriptableObject와 같이 직렬화 자산으로 로직을 구성한다면 Addressables를 통한 라이브 업데이트도 가능할것 같다. 하지만 이경우 해킹에 취약해질것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity는 API들이 빠르게 변경되고 문서 업데이트가 느린 경우가 많아서 관련 문서나 영상들은 오래될수록 잘못되어 있는 경우가 많다. 항상 최신버전의 공식 문서나 공식 답변이 아닌 경우에는 의심하는것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기타 자세한 사용방법은 아래의 링크 참조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679551955563&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Addressables | Addressables | 1.19.19&quot; data-og-description=&quot;Addressables The Addressables system provides tools and scripts to organize and package content for your application and an API to load and release assets at runtime. When you make an asset &amp;quot;Addressable,&amp;quot; you can use that asset's address to load it from an&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&quot; data-og-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/index.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Addressables | Addressables | 1.19.19&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Addressables The Addressables system provides tools and scripts to organize and package content for your application and an API to load and release assets at runtime. When you make an asset &quot;Addressable,&quot; you can use that asset's address to load it from an&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679559200157&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Namespace UnityEngine.AddressableAssets
   | Addressables | 1.19.19&quot; data-og-description=&quot;Namespace UnityEngine.AddressableAssets Classes Entry point for Addressable API, this provides a simpler interface than using ResourceManager directly as it assumes string address type. Reference to an asset label. This class can be used in scripts as a fi&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&quot; data-og-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/Packages/com.unity.addressables@1.19/api/UnityEngine.AddressableAssets.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Namespace UnityEngine.AddressableAssets | Addressables | 1.19.19&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Namespace UnityEngine.AddressableAssets Classes Entry point for Addressable API, this provides a simpler interface than using ResourceManager directly as it assumes string address type. Reference to an asset label. This class can be used in scripts as a fi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.unity.com/kr/games/addressable-asset-system&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.unity.com/kr/games/addressable-asset-system&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679556248532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;어드레서블 에셋 시스템 | Unity Blog&quot; data-og-description=&quot;어드레서블의 주된 기능은 로드할 대상이 되는 에셋과 에셋이 로드되는 위치 및 방식을 분리하는 것입니다. 씬, 프리팹, 텍스트 에셋을 비롯한 모든 에셋을 어드레서블(위치 지정 가능)로 표시&quot; data-og-host=&quot;blog.unity.com&quot; data-og-source-url=&quot;https://blog.unity.com/kr/games/addressable-asset-system&quot; data-og-url=&quot;https://blog.unity.com/kr/games/addressable-asset-system&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xUNFh/hyR13wgnQg/qxW0Cf6ek7VpMhn2ARLD81/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://blog.unity.com/kr/games/addressable-asset-system&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.unity.com/kr/games/addressable-asset-system&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xUNFh/hyR13wgnQg/qxW0Cf6ek7VpMhn2ARLD81/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;어드레서블 에셋 시스템 | Unity Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;어드레서블의 주된 기능은 로드할 대상이 되는 에셋과 에셋이 로드되는 위치 및 방식을 분리하는 것입니다. 씬, 프리팹, 텍스트 에셋을 비롯한 모든 에셋을 어드레서블(위치 지정 가능)로 표시&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.unity.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://unity.com/how-to/simplify-your-content-management-addressables&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://unity.com/how-to/simplify-your-content-management-addressables&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679552428293&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Simplify your content management with Addressables&quot; data-og-description=&quot;Learn how the Addressable Asset System can simplify your content management at both edit and runtime so your game&amp;rsquo;s initial and updated releases are smoother and easier.&quot; data-og-host=&quot;unity.com&quot; data-og-source-url=&quot;https://unity.com/how-to/simplify-your-content-management-addressables&quot; data-og-url=&quot;https://unity.com/how-to/simplify-your-content-management-addressables&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0yKj5/hyR1VkEl0n/sdzvLwSWHVkm3KuFt3nIxK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://unity.com/how-to/simplify-your-content-management-addressables&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://unity.com/how-to/simplify-your-content-management-addressables&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0yKj5/hyR1VkEl0n/sdzvLwSWHVkm3KuFt3nIxK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Simplify your content management with Addressables&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn how the Addressable Asset System can simplify your content management at both edit and runtime so your game&amp;rsquo;s initial and updated releases are smoother and easier.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;unity.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/Unity-Technologies/Addressables-Sample&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679556480010&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Unity-Technologies/Addressables-Sample: Demo project using Addressables package&quot; data-og-description=&quot;Demo project using Addressables package. Contribute to Unity-Technologies/Addressables-Sample development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot; data-og-url=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1oRtu/hyR11yrsBe/KTjOqY8fTMStDKqhKH7KUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1oRtu/hyR11yrsBe/KTjOqY8fTMStDKqhKH7KUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Unity-Technologies/Addressables-Sample: Demo project using Addressables package&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Demo project using Addressables package. Contribute to Unity-Technologies/Addressables-Sample development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=EP3pvPAcHSo&quot;&gt;https://www.youtube.com/watch?v=EP3pvPAcHSo&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=EP3pvPAcHSo&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/K1ARM/hyR1U0PkDk/1lBTQcxdSmunibAKOCsk6K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/EP3pvPAcHSo&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://lunchballer.com/archives/1559&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://lunchballer.com/archives/1559&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679580217255&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Unity] Addressable과 메모리 관리&quot; data-og-description=&quot;Addressable을 이용하고 있다면 메모리 관리 측면에서 잘 사용하고 있는지 체크해 볼 필요가 있다. public IEnumerator Start() { opHandle = Addressables.LoadAssetAsync&amp;lt;GameObject&amp;gt;(key); yield return opHandle; if (opHandle.Status &quot; data-og-host=&quot;lunchballer.com&quot; data-og-source-url=&quot;https://lunchballer.com/archives/1559&quot; data-og-url=&quot;https://lunchballer.com/archives/1559&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAKyi0/hyR11ebtt7/flbwNqpTK1rkWbiXRacDe0/img.png?width=300&amp;amp;height=201&amp;amp;face=0_0_300_201,https://scrap.kakaocdn.net/dn/i5uo7/hyR18RUFjp/IboJufPmoLMf095kA7ihwk/img.png?width=760&amp;amp;height=273&amp;amp;face=0_0_760_273&quot;&gt;&lt;a href=&quot;https://lunchballer.com/archives/1559&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lunchballer.com/archives/1559&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAKyi0/hyR11ebtt7/flbwNqpTK1rkWbiXRacDe0/img.png?width=300&amp;amp;height=201&amp;amp;face=0_0_300_201,https://scrap.kakaocdn.net/dn/i5uo7/hyR18RUFjp/IboJufPmoLMf095kA7ihwk/img.png?width=760&amp;amp;height=273&amp;amp;face=0_0_760_273');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Unity] Addressable과 메모리 관리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Addressable을 이용하고 있다면 메모리 관리 측면에서 잘 사용하고 있는지 체크해 볼 필요가 있다. public IEnumerator Start() { opHandle = Addressables.LoadAssetAsync&amp;lt;GameObject&amp;gt;(key); yield return opHandle; if (opHandle.Status&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lunchballer.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Game/개발</category>
      <category>Addressables</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/75</guid>
      <comments>https://progrunman.tistory.com/75#entry75comment</comments>
      <pubDate>Thu, 23 Mar 2023 16:57:14 +0900</pubDate>
    </item>
    <item>
      <title>[VisualStudio] 코드 분석 규칙 설정 (필요없는 message 무시)</title>
      <link>https://progrunman.tistory.com/74</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 무시하고 싶은데 계속 에러리스트에 메시지가 떠서 짜증날때&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XJgps/btr5ozXK4g0/dvch5q4bmnlzMANRRAGOWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XJgps/btr5ozXK4g0/dvch5q4bmnlzMANRRAGOWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XJgps/btr5ozXK4g0/dvch5q4bmnlzMANRRAGOWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXJgps%2Fbtr5ozXK4g0%2Fdvch5q4bmnlzMANRRAGOWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;441&quot; height=&quot;176&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.editorconfig파일 설정을 통해 코드분석기에서 특정 스타일만 제외가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## .editorconfig 파일 예시&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1679473410165&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[*]
charset=utf-8

[*.cs]

# IDE0090: Use 'new(...)'
dotnet_diagnostic.IDE0090.severity = slient&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 파일을 프로젝트 루트폴더에 위치시켜서 적용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;slient의 경우 warning으로 표시되지 않지만 계속 모니터링된다.&lt;br /&gt;아예 제외하고 싶은 경우 none으로 설정해주면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679473491865&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코드 분석 규칙 구성 - .NET&quot; data-og-description=&quot;분석기 구성 파일에서 코드 분석 규칙을 구성하는 방법을 알아봅니다.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b2O2Rb/hyR0vtJBwb/tjwcYjQ3iakVE5QpYnqRsk/img.png?width=456&amp;amp;height=456&amp;amp;face=0_0_456_456&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/configuration-options&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b2O2Rb/hyR0vtJBwb/tjwcYjQ3iakVE5QpYnqRsk/img.png?width=456&amp;amp;height=456&amp;amp;face=0_0_456_456');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코드 분석 규칙 구성 - .NET&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;분석기 구성 파일에서 코드 분석 규칙을 구성하는 방법을 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules?view=vs-2022#severity-levels&quot;&gt;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules?view=vs-2022#severity-levels&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1679473511593&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코드 스타일 언어 규칙 - .NET&quot; data-og-description=&quot;C# 및 Visual Basic 언어 구문을 사용하기 위한 다양한 코드 스타일 규칙에 대해 알아봅니다.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules?view=vs-2022#severity-levels&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beBva7/hyR0lxT0uw/EmTVZUR6eNGIuIKUFi0Qs1/img.png?width=456&amp;amp;height=456&amp;amp;face=0_0_456_456&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules?view=vs-2022#severity-levels&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/style-rules/language-rules?view=vs-2022#severity-levels&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beBva7/hyR0lxT0uw/EmTVZUR6eNGIuIKUFi0Qs1/img.png?width=456&amp;amp;height=456&amp;amp;face=0_0_456_456');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코드 스타일 언어 규칙 - .NET&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;C# 및 Visual Basic 언어 구문을 사용하기 위한 다양한 코드 스타일 규칙에 대해 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/IDE, Tools, etc.</category>
      <category>.editorconfig</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/74</guid>
      <comments>https://progrunman.tistory.com/74#entry74comment</comments>
      <pubDate>Wed, 22 Mar 2023 17:28:17 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] LogType &amp;amp; StackTraceLogType (&amp;amp; Log Level)</title>
      <link>https://progrunman.tistory.com/70</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 플랫폼이나 프레임워크마다 서로 다른 로그 기준을 사용중이라 개발시 기준을 잡기위해 로그수준에 대해서는 어느정도 본인만의 기준을 잡을 필요성이 있다. RFC 5424를 기본으로 잡는다면 아래와 같이 대부분의 상황에 기준을 명확히 세우고 로그 작업을 진행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RFC 5424(syslog) : 시스템, 소프트웨어 등에서 발생하는 로그메시지 로깅을 위한 표준 프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 개인적인 판단으로 적절하게 심각도 수준을 배치시켜 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 비어있는 영역은 개별적인 판단으로 Warning 또는 Log에 편입시키면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2606&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5JCDl/btr4AVn3EML/ShSCle9csmb6ak8np4zgLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5JCDl/btr4AVn3EML/ShSCle9csmb6ak8np4zgLk/img.png&quot; data-alt=&quot;주요 Logging 시스템 로그레벨 비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5JCDl/btr4AVn3EML/ShSCle9csmb6ak8np4zgLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5JCDl%2Fbtr4AVn3EML%2FShSCle9csmb6ak8np4zgLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2606&quot; height=&quot;518&quot; data-origin-width=&quot;2606&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주요 Logging 시스템 로그레벨 비교&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity의 Exception의 경우 Error수준인데 순서가 마지막에 있는걸보면 LogType은 심각도 수준 순서가 아니란걸 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Unity의 로깅 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 Exception은 동작 중 발생하는 예상하지 못한 예외상황을 나타내며 로직에서 상황을 캐치하여 처리하기를 기대하는 반면에 Error는 잠재적으로 복구하거나 해결기 힘든 심각한 문제를 나타내는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서는 StackTrace정보를 통해 개발자가 버그를 수정하길 원해서인지 Exception이 가장 낮은수준(상세 메시지)에 위치하고, Error가 가장 높은수준에 위치한다. (&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;Assert의 경우 Unity 내부 오류도 나타냄&lt;/u&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 보통 Logger를 하위수준으로 세팅시 상위수준까지 커버하도록 하는데 Unity에서는 특이하게도 LogType 각각에 대해 3단계로 수준(Log level)을 별도로 설정하도록 되어있다. 닷넷 모노를 사용하는 엔진이라 관리 영역과 비관리 영역에 대한 세밀한 로깅 컨트롤을 위해서 제공하는듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- None : 스택추적 안함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ScriptOnly : managed 영역만 스택추적 및 로깅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Full : native 영역까지 스택추적 및 로깅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 원하는 LogType에 대해서만 설정된 스택추적 수준으로 로깅하도록 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정은 Project Settings 또는 스크립트 상에서 세팅 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byUYFP/btr4vi3Z7HR/uKoVJLz9S8WO3x0VmIimWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byUYFP/btr4vi3Z7HR/uKoVJLz9S8WO3x0VmIimWk/img.png&quot; data-alt=&quot;Player Settings의 Logging시 Stack Trace 수준 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byUYFP/btr4vi3Z7HR/uKoVJLz9S8WO3x0VmIimWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyUYFP%2Fbtr4vi3Z7HR%2FuKoVJLz9S8WO3x0VmIimWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;142&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Player Settings의 Logging시 Stack Trace 수준 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1679069091745&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PlayerSettings.SetStackTraceLogType(LogType logType, StackTraceLogType stackTraceType);
// or
Application.SetStackTraceLogType(LogType logType, StackTraceLogType stackTraceType);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PlayerSettings를 통해 설정시 UI를 통해 설정하는것과 동일하고, 암시적으로 `Application.SetStackTraceLogType`을 호출한다. 기본설정은 ScriptOnly이다. 게임 런칭시에는 성능향상을 위해 None을 기본으로 하고 필요한 부분만 적절한 세팅이 필요해 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본로거인 `Debug.Log` (내부적으로 default logger인 `Debug.unityLogger`를 사용)를 사용해도 되지만 다목적 엔진이라 로깅 범위가 넓다. 명확한 기준을 세우고 기본 로거를 커스터마이즈시 개발에 더 효율적일 것으로 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity에서 로깅과 관련된 API : Logger, ILogger, Debug.unityLogger, Application.RegisterLogCallback&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Editor로그와 Player로그 파일 저장 위치는 &lt;a href=&quot;https://docs.unity3d.com/kr/2021.3/Manual/LogFiles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서 참조&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679035604872&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;RFC 5424: The Syslog Protocol&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.rfc-editor.org&quot; data-og-source-url=&quot;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&quot; data-og-url=&quot;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.rfc-editor.org/rfc/rfc5424#section-6.2.1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RFC 5424: The Syslog Protocol&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.rfc-editor.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679039241011&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Level (Java Platform SE 7 )&quot; data-og-description=&quot;FINE is a message level providing tracing information. All of FINE, FINER, and FINEST are intended for relatively detailed tracing. The exact meaning of the three levels will vary between subsystems, but in general, FINEST should be used for the most volum&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Level (Java Platform SE 7 )&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;FINE is a message level providing tracing information. All of FINE, FINER, and FINEST are intended for relatively detailed tracing. The exact meaning of the three levels will vary between subsystems, but in general, FINEST should be used for the most volum&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679039165581&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Log4j &amp;ndash; Custom Log Levels&quot; data-og-description=&quot;Copyright &amp;copy; 1999-2023 The Apache Software Foundation. All Rights Reserved. Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, and the Apache Logging project logo are trademarks of The Apache Software Foundation.&quot; data-og-host=&quot;logging.apache.org&quot; data-og-source-url=&quot;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&quot; data-og-url=&quot;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://logging.apache.org/log4j/2.x/manual/customloglevels.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Log4j &amp;ndash; Custom Log Levels&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Copyright &amp;copy; 1999-2023 The Apache Software Foundation. All Rights Reserved. Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, and the Apache Logging project logo are trademarks of The Apache Software Foundation.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;logging.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&quot;&gt;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1679030344645&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;로깅 이해 &amp;nbsp;|&amp;nbsp; Android 오픈소스 프로젝트 &amp;nbsp;|&amp;nbsp; Android Open Source Project&quot; data-og-description=&quot;로깅 이해 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 문서에서는 로그 표준, 수준 가이드라인, 클래스, 목적, 다중 스택 근사를 포함하여 로깅 프로&quot; data-og-host=&quot;source.android.com&quot; data-og-source-url=&quot;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&quot; data-og-url=&quot;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://source.android.com/docs/core/tests/debug/understanding-logging?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;로깅 이해 &amp;nbsp;|&amp;nbsp; Android 오픈소스 프로젝트 &amp;nbsp;|&amp;nbsp; Android Open Source Project&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;로깅 이해 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 문서에서는 로그 표준, 수준 가이드라인, 클래스, 목적, 다중 스택 근사를 포함하여 로깅 프로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;source.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/os/logging&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/os/logging&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679037726493&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Logging | Apple Developer Documentation&quot; data-og-description=&quot;Capture telemetry from your app for debugging and performance analysis using the unified logging system.&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/documentation/os/logging&quot; data-og-url=&quot;https://docs.developer.apple.com/documentation/os/logging&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0gf91/hyRXpTBUqn/yHKgQaS6N1aMzcsbmGmDj0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bEglV9/hyRXEDeDJN/nXAAzpxLKfY18WkO237gMK/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/os/logging&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/documentation/os/logging&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0gf91/hyRXpTBUqn/yHKgQaS6N1aMzcsbmGmDj0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bEglV9/hyRXEDeDJN/nXAAzpxLKfY18WkO237gMK/img.jpg?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Logging | Apple Developer Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Capture telemetry from your app for debugging and performance analysis using the unified logging system.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679035961077&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LogType - Unity 스크립팅 API&quot; data-og-description=&quot;The type of the log message in Debug.logger.Log or delegate registered with Application.RegisterLogCallback.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/LogType.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LogType - Unity 스크립팅 API&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The type of the log message in Debug.logger.Log or delegate registered with Application.RegisterLogCallback.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679035944133&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Debug-Log - Unity 스크립팅 API&quot; data-og-description=&quot;Logs message to the Unity Console.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/530/ScriptReference/Debug.Log.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Debug-Log - Unity 스크립팅 API&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Logs message to the Unity Console.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679035886742&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;로그 파일 - Unity 매뉴얼&quot; data-og-description=&quot;개발 시 사용자가 빌드한 웹 플레이어, 타겟 디바이스 또는 에디터의 로그에서 정보를 얻고 싶은 경우가 있을 수 있습니다. 일반적으로 문제가 발생하면 파일을 보고 어디에서 ​​문제가 발생&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SFSvx/hyRXwZsDrz/3hDl8TG1L44Umfort1Bs2k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/560/Manual/LogFiles.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SFSvx/hyRXwZsDrz/3hDl8TG1L44Umfort1Bs2k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;로그 파일 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개발 시 사용자가 빌드한 웹 플레이어, 타겟 디바이스 또는 에디터의 로그에서 정보를 얻고 싶은 경우가 있을 수 있습니다. 일반적으로 문제가 발생하면 파일을 보고 어디에서 ​​문제가 발생&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Programming/Languages</category>
      <category>Debug</category>
      <category>log</category>
      <category>Logger</category>
      <category>logging</category>
      <category>loglevel</category>
      <category>LogType</category>
      <category>StackTraceLogType</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/70</guid>
      <comments>https://progrunman.tistory.com/70#entry70comment</comments>
      <pubDate>Fri, 17 Mar 2023 13:41:29 +0900</pubDate>
    </item>
    <item>
      <title>[C#] const &amp;amp; readonly (컴파일타임 상수 &amp;amp; 런타임 상수)</title>
      <link>https://progrunman.tistory.com/68</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#은 두가지 상수형을 제공한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 특성에 맞게 올바르게 사용해야한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## const&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678966526706&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public const int MILLENNIUM = 2000;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- compile-time 상수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컴파일시에 const 상수형 변수가 사용되는 위치(code)가 &lt;b&gt;실질적인 값으로 치환&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;readonly에 비해 다소 빠르지만 유연성이 떨어짐&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;u&gt;변수 선언시에만&lt;/u&gt; 초기화 가능 (생성자를 통해 동적 초기화 불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 내장자료형(정수형, 실수형 등)이나 enum, string에 대해서만 선언 가능. 즉, &lt;u&gt;숫자와 문자열에 한해서만&lt;/u&gt; 사용가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 기본적으로 static이므로 동일타입의 &lt;u&gt;여러 인스턴스에서도 항상 같은 값&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;서비스 기간동안 불변값&lt;/b&gt;&lt;/span&gt;이어야하고 피치못할 변경 발생시 참조하는 모든 어셈블리 재컴파일 후 재배포 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## readonly&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678966580526&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static readonly int THIS_YEAR = 2023;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- runtime 상수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컴파일시에 readonly 상수형 변수가 사용되는 위치가 &lt;b&gt;참조값으로 치환&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;const에 비해 다소 느리지만 유연성이 좋음&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;u&gt;변수 선언시 또는 생성자에서&lt;/u&gt; 초기화 가능 (생성자 호출이 완료된 이후에는 초기화 불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;u&gt;어떤 자료형으로도&lt;/u&gt; 선언 가능 (대표적으로 1회만 초기화 되어야 하는 singleton의 private instance 멤버변수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 동일타입의 &lt;u&gt;인스턴스별로 서로 다른 값&lt;/u&gt; (static 선언을 통해 &lt;u&gt;같은 값으로도 설정 가능&lt;/u&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;초기화 이후 프로그램 동작동안 불변값&lt;/span&gt;&lt;/b&gt;. 변경 발생시 해당 변수가 선언된 어셈블리만 재컴파일 및 배포가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- readonly 대신 const를 사용했을때 유일한 장점은 수행성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- const는 수행성능이 매우 중요하고, 상수의 값이 절대로 바뀌지 않는 경우에 한해서만 사용하는것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 즉 &lt;b&gt;평소엔 readonly를 주로 사용하고 const는 필요하다고 판단되는 시점에만 readonly를 대체해서 사용&lt;/b&gt;하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 책 Effective C# (Bill Wagner)&lt;/p&gt;</description>
      <category>Programming/Languages</category>
      <category>const</category>
      <category>Constants</category>
      <category>readonly</category>
      <category>상수</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/68</guid>
      <comments>https://progrunman.tistory.com/68#entry68comment</comments>
      <pubDate>Thu, 16 Mar 2023 21:23:50 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Assembly Definition (어셈블리 정의)</title>
      <link>https://progrunman.tistory.com/66</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 어셈블리 정의 인스펙터&amp;nbsp;&lt;a style=&quot;color: #3db39e;&quot; href=&quot;https://docs.unity3d.com/kr/current/Manual/class-AssemblyDefinitionImporter.html&quot;&gt;속성&lt;/a&gt;(*.asmdef 에셋의 직렬화 정보)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- name : 어셈블리 이름(unique 해야함)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### General&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Allow 'unsafe' Code : C# `unsafe`키워드를 사용중인지 Unity 컴파일러에게 알림(결과적으로 &quot;/unsafe&quot; 옵션 전달)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Auto Referenced :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;predefined assemblies&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(e.g.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot;&gt;Assembly-CSharp.dll&lt;/a&gt;, etc)들이 해당 어셈블리를 자동참조 하는지 여부&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- No Engine References : Unity Engine 어셈블리 참조 여부&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Override References : precompiled assemblies(외부에서 컴파일된 plug-in)를 자동참조 하지않고 수동참조하도록 오버라이드&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 기본적으로 어셈블리 정의를 사용해 생성된 프로젝트의 모든 어셈블리는 precompiled된 모든 어셈블리를 자동참조하며, 이 경우 precompiled 어셈블리 중 하나만 업데이트해도 Unity가 모든 어셈블리를 재컴파일하는 오버헤드 발생&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 오버헤드 방지를 위해 참조방식을 override하여 실제로 사용하는 precompiled어셈블리만 참조하도록 할 수 있음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 설정시 현재 Build Settings에 설정된 플랫폼에 호환되는 precompiled 어셈블리만 나타나기 때문에 각 플랫폼 마다 설정필요(*.asmdef 에셋파일에 저장됨)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Root Namespace&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 해당 어셈블리정의의 스크립트 생성시 사용되는 기본 namespace (e.g. script template의 `#ROOTNAMESPACEBEGIN#`)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 스크립트 생성시 우선순위 : Assembly Root Namespace &amp;gt; Project Settings Root Namespace&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### Define Constraints&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 조건부 어셈블리 포함 정의 : 스크립트 수준이 아닌 어셈블리 수준에서 작동&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 해당 제약 정의에 충족하는 경우에만 컴파일 후 참조 및 빌드에 포함됨&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- `!`, `||` 연산자 사용 가능&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### Assembly Definition References&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Use GUIDs : 유니티 메타데이터(*.meta)를 통한 GUID 사용. 종속성(참조) 관계없이 해당 어셈블리 name 변경 가능하지만 파일이동, 메타데이터 삭제 등으로 꼬이는 경우 GUID 초기화 필요&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Assembly Definition References : 어셈블리정의 참조설정을 통한 어셈블리간 종속성 정의&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### Assembly References&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- precomiled어셈블리 참조설정을 통한 종속성 정의&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### Platforms&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 해당 어셈블리의 플랫폼 호환성 설정&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 설정된 플래폼에서만 해당 어셈블리를 컴파일 또는 참조&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;### Version Defines&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 특정 Unity버전 또는 package버전에 따라 컴파일 및 참조제약 정의&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 컴파일 순서 4단계&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;각 컴파일은 프로젝트 루트에 있는 자동생성된 C# 프로젝트 파일(.csproj)을 사용해 단계적으로 진행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유니티가 자동설정한 컴파일 옵션은 해당 파일을 통해 확인 가능하다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Phase 1 : Assembly-CSharp-firstpass : 최상위 특수폴더 런타임 스크립트(e.g. Plugins)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Phase 2 : &lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;Assembly-CSharp-Editor-firstpass : 최상위 특수폴더내의 Editor폴더의 에디터 스크립트&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;- Phase 3 : &lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;Assembly-CSharp : Editor 폴더에 있지 않은 기타 모든 스크립트&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;- Phase 4 : &lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;Assembly-CSharp-Editor : 나머지 모든 Editor 폴더에 있는 스크립트&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 컴파일 및 빌드 오버헤드를 줄이기 위해 필수적 선택&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 직렬화 속성을 통해 predefined, definition, precomiled 어셈블리간의 종속성 세팅&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 적절한 Symbol 세팅을 통한 조건부 컴파일 및 빌드 세팅&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;- 프로젝트 구조상 하위폴더로 이동 불가능한 스크립트들은 Assembly Definition Reference 적절히 활용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 난독화 및 보안관련 모듈 적용시 효율성에 대해서는 차후 검토 필요&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678947391693&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;어셈블리 정의 - Unity 매뉴얼&quot; data-og-description=&quot;어셈블리 정의 및 어셈블리 레퍼런스는 스크립트를 어셈블리로 구성할 수 있는 에셋입니다.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CxUqq/hyRWoH6wiQ/EUsTVCURO5Yqy8UVUkMtw0/img.png?width=789&amp;amp;height=320&amp;amp;face=0_0_789_320&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompilationAssemblyDefinitionFiles.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CxUqq/hyRWoH6wiQ/EUsTVCURO5Yqy8UVUkMtw0/img.png?width=789&amp;amp;height=320&amp;amp;face=0_0_789_320');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리 정의 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리 정의 및 어셈블리 레퍼런스는 스크립트를 어셈블리로 구성할 수 있는 에셋입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678951918118&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;특수 폴더와 스크립트 컴파일 순서 - Unity 매뉴얼&quot; data-og-description=&quot;Unity는 몇몇 프로젝트 폴더 이름을 콘텐츠가 특수한 목적을 가지고 있음을 표시하기 위한 목적으로 따로 보관합니다. 이들 중 일부는 스크립트 컴파일 순서에 영향을 줍니다. 폴더명은 다음과 &quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d9l21s/hyRWzJIRFK/2855LzIEgoEDSj8LBwG3Pk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/ScriptCompileOrderFolders.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d9l21s/hyRWzJIRFK/2855LzIEgoEDSj8LBwG3Pk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;특수 폴더와 스크립트 컴파일 순서 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Unity는 몇몇 프로젝트 폴더 이름을 콘텐츠가 특수한 목적을 가지고 있음을 표시하기 위한 목적으로 따로 보관합니다. 이들 중 일부는 스크립트 컴파일 순서에 영향을 줍니다. 폴더명은 다음과&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Game/개발</category>
      <category>Assembly Definition</category>
      <category>어셈블리정의</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/66</guid>
      <comments>https://progrunman.tistory.com/66#entry66comment</comments>
      <pubDate>Thu, 16 Mar 2023 15:15:49 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Preprocessor directives &amp;amp; Conditional Compilation (전처리기 지시문 및 조건부 컴파일)</title>
      <link>https://progrunman.tistory.com/65</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 할때 보통 전처리기 지시문(Preprocessor Directives)을 사용해서 디버깅용 개발빌드와 릴리즈용 배포빌드를 분리하는게 보편적이다. Unity에서도 이런 전처리기 지시문을 통한 조건부 컴파일을 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(참고 : UNITY_EDITOR는 유니티 에디터를 통해 컴파일시에만 정의됨)&lt;/p&gt;
&lt;pre id=&quot;code_1678854714417&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void ConditionalMethod()
{
#if UNITY_EDITOR
    Debug.Log(&quot;UNITY_EDITOR 정의시에만 해당 메서드가 산출물에 포함됨&quot;);
#endif
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티 &lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;에도 나와있듯이 특정 method 호출부도 조건부컴파일 하고 싶을때는 C# `Conditional`어트리뷰트를 사용해 아래와 같이 더 깔끔하게 사용이 가능하다. 단, 몇가지 제약사항이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- void를 리턴하는 method만 가능 (class는 `System.Attribute`를 상속받은 특성 class만 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;- 조건 연산 미지원 : `#if`, `#define`, `#endif`를 통해 조건을 정의해서 회피가능&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - PlayerSettings를 통해 세팅 가능하고 파일 상단 #define은 에디터 플레이모드에 적용안됨(`InitializeOnLoad`, `InitializeOnLoadMethod`에 조건부컴파일로 분기 및 define symbol을 세팅에 밀어넣는 방법으로 설정가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;`Start()`, `Update()`등과 같은 Unity엔진 callback method에는 적용안됨에 유의&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678863957770&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void CallerLogic()
{
    ConditionalMethod(); // UNITY_EDITOR 정의시에만 해당 코드가 산출물(어셈블리)에 포함됨
}

[Conditional(&quot;UNITY_EDITOR&quot;)]
public static void ConditionalMethod()
{
    Debug.Log(&quot;해당 메서드 및 코드는 항상 산출물(어셈블리)에 포함됨&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 산출물 용량을 눈꼽만큼이라도 줄이고 싶다면 아래와 같이 조합도 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1678865159439&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void CallerLogic()
{
    ConditionalMethod(); // UNITY_EDITOR 정의시에만 해당 코드가 산출물(어셈블리)에 포함됨
}

[Conditional(&quot;UNITY_EDITOR&quot;)]
public static void ConditionalMethod()
{
#if UNITY_EDITOR
    Debug.Log(&quot;UNITY_EDITOR 정의시에만 해당 코드가 산출물(어셈블리)에 포함됨&quot;);
#endif
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리정의된 Symbol외에 사용자정의가 필요할때는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;- 스크립트 파일 상단에서 `#define`을 통해 정의해서 사용하거나&amp;nbsp;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Unity 직렬화 및 compilation system에 따라 프로젝트파일(.csproj)에 추가되는 시점 문제로 스크립트 상단에 #define을 정의해도 edit time에 c# 프로젝트파일에는 심볼이 추가 안됨에 유의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Assets폴더에 .rsp 파일을 통해 심볼 추가 (비추천)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 유니티 에디터의 &quot;Projects Settings &amp;gt; Player &amp;gt; Script Compilation &amp;gt; Scripting Define Symbols&quot;에서도 정의 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서 미리 정의되어 있는 Symbol들은 공식문서에서 확인 가능하며 주로 사용되는 것들은 다음과 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 디버그/릴리즈 빌드 구분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DEVELOPMENT_BUILD : 개발용 빌드로 설정되어 &lt;u&gt;&lt;b&gt;런타임 플레이어에서 실행될때&lt;/b&gt;&lt;/u&gt; 정의됨(&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Playmode가 아님에 유의&lt;/b&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 해당 symbol 정의 = Build Settings의 Development Build 체크 = `Debug.isDebugBuild = true`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DEBUG : C#용 predefined symbol이며, 유니티 에디터 빌드 또는 Development Build시 정의됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티 에디터에서 디버그/릴리즈 빌드설정은 &quot;Build Settings &amp;gt; Development Build&quot; 옵션을 통해 활성/비활성 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 플랫폼에서 개발하다 넘어온 개발자들은 특히 `DEVELOPMENT_BUILD`, `DEBUG` 사용시 예상처럼 동작하지 않는것에 의아해할 수 있는데 유니티 에디터의 Serialization/Compilation 동작 관계상 네이밍을 모호하게 해놓은것 뿐이므로 주의가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티 에디터 구조상 에디터상에서 호출되는 C# 스크립트는 항상 디버그 모드로 동작하므로 C# symbol인 `&lt;b&gt;DEBUG&lt;/b&gt;`는 &lt;u&gt;에디터상에서 항상 defined 상태&lt;/u&gt;이며, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;u&gt;기기 런타임 동작시에만 디버그/릴리즈 적용&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;이 된다고 이해하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;마찬가지로 `&lt;b&gt;DEVELOPMENT_BUILD&lt;/b&gt;`가 의미하는바도 기기 런타임 동작에 사용되는 빌드에 디버그/릴리즈 적용이지만 &lt;u&gt;에디터 상에서는 항상 non-defined 상태&lt;/u&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;즉, 아래 두가지는 동일한 결과를 나타낸다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678855840509&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#if (UNITY_EDITOR || DEVELOPMENT_BUILD)
    // 실제 배포버전인 릴리즈 빌드(기기 런타임)에서만 무시
#endif

#if DEBUG
    // 실제 배포버전인 릴리즈 빌드(기기 런타임)에서만 무시
#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두가지 동작이 동일하지만 유니티 공식문서에 C# `DEBUG` 사용에 대한 이야기가 없고, 차후 유니티 에디터의 C# 스크립트 연동 동작이 어떻게 수정될지 모르므로 &lt;b&gt;`DEVELOPMENT_BUILD`와 `UNITY_EDITOR`를 같이 사용하는 방식이 더 안전해보인다&lt;/b&gt;. 다만, 왜인지 `DEVELOPMENT_BUILD`는 2021.3 기준으로 VS2022 Intellisense에 나타나지 않으나 정상동작함을 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적인 추천은 따로 사용자정의 symbol을 사용하는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리정의된 symbol들은 3rd-party나 기타 라이브러리에서 사용중일수도 있어서 사용자정의 symbol을 사용해 on/off 하는것이 휴먼에러만 없다면 가장 깔끔하다. 사용자정의 symbol은 미리정의된 symbol과의 충돌을 방지하기 위해 prefix를 추가하는것이 좋다. (e.g. COMPANY_DEBUG, COMPANY_QA, COMPANY_RELEASE)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 사용자정의 symbol을 사용해서 wrapper util을 작성해 놓으면 몸이 편해진다. (e.g. Logging 관련 wrapper util class)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 플랫폼 구분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_EDITOR : 유니티 에디터에서 동작할때 정의됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_STANDALONE : 스탠드얼론 플랫폼(Max OS X, Windows, Linux) 전용 컴파일링/실행 코드용 스크립팅 symbol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_ANDROID : Android 플랫폼용 스크립팅 symbol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_IOS : iOS 플랫폼용 컴파일링/실행 코드용 스크립팅 symbol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 유니티 에디터 버전 구분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_2021 : 모든 2021.Y.Z 유니티 에디터를 뜻하는 symbol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_2021_3_OR_NEWER : 특정 버전 이상의 유니티 에디터를 뜻하는 symbol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Unit Test (Test Framework)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- UNITY_INCLUDE_TESTS : 해당 어셈블리가 유닛테스트를 포함함을 정의 (릴리즈 빌드에서 제외)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &quot;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot;&gt;&lt;a href=&quot;https://forum.unity.com/threads/info-on-unity_include_tests-define.890095/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The purpose&lt;/a&gt; of UNITY_INCLUDE_TESTS is to signal whether an assembly contains tests. The constraint is added to the asmdef for the test assembly automatically when it is created. It is used by the build system to ensure that your tests does not get included in the player build, when building normally.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외 기타 symbol들을 필요에 따라 사용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## 추가사항 (개인적인 결론도출)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에 디버그/릴리즈 관련된 항목 정리하자면 아래와 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VS2022 솔루션 구성 : 스크립트는 Unity에디터에서 컴파일되므로 IDE 솔루션 구성을 Debug/Release로 설정하는것은 &lt;u&gt;컴파일 및 빌드산출물에 영향을 주지않음&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity Editor 모드 : 에디터 하단 상태바 우측에서 전환 가능한 Debug/Release모드. 에디터 직렬화 compilation 수행시 스크립트에 대한 Debug/Release 구성여부와 관련이 있고 &lt;u&gt;에디터의 작동모드이며&amp;nbsp;빌드산출물에 영향을 주지않음&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로젝트세팅의 C++ Compiler Configuration : &lt;u&gt;IL2CPP 산출물의 Debug/Release 구성여부. &lt;b&gt;런칭시 Release로 전환&lt;/b&gt;필요&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 빌드세팅의 Development Build : &lt;u&gt;빌드 산출물의 Debug/Release 구성여부. &lt;b&gt;런칭시 체크해제&lt;/b&gt; 필요&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;----------------------------------------------------------------------------------------------------------------------------------------------&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;## 주의&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티 에디터 2021.3 기준으로 Development Build 세팅 전환시 Debug.isDebugBuild 값에 버그가 있는듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체크 &amp;lt;-&amp;gt; 체크해제간 전환 후 빌드시 Clean Build를 하지않으면 Development Build가 체크상태임에도 Debug.isDebugBuild속성에 true가 아닌 false로 세팅되어있는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;유니티 디버그/릴리즈 빌드 전환시 항상 Clean빌드를 해주는것이 안전&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;할것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;----------------------------------------------------------------------------------------------------------------------------------------------&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## References&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;- 책 Effective C# (Bill Wagner)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot;&gt;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679055426163&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;조건부 컴파일 - Unity 매뉴얼&quot; data-og-description=&quot;Unity의 C# 언어 지원에는 지시문의 사용이 포함되어 있어서 특정 스크립팅 심볼이 정의됨 또는 정의되지 않음에 따라 컴파일에서 코드를 선택적으로 포함하거나 제외할 수 있습니다.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/teELR/hyRXsC4MiJ/5kCI9XVKJUHTZ5p7Itx400/img.png?width=640&amp;amp;height=603&amp;amp;face=0_0_640_603&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/PlatformDependentCompilation.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/teELR/hyRXsC4MiJ/5kCI9XVKJUHTZ5p7Itx400/img.png?width=640&amp;amp;height=603&amp;amp;face=0_0_640_603');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;조건부 컴파일 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Unity의 C# 언어 지원에는 지시문의 사용이 포함되어 있어서 특정 스크립팅 심볼이 정의됨 또는 정의되지 않음에 따라 컴파일에서 코드를 선택적으로 포함하거나 제외할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678867028413&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity - Scripting API: Debug.isDebugBuild&quot; data-og-description=&quot;If it is checked isDebugBuild will be true. In the editor isDebugBuild always returns true. It is recommended to remove all calls to Debug.Log when deploying a game, this way you can easily deploy beta builds with debug prints and final builds without.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&quot; data-og-url=&quot;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfim27/hyRU6870pt/21PB3atbL6IDnROEfsWvHK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/ScriptReference/Debug-isDebugBuild.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfim27/hyRU6870pt/21PB3atbL6IDnROEfsWvHK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity - Scripting API: Debug.isDebugBuild&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;If it is checked isDebugBuild will be true. In the editor isDebugBuild always returns true. It is recommended to remove all calls to Debug.Log when deploying a game, this way you can easily deploy beta builds with debug prints and final builds without.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678853496685&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;C# preprocessor directives&quot; data-og-description=&quot;Learn the different C# preprocessor directives that control conditional compilation, warnings, nullable analysis, and more&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&quot; data-og-url=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/n4HBM/hyRVihll5K/2iZdKKEwZQIlkk4kGRxTdK/img.png?width=64&amp;amp;height=64&amp;amp;face=0_0_64_64&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/n4HBM/hyRVihll5K/2iZdKKEwZQIlkk4kGRxTdK/img.png?width=64&amp;amp;height=64&amp;amp;face=0_0_64_64');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;C# preprocessor directives&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn the different C# preprocessor directives that control conditional compilation, warnings, nullable analysis, and more&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678862612602&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ConditionalAttribute Class (System.Diagnostics)&quot; data-og-description=&quot;Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute&quot; data-og-url=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute?view=net-8.0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wmmU8/hyRWuN4bEi/kK5Qq1CYugANYAPd8Hg9k0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wmmU8/hyRWuN4bEi/kK5Qq1CYugANYAPd8Hg9k0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ConditionalAttribute Class (System.Diagnostics)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678866664973&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Conditional compilation for ignoring method calls with the ConditionalAttribute&quot; data-og-description=&quot;In this post I describe conditional compilation using&quot; data-og-host=&quot;andrewlock.net&quot; data-og-source-url=&quot;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&quot; data-og-url=&quot;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oa7hA/hyRVa4L7GM/j8T4T3Kn0ZCMILhSfaCnDk/img.png?width=1920&amp;amp;height=1280&amp;amp;face=0_0_1920_1280,https://scrap.kakaocdn.net/dn/mHmdu/hyRWyCX6yW/mQkr1qGPKPNBg85eLnP3Qk/img.png?width=1920&amp;amp;height=1280&amp;amp;face=0_0_1920_1280,https://scrap.kakaocdn.net/dn/UlE5Q/hyRWA8B8t3/Qq9wEM8JZsZ7qUdogKijRK/img.png?width=1922&amp;amp;height=942&amp;amp;face=0_0_1922_942&quot;&gt;&lt;a href=&quot;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oa7hA/hyRVa4L7GM/j8T4T3Kn0ZCMILhSfaCnDk/img.png?width=1920&amp;amp;height=1280&amp;amp;face=0_0_1920_1280,https://scrap.kakaocdn.net/dn/mHmdu/hyRWyCX6yW/mQkr1qGPKPNBg85eLnP3Qk/img.png?width=1920&amp;amp;height=1280&amp;amp;face=0_0_1920_1280,https://scrap.kakaocdn.net/dn/UlE5Q/hyRWA8B8t3/Qq9wEM8JZsZ7qUdogKijRK/img.png?width=1922&amp;amp;height=942&amp;amp;face=0_0_1922_942');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Conditional compilation for ignoring method calls with the ConditionalAttribute&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this post I describe conditional compilation using&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;andrewlock.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678853803617&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;開発用ビルド時に有効になるDEVELOPMENT_BUILDとDEBUGの違い【Unity】 - (:3[kanのメモ帳]&quot; data-og-description=&quot;この記事でのバージョン Unity 2021.3.1f1 はじめに ゲームのデバッグ用の機能等を実装したいが、リリース時にはユーザから見えない(使えない)ようにしたい、という事がよくあります。 そんな&quot; data-og-host=&quot;kan-kikuchi.hatenablog.com&quot; data-og-source-url=&quot;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&quot; data-og-url=&quot;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cD5iWk/hyRU3qVS5m/SdMkxhFsfl8IuYNNHfkeIK/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625,https://scrap.kakaocdn.net/dn/bD7zaP/hyRU6upRKm/T26iagHXmV3x2HOelpuFrk/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625,https://scrap.kakaocdn.net/dn/4Saz7/hyRU8lt2jz/KJWokR7uIQK3A3HsSkYSbK/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625&quot;&gt;&lt;a href=&quot;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kan-kikuchi.hatenablog.com/entry/DEVELOPMENT_BUILD_DEBUG&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cD5iWk/hyRU3qVS5m/SdMkxhFsfl8IuYNNHfkeIK/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625,https://scrap.kakaocdn.net/dn/bD7zaP/hyRU6upRKm/T26iagHXmV3x2HOelpuFrk/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625,https://scrap.kakaocdn.net/dn/4Saz7/hyRU8lt2jz/KJWokR7uIQK3A3HsSkYSbK/img.png?width=639&amp;amp;height=625&amp;amp;face=0_0_639_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;開発用ビルド時に有効になるDEVELOPMENT_BUILDとDEBUGの違い【Unity】 - (:3[kanのメモ帳]&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;この記事でのバージョン Unity 2021.3.1f1 はじめに ゲームのデバッグ用の機能等を実装したいが、リリース時にはユーザから見えない(使えない)ようにしたい、という事がよくあります。 そんな&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kan-kikuchi.hatenablog.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Game/개발</category>
      <category>Conditional</category>
      <category>Debug</category>
      <category>DEVELOPMENT_BUILD</category>
      <category>Preprocessor</category>
      <category>UNITY_EDITOR</category>
      <category>조건부 컴파일</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/65</guid>
      <comments>https://progrunman.tistory.com/65#entry65comment</comments>
      <pubDate>Wed, 15 Mar 2023 17:25:43 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] 엔진의 주요 event 함수 정리 (Awake(), Start(), etc)</title>
      <link>https://progrunman.tistory.com/64</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## `GameObject.SetActive`와 `Behaviour.enabled`&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- GameObject &lt;u&gt;활성여부&lt;/u&gt;&amp;nbsp;vs 컴포넌트의 &lt;u&gt;활성여부&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Scene내 객체(GameObject)의 활성여부 vs 객체내 부품(Component)의 활성여부(동작가능 : e.g. Update)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 참고로 Transform의 경우 Bahaviour가 아닌 Component에서 바로 상속하기에 enabled가 없음. 즉, 항상 동작.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## MonoBehaviour 파생 클래스의 생성자&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Unity Engine 및 직렬화 시스템에 의해 생성자가 여러번 호출될 수 있으니 pure C# API class에만 사용하고 Unity API class에는 &lt;u&gt;사용금지&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 참고로 `RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)` 호출전에 빌드된 모든 MonoBehaviour script의 생성자가 호출되는듯(Subsystem에 Scripting이 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Awake()&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 Script lifetime 동안 정확히 &lt;u&gt;&lt;b&gt;한번만 호출&lt;/b&gt;&lt;/u&gt;됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Script 인스턴스가 로드될 때 호출(e.g. `Object.Instantiate`, Scene로드)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;span&gt;Scene의 모든 활성 GameObject가 초기화된 후 호출됨. 따라서 해당 메서드내에서 `GameObject.FindWithTag` 등으로 쿼리 가능하지만 쿼리된 객체의 Awake()가 먼저 호출되었는지는 보장되지 않으므로 &lt;u&gt;참조하는 객체 속성 할당 또는 사용에는 주의&lt;/u&gt;가 필요함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;비활성화(`SetActive(false)`) 상태로 인스턴스가 로드되면 최초 활성화 이전까지 Awake호출이 지연됨에 주의&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 Component의 활성화(enabled) 여부와 상관없이 초기화시 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;&lt;b&gt;객체 초기화에 사용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;(Coroutine으로 정의 불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## OnEnable()&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체가 enabled 되거나 active될 때 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 활성화 될때마다 초기화가 필요한 로직은 해당 메서드에서 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;## Start()&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 Script lifetime 동안 정확히 &lt;u&gt;&lt;b&gt;한번만 호출&lt;/b&gt;&lt;/u&gt;됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 객체의 최초 Update() 호출 직전에 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비활성화(Disabled) 상태인 경우 Awake()와 동일한 frame에서 호출되지 않을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &quot;Where objects are instantiated during gameplay, their Awake function is called after the Start functions of Scene objects have already completed.&quot; (&lt;s&gt;공식문서에 뭔소린지? 왜케 일관성이 없지?? 이미 Scene및 Update들이 열나게 돌아가는중에는 중간에 인스턴스화되는 객체들의 Awake 호출 순서는 보장되지 않는다는건가?? 차후 테스트 필요&lt;/s&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;&lt;b&gt;객체 상태 시작에 사용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;(Coroutine으로 정의 가능 - Unity Engine에서 비동기로 호출함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## Update()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MonoBehaviour가 enabled된 경우 모든 frame에서 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## OnApplicationPause()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일시정지가 감지된 frame의 끝에 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일시정지 그래픽 표시를 위해 호출이후 frame이 1회 추가 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## OnApplicationQuit()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 앱 종료전 모든 GameObject에서 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## OnDisable()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체(부착된 Behaviour)가 disabled 되거나 destroy될 때 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## OnDestroy()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체(부착된 Behaviour)가 파괴될 때 호출(e.g. 오브젝트 소멸)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 마지막 프레임까지 Update를 마친 뒤 호출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기타 다른것들은 아래 링크 참조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;## References&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678361792476&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;이벤트 함수의 실행 순서 - Unity 매뉴얼&quot; data-og-description=&quot;Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/2021.3/Manual/ExecutionOrder.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;이벤트 함수의 실행 순서 - Unity 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678361839277&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity - Scripting API: MonoBehaviour.Awake()&quot; data-og-description=&quot;Awake is called either when an active GameObject that contains the script is initialized when a Scene loads, or when a previously inactive GameObject is set to active, or after a GameObject created with Object.Instantiate is initialized. Use Awake to initi&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&quot; data-og-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QQdnR/hyRSNAyzUh/BOPDWzur90BnR6Uv9ku7V0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QQdnR/hyRSNAyzUh/BOPDWzur90BnR6Uv9ku7V0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity - Scripting API: MonoBehaviour.Awake()&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Awake is called either when an active GameObject that contains the script is initialized when a Scene loads, or when a previously inactive GameObject is set to active, or after a GameObject created with Object.Instantiate is initialized. Use Awake to initi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678361808179&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity - Scripting API: MonoBehaviour.Start()&quot; data-og-description=&quot;Like the Awake function, Start is called exactly once in the lifetime of the script. However, Awake is called when the script object is initialised, regardless of whether or not the script is enabled. Start may not be called on the same frame as Awake if t&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&quot; data-og-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/drhKwL/hyRSUzHClP/rvF9VCsoLkCeSjoGfH5XOk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/drhKwL/hyRSUzHClP/rvF9VCsoLkCeSjoGfH5XOk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity - Scripting API: MonoBehaviour.Start()&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Like the Awake function, Start is called exactly once in the lifetime of the script. However, Awake is called when the script object is initialised, regardless of whether or not the script is enabled. Start may not be called on the same frame as Awake if t&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Game/개발</category>
      <category>awake</category>
      <category>onDestroy</category>
      <category>OnDisable</category>
      <category>OnEnable</category>
      <category>start</category>
      <category>Update</category>
      <author>progrunman</author>
      <guid isPermaLink="true">https://progrunman.tistory.com/64</guid>
      <comments>https://progrunman.tistory.com/64#entry64comment</comments>
      <pubDate>Fri, 10 Mar 2023 00:05:42 +0900</pubDate>
    </item>
  </channel>
</rss>