<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>자가라 노트</title>
    <link>https://zagara.tistory.com/</link>
    <description>자가라 노트</description>
    <language>ko</language>
    <pubDate>Fri, 17 Jul 2026 01:58:05 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>자가라o</managingEditor>
    <image>
      <title>자가라 노트</title>
      <url>https://tistory1.daumcdn.net/tistory/4784200/attach/225870f5573849f3829431b6b5494e6d</url>
      <link>https://zagara.tistory.com</link>
    </image>
    <item>
      <title>[C#] 부동소수점 ( + int의 float 변환)</title>
      <link>https://zagara.tistory.com/26</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실수형 변수에는 decimal, float(single), double이 있고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 안에서 '고정 소수점 방식'과 '부동 소수점 방식'으로 나뉩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt; 고정 소수점 (fixed point) &amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;decimal이 해당하는 방식으로&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;32bit(4byte) 중 [부호-1bit] [정수부-15bit] [소수부-16bit]로 이루어져 있고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 방법이 일반적으로 생각하는 정수,소수 직접 다 저장하는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt; IEEE 부동 소수점 (floating point) &amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;float(single), double이 해당하는 방식으로&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부동(不動)이 아니라 부동(浮動&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) : '&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;부&lt;/span&gt;유해서 &lt;span style=&quot;color: #ee2323;&quot;&gt;동&lt;/span&gt;동 떠다니는 &lt;span style=&quot;color: #ee2323;&quot;&gt;소수점&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;'이란 뜻입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 안에서 또 분류하면 단정도 float (4byte), 그 2배인 배정도 double (8byte)로 나눕니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;float은 4byte : [부호-1bit] [지수부-8bit] [가수부-23bit]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;double은 8byte : [부호-1bit] [지수부-11bit] [가수부-52bit]&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;color: #000000;&quot;&gt;부동소수점 방식은 '정수 + 소수'방식이 아니라 '지수 * 가수'방식으로&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;숫자를 2진법으로 변환한뒤 정수부분이 1의 자리+소수점으로 남을때까지 2로 나누고 나눈만큼 지수로 곱해줍니다.&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;&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;957&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ELBif/btrl00dDPnv/JMoOtcuUteFc2KdKKo2eeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ELBif/btrl00dDPnv/JMoOtcuUteFc2KdKKo2eeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ELBif/btrl00dDPnv/JMoOtcuUteFc2KdKKo2eeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FELBif%2Fbtrl00dDPnv%2FJMoOtcuUteFc2KdKKo2eeK%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;605&quot; height=&quot;407&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;644&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;span style=&quot;color: #000000;&quot;&gt;실수형 변수를 출력했을때 작은 숫자에 경우 정상적으로 출력하다가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;float의 경우 10의 9승부터&lt;/span&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;가수E+지수&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;형식의 정규표현법으로 출력됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt;지수부의 저장&amp;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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지수부는 지수에 127(&lt;span style=&quot;background-color: #ffffff;&quot;&gt;바이어스)를 더하여 저장합니다.&lt;/span&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;background-color: #ffffff; color: #000000;&quot;&gt;&lt;b&gt;바이어스(bias)&lt;/b&gt;란 지수의 음수 양수를 구별하기 위해 사용되는 값이며&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;float의 경우 0111 1111(127) 값을 더합니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;이는 지수의 맨앞자리를 통해 지수의 부호를 나타낸다고 볼 수 있는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;127에 단 1(개의 자리수)이라도 더 해진다면 지수부의 맨앞자리는 1로 바뀌게 됩니다.&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;color: #666666;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;float으로 나타내면 4byte :&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;[부호-1bit]&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;[&lt;span style=&quot;color: #409d00;&quot;&gt;[지수부호-1bit]&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #1b711d;&quot;&gt;[지수부-7bit]&lt;/span&gt;]&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;[가수부-23bit]&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바이어스는 float일때 127 / double일때 1023 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;양수지수는 실수가 1의 자리보다 클때, 음수지수는 실수가 1의 자리보다 작을때 사용됩니다.&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;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt;가수부의 저장&amp;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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가수부는 변환한 숫자에서 가장 첫번째 값을 제외하고 메모리에 저장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 예시를 메모리에 저장한다면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 76.7316%; height: 45px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.02887%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 26.7027%; text-align: center;&quot;&gt;1000 1100&lt;/td&gt;
&lt;td style=&quot;width: 65.2683%; text-align: center;&quot;&gt;001 1100 0100 0000 0000 0000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&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;color: #000000;&quot;&gt;그 이유는 &lt;u&gt;맨 첫번째 값은 지수부에서 크기확인을 통해 유추할 수 있기 때문&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;color: #000000;&quot;&gt;실제값이 1보다 크거나 같다면 지수가 양수형태 -&amp;gt; 첫번째 값 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1보다&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;작다면 지수가 음수형태 -&amp;gt; 첫번째 값 0으로 나타나기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;굳이 1bit를 더 쓸필요가 없는 것입니다.&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;color: #000000;&quot;&gt;▶ 부동소수점에의한 실수표현은 항상 오차가 발생한다는 특징이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 무시해도 될 정도의 수준이거나 float의 경우 double로 대체하여 정밀도를 높이는 방법으로 해결할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt; 본론 : int의 float 변환 &amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&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;color: #000000;&quot;&gt;float은 최대 10의 38승까지 표현이 가능합니다.&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;color: #000000;&quot;&gt;float.MaxValue가 대충 340282350000000000000000000000000000000이며 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;int의 최대값인 약 21억과 비교했을때 굉장히 큰 숫자죠.&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;color: #000000;&quot;&gt;이때 제가 했던 실수는 float의 최대값이 더 크니까 int값을 float에 삽입해도 문제가 없을거라 생각한 것이었습니다.&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;color: #000000;&quot;&gt;float의 최대값이 int의 최대값보다는 크지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;float이 실제 나타낼 수 있는 가수부의 크기(23bit)가 int의 크기(32bit)보다 작기 때문에&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;color: #000000;&quot;&gt;int의 값이 대충 8,388,607을 넘어가면서 부터는 데이터의 소실이 일어나게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1637694054782&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int max = int.MaxValue;

while (max &amp;gt; 10) 
{
    Console.WriteLine($&quot;{max}&quot;);        // 실제 int값
    Console.WriteLine($&quot;{(float)max}&quot;); // float으로 변환
    
    max /= 10;    
    Console.WriteLine();
}&lt;/code&gt;&lt;/pre&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;213&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPynV3/btrlYOebuvM/N18aNB7C4xt5tkFyGCK1kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPynV3/btrlYOebuvM/N18aNB7C4xt5tkFyGCK1kk/img.png&quot; data-alt=&quot;데이터가 손실된걸 볼 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPynV3/btrlYOebuvM/N18aNB7C4xt5tkFyGCK1kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPynV3%2FbtrlYOebuvM%2FN18aNB7C4xt5tkFyGCK1kk%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;213&quot; height=&quot;438&quot; data-origin-width=&quot;213&quot; data-origin-height=&quot;438&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;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;▶&lt;span&gt; &lt;/span&gt;&lt;/span&gt;float -&amp;gt; int 에서 뿐만 아니라 int -&amp;gt; float에서도 데이터 손실이 일어나는걸 알 수 있습니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[참고]&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://ahnjg.tistory.com/16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ahnjg.tistory.com/16&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tcpschool.com/cpp/cpp_datatype_floatingPointNumber&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.tcpschool.com/cpp/cpp_datatype_floatingPointNumber&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;jjang (7).jpg&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/briv1B/btrl0aHzKHr/GaHc8Dj6WeMiMgmWqYK05K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/briv1B/btrl0aHzKHr/GaHc8Dj6WeMiMgmWqYK05K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/briv1B/btrl0aHzKHr/GaHc8Dj6WeMiMgmWqYK05K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbriv1B%2Fbtrl0aHzKHr%2FGaHc8Dj6WeMiMgmWqYK05K%2Fimg.jpg&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;310&quot; height=&quot;285&quot; data-filename=&quot;jjang (7).jpg&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;442&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;</description>
      <category>C#</category>
      <category>DOUBLE</category>
      <category>float</category>
      <category>부동소수점</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/26</guid>
      <comments>https://zagara.tistory.com/26#entry26comment</comments>
      <pubDate>Wed, 24 Nov 2021 04:20:10 +0900</pubDate>
    </item>
    <item>
      <title>[게임수학] 내적</title>
      <link>https://zagara.tistory.com/25</link>
      <description>&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;원점O와 두 벡터 A(10, 5), B(3, 7)이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각&amp;ang;AOB는 모른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 OAB의 넓이는 어떻게 구할까?&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. 각각의 벡터를 통해 원점에서의 길이 a, b를 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 내적의 공식은 OA&amp;middot;OB로 (A.x * B.x) + (A.y * B.y)이며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. |a||b|cos&amp;theta;와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 내적과 길이 a, b를 통해 cos&amp;theta;를 구할 수 있고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 삼각함수 sin&amp;sup2;&amp;theta; + cos&amp;sup2;&amp;theta; = 1을 통해 sin&amp;theta;의 값을 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. sin&amp;theta;를 이용해 A에서 B로 내리는 수직의 길이를 구할 수 있다.&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;235&quot; data-filename=&quot;jjang (24).jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4XFF/btriMJMPWwo/EYgcIoogMTD2kBumMm36E0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4XFF/btriMJMPWwo/EYgcIoogMTD2kBumMm36E0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4XFF/btriMJMPWwo/EYgcIoogMTD2kBumMm36E0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4XFF%2FbtriMJMPWwo%2FEYgcIoogMTD2kBumMm36E0%2Fimg.jpg&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;235&quot; data-filename=&quot;jjang (24).jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>게임수학</category>
      <category>내적</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/25</guid>
      <comments>https://zagara.tistory.com/25#entry25comment</comments>
      <pubDate>Mon, 25 Oct 2021 04:02:31 +0900</pubDate>
    </item>
    <item>
      <title>[알고리즘] 소수 구하기</title>
      <link>https://zagara.tistory.com/24</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;https://www.acmicpc.net/problem/1929&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;백준 1929번에서 파생되었습니다.&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;소수를 구하는 알고리즘에서는 요구하는 조건이 &lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특정수의 소수판별&lt;/li&gt;
&lt;li&gt;범위 소수 개수 판별&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 이 2가지로 나뉜다고 볼 수 있습니다.&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;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;1. 특정수의 소수판별&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;어떤수 n이 주어졌을때 소수를 판별하는 방법으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히 n의 제곱근까지 비교하여 약수의 개수를 세는 방법입니다.&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) 소수는 약수를 1과 자기자신 밖에 가지지않기 때문에 항상 약수의 개수가 2개입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1의 경우&amp;nbsp; :&amp;nbsp; 1은 약수로 1밖에 가지지 않습니다. 약수의 개수가 1개이기 때문에 소수가 아닙니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;편의상 약수가 1개라 소수가 아니라는거지, 정말 1이 소수인 이유가 약수가 1개라서는 아닙니다. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3의 경우&amp;nbsp; :&amp;nbsp; 3은 약수로 1, 3을 가집니다. 약수의 개수가 2개이기 때문에 소수입니다.&lt;/li&gt;
&lt;li&gt;8의 경우&amp;nbsp; :&amp;nbsp; 8은 약수로 1, 2, 4, 8을 가집니다. 약수의 개수가 4개이기 때문에 소수가 아닙니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준 2) 약수는 원래의 숫자될 수 있는 약수쌍을 가지고 있습니다.&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부터 n까지 비교할 필요없이 1부터 n의 제곱근까지만 비교하면 됩니다.&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;약수는 한개만 찾는다면 ( n / 약수 )를 통해 다른 약수를 찾을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1과 자기자신도 1 * n = n이라는 숫자쌍이라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외로 25의 5 * 5처럼 숫자쌍이 겹치는 경우도 있지만 제곱근까지 비교하면 자연스럽게 포함됩니다.&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;pre id=&quot;code_1635097676358&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int isPrime(int n) 
{
    int sqt = MathF.Sqrt(n); // 제곱근
    for(int i = 2; i &amp;lt;= sqt; i++) // 1을 제외하고 2부터
    { 
        if(n % i == 0) // 1과 n이 비교대상에서 제외되었으므로 하나라도 통과한다면 
            return 0;  // 소수가 아닙니다.
    }
    
	return 1; // 소수입니다.
}&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;시간복잡도는 O(&amp;radic;n)입니다.&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;lt;2. 범위 소수 개수 판별&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;/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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&quot; data-filename=&quot;Sieve_of_Eratosthenes_animation.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mzfzW/btriKxTpEge/mIacyZi3VRUxSutZC0hAGk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mzfzW/btriKxTpEge/mIacyZi3VRUxSutZC0hAGk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mzfzW/btriKxTpEge/mIacyZi3VRUxSutZC0hAGk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/mzfzW/btriKxTpEge/mIacyZi3VRUxSutZC0hAGk/img.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&quot; data-filename=&quot;Sieve_of_Eratosthenes_animation.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에라토스테네스의 체&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;처음엔 모두 살아있으니 그중 첫번째인&lt;br /&gt;2는 살리고 2의 배수를 다 지웁니다.&lt;br /&gt;2 다음으로 살아남은 수 3은 살리고 3의 배수를 다 지웁니다.&lt;br /&gt;3 다음으로 4는 2의 배수로 지워버렸으니 건너뜁니다.&lt;br /&gt;3 다음으로 살아남은 수 5는 살리고 5의 배수를 다 지웁니다.&lt;br /&gt;.... 이런식으로 끝까지 진행하고 살아남은 숫자들은 소수입니다.&lt;/blockquote&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;pre id=&quot;code_1635099915531&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void eratostenes(int min, int max)
{
    bool[] Len = new bool[max + 1]; // 조건이 범위로 주어지더라도 max값을 기준으로 배열을 만듭니다.

    for (int i = 2; i &amp;lt;= max; i++) // 최소 소수 2부터 max까지
    {
        if (Len[i] == false) // 해당수가 지워져 있다면 건너뜁니다
        {
            Console.WriteLine(i); // 소수를 출력해주고
        
            for (int j = 1; j * i &amp;lt;= mx; j++) // 방식에 따라서 2부터 시작하여 소수를 살릴수 있습니다.
                Len[i * j] = true; // 배수를 다 지웁니다.
        }
    }
}&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;시간복잡도는 O(nloglogn)입니다.&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,000,000정도로 제한적이라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;pre id=&quot;code_1635100326726&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void eratostenes(int mn, int mx)
{
    mn += (mn == 1) ? 1 : 0;

    StringBuilder sb = new StringBuilder(); // 출력시간 조절위해 StringBuilder사용
    
    bool[] Len = new bool[max + 1];
    
    int mid = (int)MathF.Sqrt(max) + 1; // StringBuilder로 저장 출력 -&amp;gt; 즉시 출력X
    for (int i = 2; i &amp;lt; mid; i++)     // 그렇게 때문에 최대값의 제곱근까지만 비교해도 충분합니다.
    {
        if (Len[i] == false)
        {
            for (int j = 2; j * i &amp;lt;= max; j++)
                Len[i * j] = true;
        }
    }
    
    for (int i = min; i &amp;lt;= max; i++)
    {
        if (Len[i] == false)
            sb.AppendLine($&quot;{i}&quot;); // 범위 안의 판별된 소수들을 StringBuilder에 삽입
    }

    Console.WriteLine(sb.ToString()); // 출력
}&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;955&quot; data-filename=&quot;ㅋㄻ.jpg&quot; width=&quot;292&quot; height=&quot;201&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biRnZc/btriHB26HH6/jVw1WDizuwguBbdCtOjho1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biRnZc/btriHB26HH6/jVw1WDizuwguBbdCtOjho1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biRnZc/btriHB26HH6/jVw1WDizuwguBbdCtOjho1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiRnZc%2FbtriHB26HH6%2FjVw1WDizuwguBbdCtOjho1%2Fimg.jpg&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;955&quot; data-filename=&quot;ㅋㄻ.jpg&quot; width=&quot;292&quot; height=&quot;201&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>소수</category>
      <category>소수찾기</category>
      <category>소수판별</category>
      <category>에라토스어쩌고</category>
      <category>에라토스테네스</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/24</guid>
      <comments>https://zagara.tistory.com/24#entry24comment</comments>
      <pubDate>Mon, 25 Oct 2021 03:35:16 +0900</pubDate>
    </item>
    <item>
      <title>[C#] GC 가비지 컬렉션</title>
      <link>https://zagara.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Garbage Collection&lt;/b&gt; 통칭 GC는 &lt;span style=&quot;color: #ee2323;&quot;&gt;메모리 관리기법&lt;/span&gt;의 하나.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CLR에서 GC는 &lt;u&gt;자동메모리 관리자 역할&lt;/u&gt;로 &lt;span style=&quot;color: #ee2323;&quot;&gt;어플리케이션의 메모리 할당 및 해제를 관리&lt;/span&gt;합니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&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;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;CLR : MS .NET의 가상머신 구성요소로 IL 실행을 담당합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;span style=&quot;color: #000000;&quot;&gt;&amp;lt;기본적인 동작 방식&amp;gt;&lt;/span&gt;&lt;/h4&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;color: #000000;&quot;&gt;1) 현재 수행중인 스레드를 모두 중단하고 GC스레드를 활성화합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2) 사용중인 객체 참조그래프 : 루트를 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;루트 참조&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;각 스레드가 수행중인 메서드 로컬변수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;CPU 레지스터 변수가 가지고있는 참조&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;사용중인 각 타입(클래스)의 정적필드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;전역변수&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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-origin-width=&quot;996&quot; data-origin-height=&quot;282&quot; width=&quot;715&quot; height=&quot;203&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duOvGV/btrhZl7L0Ka/wiqzNti6jr0F6mNUfnShE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duOvGV/btrhZl7L0Ka/wiqzNti6jr0F6mNUfnShE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duOvGV/btrhZl7L0Ka/wiqzNti6jr0F6mNUfnShE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduOvGV%2FbtrhZl7L0Ka%2FwiqzNti6jr0F6mNUfnShE0%2Fimg.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;282&quot; width=&quot;715&quot; height=&quot;203&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;3) 힙 메모리의 모든데이터는 처음에 쓰레기로 간주합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) GC는 루트를 참조하여 관계있는 데이터를 쓰레기에서 제외합니다.&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-origin-width=&quot;1000&quot; data-origin-height=&quot;282&quot; width=&quot;715&quot; height=&quot;202&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qo8C2/btrhVrVtS3C/CK8KIl2KutRt90sh1xHTh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qo8C2/btrhVrVtS3C/CK8KIl2KutRt90sh1xHTh0/img.png&quot; data-alt=&quot;메모리 컴팩션&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qo8C2/btrhVrVtS3C/CK8KIl2KutRt90sh1xHTh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqo8C2%2FbtrhVrVtS3C%2FCK8KIl2KutRt90sh1xHTh0%2Fimg.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;282&quot; width=&quot;715&quot; height=&quot;202&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;5) 쓰레기 데이터를 삭제하고 &lt;span style=&quot;color: #ee2323;&quot;&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;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;메모리 컴팩션(Memory Compaction)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;찾아보면 '동적으로 시스템을 구성하는 기억장소에서 여러곳에 흩어져 있는 가용 공간을 하나의 연속된 공간으로 만드는 작업. 기억장소의 할당과 반납과정에서 일어난 단편화 현상을 제거한다.' 고 하는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;대충 쉽게 띄엄띄엄 사용중인 메모리들을 한곳으로 잘모아서 빈공간을 늘리는 일종의 조각모음이라고 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GC가 효율적으로 작동하기 위해 다양한 방식이 제시되 었는데 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;추적기반의 점진적GC, 세대별GC와 참조 카운팅GC등의 방법이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 흔하게 쓰이는 세대별 GC방식만 알아보겠습니다.&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;세대별 GC&amp;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;color: #000000;&quot;&gt;메모리를 구역별로 나누어 &lt;u&gt;빨리 해제될 객체&lt;/u&gt;와 &lt;u&gt;오래 남아있을 객체&lt;/u&gt;를 따로 관리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메모리를 0, 1, 2세대로 구분하여 0세대는 방금 생성된 객체나 빨리 사라질것으로 예상되는 객체, 2세대는 오래남을 것으로 예상되는 객체로 나뉩니다. &lt;span style=&quot;color: #ee2323;&quot;&gt;수명 예측 방법은 GC를 겪은 횟수&lt;/span&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;color: #000000;&quot;&gt;▶ 작동방식&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;애플리케이션 실행 후 힙에 할당하다가 (할당 즉시 0세대) 할당된 총 크기가 0세대 GC의 임계치에 도달하면 0세대 가비지 컬렉션을 수행합니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 살아남아 일정 횟수의 GC를 겪은 객체는 1세대로 이동합니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1세대 임계치 도달시 1세대 GC, 2세대 임계치 도달시 2세대 GC로 반복합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;세대별 GC 실행시에는 이전 세대 또한 포함해서 진행&lt;/u&gt;합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0세대 GC 실행시 0세대만 실행하지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1세대 GC 실행시에는 1, 0세대, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2세대 GC 실행시 2, 1, 0세대 모두 GC를 실행하며 이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;Full GC&lt;/span&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;color: #000000;&quot;&gt;GC 실행시 애플리케이션의 실행을 잠시 멈추고 GC를 실행한다고 했는데 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;애플리케이션 메모리가 커지면 -&amp;gt; Full GC의 오버헤드도 커지게 되고 -&amp;gt; 정지시간 또한 늘어나게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 실시간 프로그램에서는 GC가 효율적으로 동작할 수 있도록 신경쓰는게 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;객체 크기별 GC 작동방식&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;C#의 CLR에서는 객체의 크기에 따라 메모리를 크게 2가지로 나눠서 관리합니다.&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;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1) SOH (Small Object Heap)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SOH는 용량이 작은 객체 (85KB 미만)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;- 세대별 GC방식 그대로 사용됩니다.&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;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2) LOH (Large Object Heap)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LOH는 용량이 큰 객체 (85KB 이상)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;- [C/C++ 방식과 유사] 할당, 해제는 GC에서 하지만 메모리 컴팩션이 일어나지는 않습니다. (해제되면 된대로 냅둠)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;용량이 큰경우 오히려 메모리를 재배치하는 오버헤드가 크기 때문에 2세대 GC에서만 메모리를 해제합니다. (하지만 이때도 많은 오버헤드) 그렇기에 2세대 GC가 자주 일어나지 않게하고 큰용량의 생성,해제도 반복해서는 안됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;color: #000000;&quot;&gt;&amp;lt;GC 장점&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유효하지 않은(이미 해제된) 포인터 접근을 방지합니다.&lt;/li&gt;
&lt;li&gt;이중해제를 방지합니다.&lt;/li&gt;
&lt;li&gt;메모리 누수를 방지 할 수 있습니다.&lt;/li&gt;
&lt;/ul&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;color: #000000;&quot;&gt;&amp;lt;GC 단점&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 메모리를 해제할지 결정하는데도 비용이 듭니다.&lt;/li&gt;
&lt;li&gt;GC가 일어나는 타이밍이나 점유시간을 예측하기 어렵습니다.&lt;/li&gt;
&lt;li&gt;메모리 해제 시점을 알 수 없습니다.&lt;/li&gt;
&lt;/ul&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;color: #000000;&quot;&gt;&amp;lt;GC 사용지침&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지나치게 많은 할당 X&lt;/li&gt;
&lt;li&gt;너무 큰 객체 할당 X&lt;/li&gt;
&lt;li&gt;너무 복잡한 참조 X&lt;/li&gt;
&lt;li&gt;너무 많은 루트 X&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;lt;GC 메서드&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 120px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 28.7209%; height: 20px;&quot;&gt;GC.Collect()&lt;/td&gt;
&lt;td style=&quot;width: 71.2791%; height: 20px;&quot;&gt;모든 세대 GC 즉시 수행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 28.7209%; height: 20px;&quot;&gt;GC.Collect(int)&lt;/td&gt;
&lt;td style=&quot;width: 71.2791%; height: 20px;&quot;&gt;0세대에서 지정된 세대까지 GC 즉시 수행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 28.7209%; height: 40px;&quot;&gt;GC.CollectionCount(int)&lt;/td&gt;
&lt;td style=&quot;width: 71.2791%; height: 40px;&quot;&gt;지정된 세대의 개체에 대해 GC가 수행된 횟수 반환 &lt;br /&gt;(GC가 언제 발생하는지 모니터링하는 가장 쉬운방법)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 28.7209%; height: 20px;&quot;&gt;GC.GetGeneration(object)&lt;/td&gt;
&lt;td style=&quot;width: 71.2791%; height: 20px;&quot;&gt;obj의 현재세대 반환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 28.7209%; height: 20px;&quot;&gt;GC.MaxGeneration&lt;/td&gt;
&lt;td style=&quot;width: 71.2791%; height: 20px;&quot;&gt;시스템에서 현재 지원하는 가장 큰 세대 번호를 가져옵니다.&lt;br /&gt;(설명은 0,1,2세대라고 했지만 시스템에 따라 0~n세대로 나뉠수도 있기때문)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;[추가] C / C++ 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;new, malloc으로 힙에 동적 메모리 할당 / delete, free로 동적 메모리 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;자유 메모리 블록 리스트 (Free memory block list)로 관리 된다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;할당 : 메모리 앞쪽부터 필요한만큼의 메모리 할당이 가능한 공간을 찾아 할당 후 초기화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;해제 : 해제 후 주변의 빈 메모리와 합쳐집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;단점 : 파편화 - 전체 빈 메모리는 많지만 실질적 할당 실패 가능성이 커집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;Heap의 앞에서 부터 메모리를 탐색하므로 빈메모리가 뒤쪽에 많다면 매번 오버헤드가 발생할 수 있습니다.&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;360&quot; data-filename=&quot;jjang (9).jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctArQi/btrh2hxihbg/cWN4SrAhtmjrqOoJlsUvtK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctArQi/btrh2hxihbg/cWN4SrAhtmjrqOoJlsUvtK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctArQi/btrh2hxihbg/cWN4SrAhtmjrqOoJlsUvtK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctArQi%2Fbtrh2hxihbg%2FcWN4SrAhtmjrqOoJlsUvtK%2Fimg.jpg&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;360&quot; data-filename=&quot;jjang (9).jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>C#</category>
      <category>gc</category>
      <category>가비지컬렉션</category>
      <category>가비지컬렉터</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/23</guid>
      <comments>https://zagara.tistory.com/23#entry23comment</comments>
      <pubDate>Sun, 17 Oct 2021 23:02:55 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] 컴파일 방식 2) IL2CPP</title>
      <link>https://zagara.tistory.com/22</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;IL2CPP는 Unity에서 개발한 (스크립팅 백엔드)AOT 컴파일러로, &amp;lt;&amp;lt;IL to CPP&amp;gt;&amp;gt; Unity가 &lt;u&gt;스크립트와 어셈블리의 &lt;span style=&quot;color: #ee2323;&quot;&gt;IL코드&lt;/span&gt;를 &lt;span style=&quot;color: #ee2323;&quot;&gt;C++ 코드&lt;/span&gt;로 변환&lt;/u&gt;시켜 선택한 플랫폼에 적합한 네이트브 바이너리 파일로 만듭니다. IL2CPP는 Unity 프로젝트의 성능, 보안 및 플랫폼 호환성을 개선하는 등의 용도로 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안관련하여 IL2CPP로 빌드하게 되면 코드가 난독화되어 디컴파일시 코드가 바로 노출되지 않습니다. (최소한의 보안)&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/2018.4/Manual/IL2CPP.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;Mono의 문제점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;C# runtime performance가 C/C++에 비해 여전히 느리다.&lt;/li&gt;
&lt;li&gt;최신 버전의 .NET언어를 Mono에서 지원하기 힘들다.&lt;/li&gt;
&lt;li&gt;다양한 플랫폼 아키텍처에 맞추기위한 포팅, 유지보수등의 작업에 너무 많은 노력이 든다.&lt;/li&gt;
&lt;li&gt;실행 중 GC가 멈출 수도 있다.&lt;/li&gt;
&lt;li&gt;IOS 앱스토어에 APK 등록시 armv7과 armv8 두 버전을 모두 등록해야 하는데(정책) Mono는 armv8(arm64)를 지원하지 못한다.&lt;/li&gt;
&lt;li&gt;IOS가 JIT(Just in time) 컴파일 방식을 지원하지 않음에 따라 &lt;u&gt;AOT(Ahead of time) 컴파일 방식을 사용하는 IL2CPP&lt;/u&gt;가 대두되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;lt;IL 코드&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C# 코드를 빌드하면 MSIL이라는 중간코드(&lt;span style=&quot;color: #ee2323;&quot;&gt;I&lt;/span&gt;ntermediate &lt;span style=&quot;color: #ee2323;&quot;&gt;L&lt;/span&gt;anguage)를 만들어 냅니다. 프로그램 실행시 이 IL 코드는 JIT Compiler에 의해 컴파일 되어 Native코드로 변경됩니다. IL 방식의 가장 큰 장점은 실행 머신 환경에 관계없이 동일 코드를 실행 할 수 있다는 것입니다. 하지만 실행시 IL코드를 컴파일 해야하기 때문에 속도가 저하의 원인이 된다는 단점도 있습니다. .NET에서는 이러한 문제를 해결하기 위해 프로그램 실행시 전체 IL코드를 컴파일하는 것이 아니라 호출되는 메서드단위로 컴파일을 실행합니다. 따라서 어떤 메서드가 한번도 호출되지 않는다면 해당 메서드는 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;MSIL&amp;nbsp; :&amp;nbsp; MS에서 나온 IL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CIL&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp; Common Intermediate Language&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;lt;IL2CPP 작동방식&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Unity 스크립팅 API코드를 일반 .NET DLL로 컴파일&lt;/li&gt;
&lt;li&gt;관리되는 바이트코드 스트리핑을 적용 -&amp;gt; 빌드된 게임의 크기를 크게 줄여줍니다.&lt;/li&gt;
&lt;li&gt;모든 관리되는 어셈블리를 표준 C++ 코드로 전환&lt;/li&gt;
&lt;li&gt;생성된 C++코드와 IL2CPP의 런타임 부분을 네이티브 플랫폼 컴파일러로 컴파일&lt;/li&gt;
&lt;li&gt;대상 플랫폼에 따라 실행 가능한 파일이나 DLL에 코드를 연결&lt;/li&gt;
&lt;/ol&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-origin-width=&quot;885&quot; data-origin-height=&quot;383&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XadVL/btrhh7hBeSZ/Il90vrzoQtj0LzVxVrSU3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XadVL/btrhh7hBeSZ/Il90vrzoQtj0LzVxVrSU3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XadVL/btrhh7hBeSZ/Il90vrzoQtj0LzVxVrSU3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXadVL%2Fbtrhh7hBeSZ%2FIl90vrzoQtj0LzVxVrSU3K%2Fimg.png&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;383&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-noaft=&quot;1&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;468&quot; width=&quot;190&quot; height=&quot;176&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ExmQ1/btrhfyUf9AR/vIZQNLOpzTNsPtlaEK4QB1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ExmQ1/btrhfyUf9AR/vIZQNLOpzTNsPtlaEK4QB1/img.jpg&quot; data-alt=&quot;아~ 완벽히 이해못했어!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ExmQ1/btrhfyUf9AR/vIZQNLOpzTNsPtlaEK4QB1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FExmQ1%2FbtrhfyUf9AR%2FvIZQNLOpzTNsPtlaEK4QB1%2Fimg.jpg&quot; data-noaft=&quot;1&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;468&quot; width=&quot;190&quot; height=&quot;176&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;&lt;a href=&quot;https://docs.unity3d.com/kr/2018.4/Manual/IL2CPP-HowItWorks.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;- 작동방식 문서&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;lt;IL2CPP 빌드 시간 최적화&amp;gt;&lt;/b&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;증분 빌드를 사용하면 C++ 컴파일러가 마지막 빌드 후 변경된 파일만 다시 컴파일한다고 합니다.&lt;/li&gt;
&lt;li&gt;사용하려면 (대상 디렉토리를 삭제하지 않고) 프로젝트를 이전 빌드 위치에 빌드합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 멀웨어 차단 소프트웨어 검사에서 프로젝트 및 대상 빌드 폴더 제외&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Unity Technologies의 테스트 결과,&lt;/li&gt;
&lt;li&gt;Windows 10에서 Windows Defender를 비활성화 후 빌드시간이 50-66% 단축됬다고 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ SSD에 프로젝트와 대상 빌드 폴더 저장&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스토리지 디바이스가 더 빠르면 처리 속도가 빨라집니다.&lt;/li&gt;
&lt;/ul&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/2018.4/Manual/IL2CPP-OptimizingBuildTimes.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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;lt;추가&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;a href=&quot;http://linforum.kr/bbs/board.php?bo_table=android&amp;amp;wr_id=4&amp;amp;sca=%EA%B0%95%EC%A2%8C&amp;amp;page=2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://linforum.kr/bbs/board.php?bo_table=android&amp;amp;wr_id=4&amp;amp;sca=%EA%B0%95%EC%A2%8C&amp;amp;page=2&lt;/a&gt;&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-origin-width=&quot;170&quot; data-origin-height=&quot;170&quot; data-filename=&quot;rhals.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nNQQS/btrhc7wMYHB/6x3IAhOo3NlVve068EvWgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nNQQS/btrhc7wMYHB/6x3IAhOo3NlVve068EvWgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nNQQS/btrhc7wMYHB/6x3IAhOo3NlVve068EvWgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnNQQS%2Fbtrhc7wMYHB%2F6x3IAhOo3NlVve068EvWgK%2Fimg.png&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;170&quot; data-filename=&quot;rhals.png&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Unity</category>
      <category>il2cpp</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/22</guid>
      <comments>https://zagara.tistory.com/22#entry22comment</comments>
      <pubDate>Sun, 10 Oct 2021 05:55:00 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 상태 패턴 : FSM 유한 상태 기계</title>
      <link>https://zagara.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;상태 패턴&lt;/b&gt;(state pattern)&lt;span style=&quot;color: #000000;&quot;&gt;은 객체 지향 방식으로 상태 기계를 구현하는 행위 소프트웨어 디자인 패턴이다. 상태 패턴을 이용하면 상태 패턴 인터페이스의 파생 클래스로서 각각의 상태를 구현함으로써, 또 패턴의 슈퍼클래스에 의해 정의되는 메소드를 호출하여 상태 변화를 구현함으로써 상태 기계를 구현한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%83%81%ED%83%9C_%ED%8C%A8%ED%84%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태패턴 - 위키백과&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;color: #000000;&quot;&gt;&lt;b&gt;&amp;lt;FSM 유한 상태 기계 특징&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태 : 가질 수 있는 상태가 한정되며 한 번에 한가지 상태만 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입력 : 입력이나 이벤트가 기계에 전달됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전이 : 각 상태에는 입력에 따라 다음상태로 바뀌는 전이가 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대부분 열거형을 통해 상태를 구분하고 그 중 하나를 현재의 상태로 저장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장된 상태에 해당하는 행동을 하거나, 데이터를 유지합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Ex) 전구의 ON / OFF&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;b&gt;&amp;lt;일반적 구현&amp;gt;&lt;/b&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;span style=&quot;color: #ee2323;&quot;&gt;① 상태 인터페이스의 정의&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태의 기본이 되는 &lt;u&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;&lt;span style=&quot;color: #ee2323;&quot;&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;&lt;span style=&quot;color: #ee2323;&quot;&gt;③ 상태패턴의 적용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태패턴이 적용되는 클래스에서는 기본 인터페이스를 필드로 가지고 상태가 변화함에 따라 인터페이스 필드에 상태 클래스들을 적용시키며 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1633379008500&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기본 인터페이스 ====================================================
interface human
{
    public void Init();
    public void Update();
}

// 상태 클래스 =========================================================
public class Run : human // 상태 : 달리기
{
    public void Init()
    {	
        // 달리는 애니메이션
        ...
    }
    
    public void Update()
    {
        // 위치 이동
        ...
    }
}

public class Attack : human // 상태 : 공격
{
    public void Init()
    {	
        // 공격 애니메이션
    }
    
    public void Update()
    {
        // 등등
    }
}

// 상태패턴이 적용될 클래스 ================================================

enum state { run, attack }

class player
{
    human _human = new human();
    state _state = state.run;
    
    // 상태 변경
    public void stateChange(state stt)
    { 
    	_state = stt;
        // 상태가 변경 될때 _human에 적용되는 상태도 달라집니다.
    	switch(_state)
        {
            Case state.run:
            	_human = new Run();
            	break;
            Case state.attack:
            	_human = new Attack();
            	break;
        }
    
    	_human.Init();
    }
    
    public void stateUpdate()
    {
        // 메서드는 항상 작동하지만
        // 상태가 변경됨에 따라 작동 내용은 달라집니다.
    	_human.Update();
    }
}&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;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;간단한 구현&amp;gt;&lt;/span&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;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태는 enum으로 컨트롤하며 상태마다 공통되는 메서드들을 클래스에 정의하고 메서드 내부에서 switch문 등을 통해 상태별 작동을 하게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1633379657426&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum state { idle, run, attack, die }

class player
{
    // 기본 상태
    state _state = state.idle;
    
    public void changeState(state stt)
    {
        _state = stt;
        stateInit();
    }
    
    public void stateInit()
    {
        switch(_state)
        {
            Case state.idle :
                // idle 초기화
                break;
            Case state.run :
                // run 초기화
                break;
            Case state.attack :
                // attack 초기화
                break;
            Case state.die :
                // die 초기화
                break;
        }
    }
    
    public void stateUpdate()
    {
        switch(_state)
        {
            Case state.idle :
                // idle 업데이트 행동
                break;
            Case state.run :
                // run 업데이트 행동
                break;
            Case state.attack :
                // attack 업데이트 행동
                break;
            Case state.die :
                // die 업데이트 행동
                break;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현은 더 간단하지만 상태가 많아지거나 하면 코드가 복잡해 질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;::: 상태 패턴은 외부에서 어떤 입력이 들어오던간에 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&amp;nbsp; 현재 상태에 정의되어 있는 행동만을 취할 수 있으므로 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&amp;nbsp; 개체의 행동을 분화하고 구체화하는데 좋다고 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;lt;(추천받은) 유니티에서 사용할만한 외부 라이브러리&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/thefuntastic/Unity3d-Finite-State-Machine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;- MonsterLove 상태머신&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;▶ enum을 통해 상태 목록을 정의하고 메서드 형식만 갖추면 쉽게 사용이 가능한 라이브러리입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&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;color: #000000;&quot;&gt;▶ 메서드 규칙은 &lt;span style=&quot;color: #ee2323;&quot;&gt;enum에서 정의한 상태명 + _(언더바) + 내장 메서드명&lt;/span&gt;으로 구성되며&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내장 메서드에는 Enter, Update, Exit등의 기본적인 메서드외에도 FixedUpdate, LateUpdate, OntriggerEnter2D등 다양하게 있다고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;※ 메서드는 내부적으로 리플렉션을 사용해 바인딩하는데 _언더바를 기준으로 메서드명을 읽는다고 합니다. 만약 double_jump 라는 상태가 있어 메서드명을 double_jump_Enter등으로 짓는다면 double이후의 이름을 내장메서드중 찾게 되고 실패하게 됩니다. 따라서 _는 이름중에 사용하지 않는 것이 좋겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1633380679083&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using MonsterLove.StateMachine; //1. Remember the using statement

public class MyGameplayScript : MonoBehaviour
{
    public enum States
    {
        Init, 
        Play, 
        Win, 
        Lose
    }
    
    StateMachine&amp;lt;States&amp;gt; fsm;
    
    void Awake(){
        fsm = new StateMachine&amp;lt;States&amp;gt;(this); //2. The main bit of &quot;magic&quot;. 

        fsm.ChangeState(States.Init); //3. Easily trigger state transitions
    }

    void Init_Enter()
    {
        Debug.Log(&quot;Ready&quot;);
    }

    void Play_Enter()
    {      
        Debug.Log(&quot;Spawning Player&quot;);    
    }

    void Play_FixedUpdate()
    {
        Debug.Log(&quot;Doing Physics stuff&quot;);
    }

    void Play_Update()
    {
        if(player.health &amp;lt;= 0)
        {
            fsm.ChangeState(States.Lose); //3. Easily trigger state transitions
        }
    }

    void Play_Exit()
    {
        Debug.Log(&quot;Despawning Player&quot;);    
    }

    void Win_Enter()
    {
        Debug.Log(&quot;Game Over - you won!&quot;);
    }

    void Lose_Enter()
    {
        Debug.Log(&quot;Game Over - you lost!&quot;);
    }

}&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;b&gt;&amp;lt;기본 사용팁&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. using&lt;/span&gt; &lt;span&gt;MonsterLove&lt;/span&gt;.&lt;span&gt;StateMachine&lt;/span&gt;; 선언&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 원하는 상태 enum 정의 ('_' 들어가면 안됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;StateMachine&amp;lt;TState(enum명)&amp;gt; &lt;/b&gt;&lt;/span&gt;선언 및&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt; 초기화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;StateMachine의 초기화에는 StateMachine&amp;lt;TState&amp;gt;.Initialize(this); 와 new StateMachine&amp;lt;TState&amp;gt;(this) 두가지 방법이 있습니다.&lt;/li&gt;
&lt;li&gt;그 외에 StateMachine이 작동하기 위해서는 StateMachineRunner 컴포넌트가 필요합니다.&lt;/li&gt;
&lt;li&gt;StateMachine의 초기화중 new로 초기화한다면 아마 작동하지 않을 것입니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;StateMachine&amp;lt;TState&amp;gt;.Initialize(this);는 사실 초기화 과정중 new StateMachine&amp;lt;TState&amp;gt;(this)를 이미 포함하며 초기화시 내부적으로 상태패턴이 적용되는 개체에 StateMachineRunner 컴포넌트를 Add해주어 작동이 가능하게 해줍니다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Changed 이벤트 사용&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Action&amp;lt;TState&amp;gt; Changed 이벤트 입니다.&lt;/li&gt;
&lt;li&gt;상태가 전이될때 할 일이 있다면 TState를 인자로 받는 메서드를 이벤트 체이닝하여 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&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-origin-width=&quot;800&quot; data-origin-height=&quot;433&quot; data-filename=&quot;jjang (1).png&quot; width=&quot;442&quot; height=&quot;239&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dunrXF/btrgDckz52v/l3ONlD8KdEI0Umgd7wYDEk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dunrXF/btrgDckz52v/l3ONlD8KdEI0Umgd7wYDEk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dunrXF/btrgDckz52v/l3ONlD8KdEI0Umgd7wYDEk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdunrXF%2FbtrgDckz52v%2Fl3ONlD8KdEI0Umgd7wYDEk%2Fimg.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;433&quot; data-filename=&quot;jjang (1).png&quot; width=&quot;442&quot; height=&quot;239&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>디자인 패턴</category>
      <category>monsterlove</category>
      <category>monsterlove초기화</category>
      <category>상태패턴</category>
      <category>스테이트패턴</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/21</guid>
      <comments>https://zagara.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 5 Oct 2021 06:09:25 +0900</pubDate>
    </item>
    <item>
      <title>[C#][자료구조] Tuple 튜플</title>
      <link>https://zagara.tistory.com/20</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MS Docs - https://docs.microsoft.com/ko-kr/dotnet/api/system.tuple?view=net-5.0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;Tuple&lt;/b&gt; : (1개 이상의 구성요소를 가질 수 있는 자료구조)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tuple&amp;lt;T1&amp;gt; ~ Tuple&amp;lt;T1, T2, T3, T4, T5, T6, T7&amp;gt; 까지 7개의 오버로드와&lt;/li&gt;
&lt;li&gt;Tuple&amp;lt;T1, T2, T3, T4, T5, T6, T7, TRest&amp;gt;의 8번째 오버로드로 구성되어 있습니다.&lt;/li&gt;
&lt;li&gt;using System을 사용합니다.&lt;/li&gt;
&lt;/ul&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;8번째 오버로드 : Tuple&amp;lt;T1, T2, T3, T4, T5, T6, T7, TRest&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;▶ T1 ~ T7까지는 일반적인 사용법과 같고 8번째 요소에는 반드시 Tuple이 들어가야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해 Tuple을 재귀적으로 물릴 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;▶ Tuple&amp;lt;1 ~ 7, Tuple&amp;lt;1 ~ 7, Tuple&amp;lt;1 ~ 7, Tuple&amp;lt;1 ~ 7, Tuple&amp;lt;1 ~ 7, ... &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;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;pre id=&quot;code_1631740950578&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Tuple&amp;lt;int, int&amp;gt; t2 = new Tuple&amp;lt;int, int&amp;gt;(8, 9);

// 매개변수를 넣어서 생성해줘야 한다.
Tuple&amp;lt;int, int, int, int, int, int, int, Tuple&amp;lt;int, int&amp;gt;&amp;gt; t8 
= new Tuple&amp;lt;int, int, int, int, int, int, int, Tuple&amp;lt;int, int&amp;gt;&amp;gt;(1, 2, 3, 4, 5, 6, 7, t2);

// T1 ~T7까지는 Item1 ~ Item7로 사용 
// 8번째는 Rest로 사용, 8번째 요소인 튜플의 요소인 경우 Tuple.Rest.Item1로 사용
Console.WriteLine(t8.Rest.Item2); // 9&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;▶ new를 사용한 생성외에도 &lt;b&gt;Tuple.Create()&lt;/b&gt;를 사용해 생성 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631742813028&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1 ~ 7 일반적인 경우
var t7 = Tuple.Create(1, 2, 3, 4, 5, 6, 7);

// 8개 일때
// Tuple.Create를 사용하면 8번째 인자를 자동으로 튜플로 감싸줍니다.
var t8 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);
// t8 = Tuple&amp;lt;int, int, int, int, int, int, int, Tuple&amp;lt;int&amp;gt;&amp;gt;

// Tuple.Create의 경우
// 만약 8개 이상 사용하기 위해 Tuple.Create를 중첩하여 사용하면 문제가 생깁니다.
var t10 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(1, 2, 3));
// t10 = Tuple&amp;lt;int, int, int, int, int, int, int, Tuple&amp;lt;Tuple&amp;lt;int, int, int&amp;gt;&amp;gt;&amp;gt;
// 이렇게 8번째 인자에 Tuple이 중첩되어 버립니다.
// t10.Rest.Item1.Item3 이렇게 이상하게 써야합니다.&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;/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;pre id=&quot;code_1632860764091&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var t2 = Tuple.Create(1, 2);

t2.item1 = 10; // Error 할 수 없습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;lt;유사&amp;gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ValueTuple&lt;/b&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;b&gt;Tuple 형식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;▶ C# 7.0 이상에서 사용할 수 있는 &amp;lsquo;튜플&amp;rsquo; 기능은 간단한 데이터 구조로 여러 데이터 요소를 그룹화하는 간결한 구문을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631743514468&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 튜플'형식'으로 Tuple과는 다릅니다.

// 다음과 같은 간단한 형식으로 사용가능합니다.
(float, int) t2 = (1.3f, 7);
(int, string, float, int) t4 = (8, &quot;서울&quot;, 1.3f, 40);
// 8개 이상도 가능합니다.
(int, int, int, int, int, int, int, int, int, int) t10 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 변수이름은 내부적으로 붙여줍니다.&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;b&gt;기능&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;pre id=&quot;code_1631743772571&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 다음과 같은 방법으로드필드명 설정이 가능합니다.
var t = (Sum: 4.5, Count: 3);
(double Sum, int Count) d = (4.5, 3);

// C# 7.1부터는 필드명을 설정하지 않아도 초기화식 변수이름에서 필드명이 유추됩니다.
var sum = 4.5;
var count = 3;
var t = (sum, count);
Console.WriteLine($&quot;Sum of {t.count} elements is {t.sum}.&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;▶ 합성 / 분해&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1631744247013&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 할당 ===============================================================================
// 두 튜플형식의 요소 수가 동일하고
// 우측 튜플요소의 형식이 좌측 튜플요소의 형식과 동일하거나 암시적 변환이 가능한 경우 할당이 가능합니다.
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;

// 분해 ===============================================================================
// 같은 경우
// 튜플형식으로부터 값을 변수로 나누거나 새로운 변수로 만들수 있습니다.
var t3 = (&quot;서울&quot;, 36.5f);
{ // 1번
    (string city, float Temp) = t3; 	
}
{ // 2번
    var (city, Temp) = t3;			
}
{ // 3번
    string city;					
    float Temp;
    (city, Temp) = t3;
}

// 여러 방법으로 분해할 수 있습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;굳이 클래스를 만들지 않고 Tuple로 간단하게 사용할 수도 있을 것 같습니다.&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-origin-width=&quot;270&quot; data-origin-height=&quot;210&quot; data-filename=&quot;아아아.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HevP4/btre9EXqC4s/slwu00cyk8qWOMkl8aeYGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HevP4/btre9EXqC4s/slwu00cyk8qWOMkl8aeYGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HevP4/btre9EXqC4s/slwu00cyk8qWOMkl8aeYGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHevP4%2Fbtre9EXqC4s%2Fslwu00cyk8qWOMkl8aeYGk%2Fimg.png&quot; data-origin-width=&quot;270&quot; data-origin-height=&quot;210&quot; data-filename=&quot;아아아.png&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>C#/자료구조</category>
      <category>tuple</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/20</guid>
      <comments>https://zagara.tistory.com/20#entry20comment</comments>
      <pubDate>Thu, 16 Sep 2021 07:24:09 +0900</pubDate>
    </item>
    <item>
      <title>[Unity][기초] 'Transform어쩌고' 좌표변환</title>
      <link>https://zagara.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Transform의 멤버함수 중에는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TransformDirection / TransformPoint / TransformVector 시리즈가 있다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;color: #333333;&quot;&gt;&lt;b&gt;1.&lt;/b&gt; public Vector3 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;TransformDirection&lt;/span&gt;&lt;/b&gt;(Vector3 direction); &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬공간에서 월드공간으로 /direction/을 변환합니다.&lt;/li&gt;
&lt;li&gt;이 연산은 transform의 &lt;u&gt;스케일이나 위치에 영향 받지 않습니다. &lt;/u&gt;&lt;/li&gt;
&lt;li&gt;반환된 벡터는 /direction/처럼 같은 길이를 갖습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629915564226&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Transform center;
Transform target;

center.TransformDirection(target.position);
// Rotation없이 사용하게 되면 target의 좌표가 그대로 나온다.
// 만약 center의 Rotation값이 변경되었다면
// Rotation없는 TransformDirection의 값을 변경된 Rotation만큼 회전시킨 값이 나온다.&lt;/code&gt;&lt;/pre&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-origin-width=&quot;720&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oBYus/btrc8hwDhrR/3kJkztovXyJL62oQKQbTT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oBYus/btrc8hwDhrR/3kJkztovXyJL62oQKQbTT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oBYus/btrc8hwDhrR/3kJkztovXyJL62oQKQbTT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoBYus%2Fbtrc8hwDhrR%2F3kJkztovXyJL62oQKQbTT1%2Fimg.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;2.&lt;/b&gt; public Vector3 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;TransformPoint&lt;/b&gt;&lt;/span&gt;(Vector3 position); &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬공간에서 월드 공간으로 /position/을 변환합니다.&lt;/li&gt;
&lt;li&gt;반환된 위치는 &lt;u&gt;스케일의 영향을 받습니다.&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;방향 벡터를 처리하는 경우에 사용합니다.&lt;/li&gt;
&lt;li&gt;반대(월드 공간 -&amp;gt; 로컬 공간)의 변환 : Transform.InverseTransformPoint&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629916315015&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Transform center;
Transform target;

center.TransformPoint(target.position);
// 값을 도출하는 방식은 TransformDirection과 같다.
// 다른 점은 기준이 되는 좌표가 center이다.
// center(월드좌표) + TransformDirection으로 보면 될 것같다.&lt;/code&gt;&lt;/pre&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-origin-width=&quot;720&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DwwLO/btrdeswNJ5u/JSfyeWJ3zQ8rkf2DZ7xj1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DwwLO/btrdeswNJ5u/JSfyeWJ3zQ8rkf2DZ7xj1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DwwLO/btrdeswNJ5u/JSfyeWJ3zQ8rkf2DZ7xj1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDwwLO%2FbtrdeswNJ5u%2FJSfyeWJ3zQ8rkf2DZ7xj1K%2Fimg.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;3.&lt;/b&gt; public Vector3 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TransformVector&lt;/b&gt;&lt;/span&gt;(Vector3 vector);&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬공간에서 월드 공간으로 /vector/을 변환합니다.&lt;/li&gt;
&lt;li&gt;이 연산은 transform의 위치에 영향을 받지 않지만 스케일에 영향을 받습니다.&lt;/li&gt;
&lt;li&gt;반환된 벡터의 길이가 벡터와 다를 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1629919714336&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Transform center;
Transform target;

center.TransformVector(target.position);
// 값을 도출하는 방식은 TransformDirection과 같다.
// 다른 점은 Scale에 영향을 받는다.
// TransformDirection * Scale로 보면 될 것같다.&lt;/code&gt;&lt;/pre&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-origin-width=&quot;720&quot; data-origin-height=&quot;366&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjoCnR/btrc9el4lP6/gqDZNK940PPLauCu9bHYWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjoCnR/btrc9el4lP6/gqDZNK940PPLauCu9bHYWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjoCnR/btrc9el4lP6/gqDZNK940PPLauCu9bHYWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjoCnR%2Fbtrc9el4lP6%2FgqDZNK940PPLauCu9bHYWk%2Fimg.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;366&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;center의 Rotation이 변화할때 각 함수&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 그래프&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;center(3, 3)과 target(1, 1) // scale 2&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&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;color: #ee2323;&quot;&gt;TransformDirection - scale에 변화없음, (0, 0)원점 기준&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;TransformPoint - scale에 영향, (0, 0)원점기준&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;TransformVector - scale에 영향, (3, 3)center 기준&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Unity/기초</category>
      <category>TransformDirection</category>
      <category>TransformPoint</category>
      <category>TransformVector</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/19</guid>
      <comments>https://zagara.tistory.com/19#entry19comment</comments>
      <pubDate>Thu, 26 Aug 2021 04:21:40 +0900</pubDate>
    </item>
    <item>
      <title>[Unity][기초] Transform 이동</title>
      <link>https://zagara.tistory.com/18</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Transform을 이용한 이동에는 간단하게 3가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transform.position / Transform.localPosition / Transform.Translate&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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. Transform.position&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 기본이 되는 방식으로 오브젝트의 위치를 직접 변경해주는 방식.&lt;/li&gt;
&lt;li&gt;절대좌표는 월드좌표를 따른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1629877400792&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 원하는 위치를 직접 대입하거나
Transform.position = new Vector3(1.0f, 2.0f, 3.0f);

// 현재위치를 기준으로 이동을 원하는 만큼 추가해주거나
Transform.position += Vector3.up;&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;2. Transform.localPosition&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 방식과 대부분 유사하다.&lt;/li&gt;
&lt;li&gt;절대좌표는 부모의 (rotation이 기울어져 있다면 기울어진) 좌표를 따른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1629877486138&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 원하는 위치를 직접 대입하거나
Transform.localPosition = new Vector3(1.0f, 2.0f, 3.0f);

// 현재위치를 기준으로 이동을 원하는 만큼 추가해주거나
Transform.localPosition += Vector3.up;&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;3. Transform.Translate&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방식은 position += Vector3 방식과 같다.&lt;/li&gt;
&lt;li&gt;절대좌표는 스스로의 좌표를 따른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1629877684968&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 현재위치를 기준으로 이동을 원하는 만큼 추가
Transform.Translate(Vector3.up);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629877748914&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TransformCheck : MonoBehaviour
{
    [SerializeField] Transform _obs0;
    [SerializeField] Transform _obs1;
    [SerializeField] Transform _obs2;

    private void Update()
    {
        _obs0.position += Vector3.up * Time.deltaTime;
        _obs1.localPosition += Vector3.up * Time.deltaTime;
        _obs2.Translate(Vector3.up * Time.deltaTime);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;500&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHbsDH/btrdd4vLJTG/x3FjLbNlNJeYiy7k9kYu0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHbsDH/btrdd4vLJTG/x3FjLbNlNJeYiy7k9kYu0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHbsDH/btrdd4vLJTG/x3FjLbNlNJeYiy7k9kYu0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHbsDH%2Fbtrdd4vLJTG%2Fx3FjLbNlNJeYiy7k9kYu0K%2Fimg.png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;500&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Unity/기초</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/18</guid>
      <comments>https://zagara.tistory.com/18#entry18comment</comments>
      <pubDate>Wed, 25 Aug 2021 17:11:15 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Attribute 애트리뷰트</title>
      <link>https://zagara.tistory.com/16</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;Attribute&lt;/b&gt;(속성)&lt;/span&gt; 는 class 의 위에 표시 되어, 스크립트 프로퍼티나 함수에 특별한 동작을 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/530/Manual/Attributes.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;유니티 - &lt;span&gt;Attribute(속성)&lt;/span&gt; 문서&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 인스펙터 노출 관련 Attribute&lt;/h4&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;[SerializeField]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 직렬화 해주는 기능으로 변수 위 혹은 왼쪽에 선언됩니다.&lt;/li&gt;
&lt;li&gt;private, protected로 선언된 변수들을 public 변수와 같이 inspector에서 수정가능하게 해줍니다.&lt;/li&gt;
&lt;li&gt;public과의 차이점 - 사실상 private, protected 선언이기 때문에 다른 클래스에서 접근할 수는 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628791257551&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [SerializeField]
    private int intValue = 2;
    [SerializeField]
    protected float floatValue = 3f;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;90&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xFaE3/btrbYtdcRLv/HwYgfoFe8tk0MKbDgUZKxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xFaE3/btrbYtdcRLv/HwYgfoFe8tk0MKbDgUZKxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xFaE3/btrbYtdcRLv/HwYgfoFe8tk0MKbDgUZKxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxFaE3%2FbtrbYtdcRLv%2FHwYgfoFe8tk0MKbDgUZKxk%2Fimg.png&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;90&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[System.Serializable]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;inspector에 보이지 않는 class, struct 변수를 일반변수처럼 inspector에 노출 및 수정하고자 사용됩니다.&lt;/li&gt;
&lt;li&gt;해당 class, struct를 직렬화하여 inspector에서 수정 및 확인이 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628791310167&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Serializable]
public class ClassA
{
    public int a;
    public int b;
}

public class SomeClass : MonoBehaviour
{
    public ClassA _classA;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;112&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BaK9K/btrb062LeL0/SbofOoGDGN3X23ZeglLOs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BaK9K/btrb062LeL0/SbofOoGDGN3X23ZeglLOs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BaK9K/btrb062LeL0/SbofOoGDGN3X23ZeglLOs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBaK9K%2Fbtrb062LeL0%2FSbofOoGDGN3X23ZeglLOs0%2Fimg.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;112&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[System.Nonserialized] vs &lt;b&gt;[HideInInspector]&lt;/b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Nonserialized와 HideInInspector 기능 - public으로 선언된 변수를 inspector에서 숨기고자 할때 사용됩니다.&lt;/li&gt;
&lt;li&gt;차이점은 Attribute 설정이전 inspector에서 값을 변경하고 Attribute를 설정했을때
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HideInInspector는 변경한 값이 저장되지만&lt;/li&gt;
&lt;li&gt;Nonserialized는 변경한 값이 저장되지 않으며 재생시 기본값으로 재설정됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628791413894&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [NonSerialized]
    public int _intValue;

    [HideInInspector]
    public float _floatValue;

    private void Start()
    {
        Debug.Log(_intValue);
        Debug.Log(_floatValue);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;92&quot; width=&quot;278&quot; height=&quot;85&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4bf5f/btrbXio6xWR/gGwe01hqZhfuUoJoVXkyok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4bf5f/btrbXio6xWR/gGwe01hqZhfuUoJoVXkyok/img.png&quot; data-alt=&quot;Attribute 설정전 inspector에서 값 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4bf5f/btrbXio6xWR/gGwe01hqZhfuUoJoVXkyok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4bf5f%2FbtrbXio6xWR%2FgGwe01hqZhfuUoJoVXkyok%2Fimg.png&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;92&quot; width=&quot;278&quot; height=&quot;85&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Attribute 설정전 inspector에서 값 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;81&quot; width=&quot;239&quot; height=&quot;85&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kHeXK/btrbZNbiwrI/k6jMUe9OAUySneKO3QTMI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kHeXK/btrbZNbiwrI/k6jMUe9OAUySneKO3QTMI1/img.png&quot; data-alt=&quot;Attribute 설정 후 실행 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kHeXK/btrbZNbiwrI/k6jMUe9OAUySneKO3QTMI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkHeXK%2FbtrbZNbiwrI%2Fk6jMUe9OAUySneKO3QTMI1%2Fimg.png&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;81&quot; width=&quot;239&quot; height=&quot;85&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Attribute 설정 후 실행 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. inspector 관련 소소한 커스텀&lt;/h4&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;[Header(string)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매개변수로 헤더로 사용할 string 형식의 단어를 넘겨줍니다.&lt;/li&gt;
&lt;li&gt;inspector에서 변수를 구분지어 보고 싶을때 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628793444553&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [Header(&quot;숫자&quot;)]
    public int _number;
    public int _count;

    [Header(&quot;String&quot;)]
    public string _name;
    public string _title;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;186&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vNxCS/btrbV0o6fAU/CAsCbVKQ0BK205VSYsbik0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vNxCS/btrbV0o6fAU/CAsCbVKQ0BK205VSYsbik0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vNxCS/btrbV0o6fAU/CAsCbVKQ0BK205VSYsbik0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvNxCS%2FbtrbV0o6fAU%2FCAsCbVKQ0BK205VSYsbik0%2Fimg.png&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;186&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[Space] / [Space(float)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;float값은 비워줄 공간의 길이입니다.&lt;/li&gt;
&lt;li&gt;값을 넣지않으면 기본값으로 설정됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628793748271&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    public int _number;
    [Space]
    public int _count;
    [Space(50)]
    public string _name;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;169&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzFEoY/btrbW21eJqt/ivXm0mn7GAw487cKQkKcf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzFEoY/btrbW21eJqt/ivXm0mn7GAw487cKQkKcf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzFEoY/btrbW21eJqt/ivXm0mn7GAw487cKQkKcf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzFEoY%2FbtrbW21eJqt%2FivXm0mn7GAw487cKQkKcf0%2Fimg.png&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;169&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[Tooltip(string)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ToolTip 매기변수로 string 형식의 설명을 넘겨줍니다.&lt;/li&gt;
&lt;li&gt;inspector에서 변수명에 마우스를 올렸을때 설명이 나타납니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628793947784&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [Tooltip(&quot;이런저런 내용&quot;)]
    public int _number;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brltwm/btrbV12wE29/Wa5CBoUxtohAgzIcJMmBa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brltwm/btrbV12wE29/Wa5CBoUxtohAgzIcJMmBa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brltwm/btrbV12wE29/Wa5CBoUxtohAgzIcJMmBa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrltwm%2FbtrbV12wE29%2FWa5CBoUxtohAgzIcJMmBa0%2Fimg.png&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[HelpURL(string형식의 주소)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스 상단에 선언하며 매개변수로 string형식의 주소를 넘겨줍니다.&lt;/li&gt;
&lt;li&gt;inspector의 component에서 물음표를 누르면 연결된 링크가 열립니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628794208020&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[HelpURL(&quot;https://zagara.tistory.com/&quot;)]
public class SomeClass : MonoBehaviour
{

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;52&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rCNqf/btrbYsSRdcG/tZVktopHqxt9eSlQrqvUX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rCNqf/btrbYsSRdcG/tZVktopHqxt9eSlQrqvUX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rCNqf/btrbYsSRdcG/tZVktopHqxt9eSlQrqvUX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrCNqf%2FbtrbYsSRdcG%2FtZVktopHqxt9eSlQrqvUX0%2Fimg.png&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;52&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. inspector의 변수 관련 커스텀&lt;/h4&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;[Range(float min, float max)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;int, float 숫자 형식의 변수에 사용가능합니다.&lt;/li&gt;
&lt;li&gt;inspector에서 편집시 설정된 min, max 값 이내에서만 수정이 가능합니다.&lt;/li&gt;
&lt;li&gt;코드에서 수정시 최초에 범위를 벗어나는 값을 입력했다면 초기화하는 부분에서 범위 이내로 수정해주지만 그 이후 변경되는 사항에 대해서는 그대로 적용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628794737731&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [Range(-3f, 5f)]
    public float _range = -8f;

    private void Start()
    {
        Debug.Log(_range);
        _range = 8;
        Debug.Log(_range);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;73&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjmmrH/btrb2aqbDx6/rdahhgtCQZBvCGaIueT9u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjmmrH/btrb2aqbDx6/rdahhgtCQZBvCGaIueT9u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjmmrH/btrb2aqbDx6/rdahhgtCQZBvCGaIueT9u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjmmrH%2Fbtrb2aqbDx6%2FrdahhgtCQZBvCGaIueT9u1%2Fimg.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;73&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;81&quot; width=&quot;289&quot; height=&quot;100&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dr7gDP/btrb22ZJvdr/pmXwwYqJR0k7s2f074kY6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dr7gDP/btrb22ZJvdr/pmXwwYqJR0k7s2f074kY6K/img.png&quot; data-alt=&quot;최초 설정된 -8은 범위값인 -3으로 수정해주지만 실행이후 변경된 값이 8의 경우 그대로 적용된 것을 볼 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dr7gDP/btrb22ZJvdr/pmXwwYqJR0k7s2f074kY6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdr7gDP%2Fbtrb22ZJvdr%2FpmXwwYqJR0k7s2f074kY6K%2Fimg.png&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;81&quot; width=&quot;289&quot; height=&quot;100&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;최초 설정된 -8은 범위값인 -3으로 수정해주지만 실행이후 변경된 값이 8의 경우 그대로 적용된 것을 볼 수 있습니다.&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;&lt;b&gt;[ColorUsage(bool 알파값활성화여부, bool HDR활성화 여부)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;color에 적용가능한 Attribute로 알파값을 없애거나 HDR을 활성화 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628795229328&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    // 첫번째 매개변수 - 알파값 활성화 여부
    // 두번째 매개변수 - HDR 활성화 여부
    [ColorUsage(false, true)] 
    public Color _color;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;642&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddVpC1/btrbVsltJZu/5LZOwCdkGY0Bkk6e8F0CM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddVpC1/btrbVsltJZu/5LZOwCdkGY0Bkk6e8F0CM1/img.png&quot; data-alt=&quot;알파가 없어지고 HDR이 생긴것을 확인할 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddVpC1/btrbVsltJZu/5LZOwCdkGY0Bkk6e8F0CM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddVpC1%2FbtrbVsltJZu%2F5LZOwCdkGY0Bkk6e8F0CM1%2Fimg.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;642&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;알파가 없어지고 HDR이 생긴것을 확인할 수 있습니다.&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;&lt;b&gt;[Multiline(int)] vs &lt;/b&gt;&lt;b&gt;[TextArea(int min, int max)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;둘다 긴 내용을 설정하거나 노출하고자 할때 사용됩니다.&lt;/li&gt;
&lt;li&gt;Multiline은 매개변수로 int형식의 줄 갯수를 받으며 내용을 입력하더라도 크기 변화없이 박스내에서 작성됩니다.&lt;/li&gt;
&lt;li&gt;TextArea는 매개변수로 int형식의 min,max 줄 갯수를 받으며 내용의 길이에 따라 범위내에서 유동적으로 변합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;또 TextArea는 최대 줄수 초과시 스크롤바가 생성됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628795659394&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [Multiline(5)]
    public string _string0;
    [TextArea(2,5)]
    public string _string1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;227&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKboWv/btrbW2mEs7J/nIfwMR0keZxQVe9cPWNP50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKboWv/btrbW2mEs7J/nIfwMR0keZxQVe9cPWNP50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKboWv/btrbW2mEs7J/nIfwMR0keZxQVe9cPWNP50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKboWv%2FbtrbW2mEs7J%2FnIfwMR0keZxQVe9cPWNP50%2Fimg.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;227&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;4. 에디터 관련 소소한 커스텀&lt;/b&gt;&lt;/h4&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;[AddComponentMenu(string 형식의 루트)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매개변수로 string형식의 루트 혹은 Component이름을 넣으면 inspector의 Add Component에 카테고리로 분류가 됩니다.&lt;/li&gt;
&lt;li&gt;루트를 넣지않으면 Component가 바로 노출되고&lt;/li&gt;
&lt;li&gt;루트를 넣으면 카테고리가 하위에 Component가 생성됩니다.&lt;/li&gt;
&lt;li&gt;이미 생성된 카테고리의 이름을 루트로 설정해도 해당 카테고리의 하위로 생성됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628802448759&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[AddComponentMenu(&quot;ThisIsTest&quot;)]
public class SomeClass : MonoBehaviour
{
    public string _string;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;417&quot; width=&quot;647&quot; height=&quot;312&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6xb9L/btrb0phk9JA/NCullY2QONLCAhIWxS1Nj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6xb9L/btrb0phk9JA/NCullY2QONLCAhIWxS1Nj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6xb9L/btrb0phk9JA/NCullY2QONLCAhIWxS1Nj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6xb9L%2Fbtrb0phk9JA%2FNCullY2QONLCAhIWxS1Nj1%2Fimg.png&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;417&quot; width=&quot;647&quot; height=&quot;312&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[UnityEditor.MenuItem(string 형식의 루트/정적 메소드명)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MenuItem는 매개변수로 string형식의 루트와 실행할 정적 메소드를 받으며 상단의 메뉴바에 배치됩니다.&lt;/li&gt;
&lt;li&gt;지금까지 다른 Attribute들은 루트가 필수가 아니었지만 MenuItem은 루트가 필수적으로 포함되어야 합니다.&lt;/li&gt;
&lt;li&gt;사용될 메소드는 정적메소드로 선언되어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628844873518&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    public string _string;

    [UnityEditor.MenuItem(&quot;TestEditor/MenuItemTest&quot;)]
    static void MenuItemTest()
    {
        Debug.Log(&quot;MenuItemTest&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2Q88b/btrb6tKyA37/bTdnQCetZibrRsU3A7NrBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2Q88b/btrb6tKyA37/bTdnQCetZibrRsU3A7NrBk/img.png&quot; data-alt=&quot;상단메뉴바에 배치된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2Q88b/btrb6tKyA37/bTdnQCetZibrRsU3A7NrBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2Q88b%2Fbtrb6tKyA37%2FbTdnQCetZibrRsU3A7NrBk%2Fimg.png&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;상단메뉴바에 배치된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;47&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJFaeB/btrb24drT10/mbco4lWJABxKpUfaELnyS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJFaeB/btrb24drT10/mbco4lWJABxKpUfaELnyS0/img.png&quot; data-alt=&quot;실행결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJFaeB/btrb24drT10/mbco4lWJABxKpUfaELnyS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJFaeB%2Fbtrb24drT10%2Fmbco4lWJABxKpUfaELnyS0%2Fimg.png&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;47&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;&lt;b&gt;[ContextMenu(string 형식의 메소드명)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매개변수로 실행하려는 메소드명을 넣어주면 됩니다.&lt;/li&gt;
&lt;li&gt;Component를 우클릭하여 뜨는 메뉴의 하단에 삽입됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628847068934&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    // 루트 없음
    [ContextMenu(&quot;MenuItemNoRoot&quot;)]
    void MenuItemNoRoot()
    {
        Debug.Log(&quot;MenuItemNoRoot&quot;);
    }

    // 루트 있음
    [ContextMenu(&quot;TestEditor/MenuItemRoot&quot;)]
    void MenuItemRoot()
    {
        Debug.Log(&quot;MenuItemRoot&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q81LH/btrb67HruTK/oAMQc7gBVGOh6Tc4yR43NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q81LH/btrb67HruTK/oAMQc7gBVGOh6Tc4yR43NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q81LH/btrb67HruTK/oAMQc7gBVGOh6Tc4yR43NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ81LH%2Fbtrb67HruTK%2FoAMQc7gBVGOh6Tc4yR43NK%2Fimg.png&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[ContextMenuItem(string 형식의 이름, string 형식의 메소드명)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관련된 필드위에 선언하여 inspector에서 해당 필드를 우클릭하여 실행할 수 있습니다.&lt;/li&gt;
&lt;li&gt;첫번째 매개변수는 노출되는 이름 / 두번째 매개변수는 실행하려는 메소드명을 넣어줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628851298217&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SomeClass : MonoBehaviour
{
    [ContextMenuItem(&quot;reset&quot;, &quot;resetNumber&quot;)]
    [ContextMenuItem(&quot;setFive&quot;, &quot;setNumberFive&quot;)]
    public int _number;
    
    void resetNumber()
    {
        _number = 0;
    }

    void setNumberFive()
    {
        _number = 5;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;123&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oxnw6/btrb8gqlmDY/PgloP4KNUXYSqwS9xOPlXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oxnw6/btrb8gqlmDY/PgloP4KNUXYSqwS9xOPlXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oxnw6/btrb8gqlmDY/PgloP4KNUXYSqwS9xOPlXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foxnw6%2Fbtrb8gqlmDY%2FPgloP4KNUXYSqwS9xOPlXK%2Fimg.png&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;123&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. Component 관련 Attribute&lt;/h4&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;[System.Obsolete]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;class 상단에 선언하여 사용되며 선언시 inspector에 이 Component는 사용되지 않는다는 경고문이 노출됩니다.&lt;/li&gt;
&lt;li&gt;사용에는 지장이 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628851670822&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[System.Obsolete]
public class SomeClass : MonoBehaviour
{

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;98&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3qVKK/btrb65W9gpk/D0rrJlV74669qoWth4styK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3qVKK/btrb65W9gpk/D0rrJlV74669qoWth4styK/img.png&quot; data-alt=&quot;해당 Component는 사용되지않는다고 경고가 뜬다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3qVKK/btrb65W9gpk/D0rrJlV74669qoWth4styK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3qVKK%2Fbtrb65W9gpk%2FD0rrJlV74669qoWth4styK%2Fimg.png&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;98&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;해당 Component는 사용되지않는다고 경고가 뜬다.&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;&lt;b&gt;[ExecuteInEditMode]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;플레이 상태가 아닐때도 업데이트가 코드가 호출됩니다.&lt;/li&gt;
&lt;li&gt;하지만 플레이 상태일때처럼 매프레임 호출되진않고 에디터상의 변경이 있을때만 호출됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에디터 창크기변경&lt;/li&gt;
&lt;li&gt;inspector를 포함한 Tap안에서의 값, 구조변경 등등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628852359120&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ExecuteInEditMode]
public class SomeClass : MonoBehaviour
{
    [Range(-5f,5f)]
    public float _num;

    public float _number;
    private void Update()
    {
        _number += Time.deltaTime;
        Debug.Log(_number);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;99&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KUDJV/btrb9Rp5CHr/0xdqPYdoIYcQWkgHyZGuV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KUDJV/btrb9Rp5CHr/0xdqPYdoIYcQWkgHyZGuV1/img.png&quot; data-alt=&quot;[Range]를 사용한 float값 변경시에도 호출됩니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KUDJV/btrb9Rp5CHr/0xdqPYdoIYcQWkgHyZGuV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKUDJV%2Fbtrb9Rp5CHr%2F0xdqPYdoIYcQWkgHyZGuV1%2Fimg.png&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;99&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Range]를 사용한 float값 변경시에도 호출됩니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;264&quot; data-origin-height=&quot;162&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzNEC4/btrb7b4ag5c/15yTjkrqc04zhw1AmM3d9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzNEC4/btrb7b4ag5c/15yTjkrqc04zhw1AmM3d9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzNEC4/btrb7b4ag5c/15yTjkrqc04zhw1AmM3d9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzNEC4%2Fbtrb7b4ag5c%2F15yTjkrqc04zhw1AmM3d9k%2Fimg.png&quot; data-origin-width=&quot;264&quot; data-origin-height=&quot;162&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[RequireComponent(typeof(Component))]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매개변수로는 Component를 typeof(Component)형식으로 넣어줍니다.&lt;/li&gt;
&lt;li&gt;매개변수로 넘겨준 Component는 오브젝트에 해당 클래스 Component를 Add Component시 함께 추가됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628853277369&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[RequireComponent(typeof(BoxCollider))]
public class SomeClass : MonoBehaviour
{

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;232&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNS1lJ/btrb7zRfhFU/3jFQYoq4dtO9axylVFkSBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNS1lJ/btrb7zRfhFU/3jFQYoq4dtO9axylVFkSBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNS1lJ/btrb7zRfhFU/3jFQYoq4dtO9axylVFkSBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNS1lJ%2Fbtrb7zRfhFU%2F3jFQYoq4dtO9axylVFkSBk%2Fimg.png&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;232&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;b&gt;[DisallowMultipleComponent]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Component가 2개 이상 중복으로 적용되지 않도록 해줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628853908378&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[DisallowMultipleComponent]
public class SomeClass : MonoBehaviour
{

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;152&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KVat2/btrb07aSYln/Rod2cHhFpeV8lKkNqb2LdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KVat2/btrb07aSYln/Rod2cHhFpeV8lKkNqb2LdK/img.png&quot; data-alt=&quot;2개이상 추가시 오류메세지가 뜹니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KVat2/btrb07aSYln/Rod2cHhFpeV8lKkNqb2LdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKVat2%2Fbtrb07aSYln%2FRod2cHhFpeV8lKkNqb2LdK%2Fimg.png&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;152&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;2개이상 추가시 오류메세지가 뜹니다.&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;&lt;b&gt;[CreateAssetMenu(fileName = string 형식의 파일 이름, menuName = string 형식의 루트)]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CreateAssetMenu은 ScriptableObject 스크립트를 이용해서 에셋을 생성할 수 있게 만들어줍니다.&lt;/li&gt;
&lt;li&gt;Project 탭에서 우클릭 했을때 Create 하위에 생성됩니다.&lt;/li&gt;
&lt;li&gt;MonoBehaviour가 아닌 ScriptableObject를 상속하여 만들어진 클래스에만 사용 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628855031748&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[CreateAssetMenu(fileName = &quot;Test Data&quot;, menuName = &quot;Scriptable Object/Test Data&quot;)]
public class SomeClass : ScriptableObject
{
    public int _numA;
    public int _numB;
    public int _numC;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;161&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baYZUC/btrb8gxaAo4/OoG0xILbZAoHyyzFNs10nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baYZUC/btrb8gxaAo4/OoG0xILbZAoHyyzFNs10nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baYZUC/btrb8gxaAo4/OoG0xILbZAoHyyzFNs10nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaYZUC%2Fbtrb8gxaAo4%2FOoG0xILbZAoHyyzFNs10nk%2Fimg.png&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;161&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;141&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnHklz/btrb1wV53Zx/0wITEhDnRJTd9twTJF1iJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnHklz/btrb1wV53Zx/0wITEhDnRJTd9twTJF1iJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnHklz/btrb1wV53Zx/0wITEhDnRJTd9twTJF1iJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnHklz%2Fbtrb1wV53Zx%2F0wITEhDnRJTd9twTJF1iJ1%2Fimg.png&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;141&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-noaft=&quot;1&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;480&quot; data-filename=&quot;blob&quot; width=&quot;232&quot; height=&quot;174&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2FIA4/btrb2aZv1PB/szFlUt3es2g7qJLm4hL6FK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2FIA4/btrb2aZv1PB/szFlUt3es2g7qJLm4hL6FK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2FIA4/btrb2aZv1PB/szFlUt3es2g7qJLm4hL6FK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2FIA4%2Fbtrb2aZv1PB%2FszFlUt3es2g7qJLm4hL6FK%2Fimg.png&quot; data-noaft=&quot;1&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;480&quot; data-filename=&quot;blob&quot; width=&quot;232&quot; height=&quot;174&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Unity</category>
      <category>attribute</category>
      <category>unity</category>
      <category>애트리뷰트</category>
      <author>자가라o</author>
      <guid isPermaLink="true">https://zagara.tistory.com/16</guid>
      <comments>https://zagara.tistory.com/16#entry16comment</comments>
      <pubDate>Fri, 13 Aug 2021 21:00:04 +0900</pubDate>
    </item>
  </channel>
</rss>