<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코보 게임 일지</title>
    <link>https://nanaya0630.tistory.com/</link>
    <description>초코보가 세상을 지배할 것이다.</description>
    <language>ko</language>
    <pubDate>Thu, 11 Jun 2026 15:35:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>초코보</managingEditor>
    <image>
      <title>코보 게임 일지</title>
      <url>https://tistory1.daumcdn.net/tistory/7253877/attach/93d95bdb8acd4ae7ba2438a2a1842cd9</url>
      <link>https://nanaya0630.tistory.com</link>
    </image>
    <item>
      <title>[Unity] 애니메이션 (작성중)</title>
      <link>https://nanaya0630.tistory.com/81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Animator]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;씬에서 게임 오브젝트에 애니메이션을 지정할 때 사용한다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Animation Controller]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상황에 따라 특정 행동을, 어떤 순서로 진행할 것인지 지정한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;331&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCnEz/dJMcagZYqjE/SZxY2WZaEKysrpjzsmdgM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCnEz/dJMcagZYqjE/SZxY2WZaEKysrpjzsmdgM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCnEz/dJMcagZYqjE/SZxY2WZaEKysrpjzsmdgM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCnEz%2FdJMcagZYqjE%2FSZxY2WZaEKysrpjzsmdgM0%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;331&quot; height=&quot;189&quot; data-origin-width=&quot;331&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Controller : 해당 Animator을 조종할 AnimationController를 할당한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U6kAq/dJMcaijdT0t/Sl2oz6vYVBihaldlfrRXf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U6kAq/dJMcaijdT0t/Sl2oz6vYVBihaldlfrRXf1/img.png&quot; data-alt=&quot;Create - Animation - Animator controller. 폴더를 따로 만들어 보관하자.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U6kAq/dJMcaijdT0t/Sl2oz6vYVBihaldlfrRXf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU6kAq%2FdJMcaijdT0t%2FSl2oz6vYVBihaldlfrRXf1%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;573&quot; height=&quot;45&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Create - Animation - Animator controller. 폴더를 따로 만들어 보관하자.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Avatar : 조종될 3D모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apply Root Motion : 게임 오브젝트의 위치, 회전을 Animation에서 제어할 수 있도록 허용하는 옵션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(Animation 제작 시 3D 모션의 자세, 물체 위치, 회전 변경을 위한 제작. 해당 글에서는 플레이어 위치를 스크립트로 만들기에 off)&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;[InputSystem]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;95&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1aQ6o/dJMcaarZlgM/Hw0oud39LeFf0dvnD073V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1aQ6o/dJMcaarZlgM/Hw0oud39LeFf0dvnD073V0/img.png&quot; data-alt=&quot;project - Assets - InputSystem&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1aQ6o/dJMcaarZlgM/Hw0oud39LeFf0dvnD073V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1aQ6o%2FdJMcaarZlgM%2FHw0oud39LeFf0dvnD073V0%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;95&quot; height=&quot;106&quot; data-origin-width=&quot;95&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;project - Assets - InputSystem&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 사용한 InputManager를 대체하는, 유니티의 새로운 입력 시스템.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Update에서 매프레임마다 입력을 확인하며, 입력 발생 시 이벤트를 발생시켜 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점: 매번 키 입력을 해야 하며, 모바일/콘솔 대응이 불편하다.&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;[2D Vector]&lt;/b&gt;&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;&lt;b&gt;[유한 상태 기계 Finite State Machine, FSM]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유한한 개수의 상태(State)를 기반으로 동작하는 컴퓨터 과학 및 수학적 모델.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;한 번에 하나의 상태만&lt;/u&gt; 활성화되며, 조건에 따라 &lt;u&gt;현 상태에서 다른 상태로 전환&lt;/u&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: #9d9d9d;&quot;&gt;장: 예측가능성(가독성, 쉬운 디버깅), 안정성(한 번에 하나의 상태만 처리, 꼬일 위험 낮음)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;좀 더 복잡한 AI를 만들 땐 행동트리(BeHaviour Tree)를 활용할 수도 있다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXiOnT/dJMcahYUf2C/HaYZr4xme6AK37Y70rpPD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXiOnT/dJMcahYUf2C/HaYZr4xme6AK37Y70rpPD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXiOnT/dJMcahYUf2C/HaYZr4xme6AK37Y70rpPD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXiOnT%2FdJMcahYUf2C%2FHaYZr4xme6AK37Y70rpPD1%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;572&quot; height=&quot;89&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Empty : 아무 애니메이션 클립도 재생하지 않는 기본 대기 상태(Idle. 숨쉬기 대기 모션)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Blend Tree : 여러 애니메이션을 부드럽게 혼합(Blending)하여 자연스러운 움직임을 만들어내는 기능. 걷기와 뛰기, 캐릭터의 이동 방향에 따른 애니메이션을 자연스레 전환할 때 사용한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yK5T3/dJMcadPG71o/jwTgECFKeJ6Lo6TQS3ITm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yK5T3/dJMcadPG71o/jwTgECFKeJ6Lo6TQS3ITm0/img.png&quot; data-alt=&quot;Motion에 애니메이션을 넣은 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yK5T3/dJMcadPG71o/jwTgECFKeJ6Lo6TQS3ITm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyK5T3%2FdJMcadPG71o%2FjwTgECFKeJ6Lo6TQS3ITm0%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;339&quot; height=&quot;123&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Motion에 애니메이션을 넣은 상태&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbDwyB/dJMcaaMfuqd/gDvST9N9LsWttKKL6fJJP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbDwyB/dJMcaaMfuqd/gDvST9N9LsWttKKL6fJJP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbDwyB/dJMcaaMfuqd/gDvST9N9LsWttKKL6fJJP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbDwyB%2FdJMcaaMfuqd%2FgDvST9N9LsWttKKL6fJJP1%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;247&quot; height=&quot;88&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0oal2/dJMcahR7qMz/k6rPe73ekz1ZiKBwJKRs5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0oal2/dJMcahR7qMz/k6rPe73ekz1ZiKBwJKRs5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0oal2/dJMcahR7qMz/k6rPe73ekz1ZiKBwJKRs5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0oal2%2FdJMcahR7qMz%2Fk6rPe73ekz1ZiKBwJKRs5K%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;170&quot; height=&quot;111&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;111&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;애니메이션 클립 우클릭 - Make Transition 후 화살표를 연결할 클립을 선택하여 연결해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;104&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZlATA/dJMcacpNVeF/KwLwnv1cCCpkX59yY2wnK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZlATA/dJMcacpNVeF/KwLwnv1cCCpkX59yY2wnK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZlATA/dJMcacpNVeF/KwLwnv1cCCpkX59yY2wnK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZlATA%2FdJMcacpNVeF%2FKwLwnv1cCCpkX59yY2wnK0%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;104&quot; height=&quot;91&quot; data-origin-width=&quot;104&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nzxKP/dJMb990VBLB/lVlpbTFyjd1Ki5YN7sSKH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nzxKP/dJMb990VBLB/lVlpbTFyjd1Ki5YN7sSKH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nzxKP/dJMb990VBLB/lVlpbTFyjd1Ki5YN7sSKH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnzxKP%2FdJMb990VBLB%2FlVlpbTFyjd1Ki5YN7sSKH0%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;332&quot; height=&quot;344&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&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;Has Exit Time : 상태를 이어주는 옵션. 현재 재생 중인 애니를 끝까지 틀고 다음 애니로 넘어갈지(true), 조건이 충족되는 순간 즉시 끊고 넘어갈 지(false) (switch 역할)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Conditions : 애니메이션 상태가 전환되는 기준. 만족 시 애니메이션이 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;해당 이미지의 경우, (int)Equals이 0일 시 전환 발생(1일 시 유지)&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QrnRf/dJMb99T64ED/kpZbGLsOfmHP1kGFJ7DKg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QrnRf/dJMb99T64ED/kpZbGLsOfmHP1kGFJ7DKg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QrnRf/dJMb99T64ED/kpZbGLsOfmHP1kGFJ7DKg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQrnRf%2FdJMb99T64ED%2FkpZbGLsOfmHP1kGFJ7DKg0%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;203&quot; height=&quot;102&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Parameters : 상태 제어 스크립트(Conditions 등)에 접근하여 값을 할당하여 상태를 제어하거나 영향을 줄 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;float: 속도, 체력 등 소수점 포함된 값 비교&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;int: 카운트, 레벨 등 정수 값 비교&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;bool: true/false 형태로 상태 체크&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;trigger: 일회성 이벤트/공격 동작에 사용. 실행 시 자동 초기화&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nRfig/dJMcaicvA1Q/hneYj16pXtotSVfGnLlz4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nRfig/dJMcaicvA1Q/hneYj16pXtotSVfGnLlz4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nRfig/dJMcaicvA1Q/hneYj16pXtotSVfGnLlz4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnRfig%2FdJMcaicvA1Q%2FhneYj16pXtotSVfGnLlz4K%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;651&quot; height=&quot;147&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/37k5x/dJMcafmxkjN/axyopnOGCJ2OGTVknWIU10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/37k5x/dJMcafmxkjN/axyopnOGCJ2OGTVknWIU10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/37k5x/dJMcafmxkjN/axyopnOGCJ2OGTVknWIU10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F37k5x%2FdJMcafmxkjN%2FaxyopnOGCJ2OGTVknWIU10%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;201&quot; height=&quot;86&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHiqPi/dJMcabqTjog/iuC57S54b3W9QtPJTneHGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHiqPi/dJMcabqTjog/iuC57S54b3W9QtPJTneHGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHiqPi/dJMcabqTjog/iuC57S54b3W9QtPJTneHGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHiqPi%2FdJMcabqTjog%2FiuC57S54b3W9QtPJTneHGK%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;736&quot; height=&quot;350&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;이후, Player 부모 오브젝트에 Character Controller 컴포넌트 추가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Skin Width : 스킨 너비. 콜라이더 걷면에 보이지 않는 미세한 두께(여유 공간)를 만들어 충돌을 매끄럽게 처리하고 떨림 현상을 방지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐릭터 컨트롤러의 중심점(Center), 반지름(Radius), 높이(Height)도 3D 크기에 맞게 설정해준다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[InputAction]&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Input System 패키지 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조적이고 유연하게 처리하는 구성요소. 하나의 입력 동작을 표현하는 객체. 행동에 집중한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Action Map, Action, Blinding, Type, Control Type...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당된 Input Actions에 따라 메서드가 연결된다.&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;[ .ReadValue&amp;lt;T&amp;gt;() ]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;InputAction에서 사용되는 메서드. 입력 값 추출. (&amp;lt;Vector2&amp;gt;, &amp;lt;float&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;[RotateTowards]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연스럽고 부드러운 회전을 구현할 때 사용하는 메서드.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적지를 향해 일정 속도로 각도를&amp;nbsp; 좁혀가며 회전하는 데 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Quaternion.RotateTowards (오브젝트 회전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 오브젝트가 자신의 방향(기존 회전값)에서 목표 방향으로 지정 속도(각도)만큼 회전&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Quaternion.RotateTowards(현 회전값(from), 목표 회전값(to), 최대 회전 각도)&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;- Vector3.RotateTowards (방향 벡터 회전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 오브젝트 자체가 아닌, 방향을 나타내는 Vector3 값 자체를 목표 방향으로 서서히 회전&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vector3.RotateTowards(현 방향(current), 목표 방향(target), 최대 반지름, 최대 거리 변화율)&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;[SetInteager]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애니메이터 컴포넌트의 int 파라미터 값을 변경, 애니메이션 상태 전환 시 사용하는 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;animator.SetInteager(&quot;파라미터명&quot;, 값);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[OnEnable()]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트가 &lt;u&gt;활성화 될 때마다 호출&lt;/u&gt;되는 생명주기 메서드. 상태 변경 시 필요한 초기화 작업 수행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Awake와 Start는 최초 1회, OnEnable은 Game object각 active 될 때마다 실행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서는 Awake - OnEnable - Start&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;[OnDisable()]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 오브젝트가 비활성화(중단)될 때 호출되는 생명주기 메서드.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;활성화(OnEnable)와 비활성화(OnDisable)를 반복할 때마다 매번 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;&lt;br /&gt;[OnAnimatorMove()]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애니메이션 움직임(루트 모션 Root Motion)을 스크립트에서 직접 제어 할 수 있게 하는 생명주기 메서드.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Animator의 Root Motion 옵션 체크 시, 애니메이션 시스템이 트랜스폼을 제어한다.&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: #9d9d9d;&quot;&gt;미끄러짐 방지, 물리 충돌 처리 등에 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Root Motion을 통해 애니메이션이 이동한 거리는 deltaPosition으로 얻을 수 있다.&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;[Physics.gravity]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;씬 내 모든 Rigidbody에 작용하는 전역 중력 가속도 값.&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;[squrMagnitude]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벡터 길이(Magnitude)를 제곱한 값을 반환하는 프로퍼티.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크기를 구할 땐 Magnitude를 사용하나, 제곱값이 필요할 땐 sqrMagnitude를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제곱근(루트)계산은 cpu 연산 비용이 많이 들기에, 성능 최적화 시 사용된다.&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;[UnityEvent &amp;lt;&amp;gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;using UnityEngine.Events;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티에서 제공하는 내장 이벤트 시스템. 유니터 에디터 인스펙터 창에서 드래그 앤 드롭을 통해 이벤트를 쉽게 연결하고 관리할 수 있게 한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/81</guid>
      <comments>https://nanaya0630.tistory.com/81#entry81comment</comments>
      <pubDate>Tue, 2 Jun 2026 14:33:10 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Find, Coroutine</title>
      <link>https://nanaya0630.tistory.com/80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Find 계열]&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;[주의사항]&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;Update 반복 호출 시 문제 발생(Awake나 Start에서 한 번만 찾아서 사용해야 한다)&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;Find 계열을 써야하는 상황은 분명 있으나, 비용이 크기 때문에 성능 저하의 주 원인이 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//대체 1: 인스펙터 직접 할당&lt;/span&gt;&lt;br /&gt;&lt;b&gt;[SerializeField]&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//대체 2: 코드 중심 접근 필요 시, 컴포넌트 직접 탐색&lt;/span&gt;&lt;br /&gt;&lt;b&gt;[GetComponentInChildren]&lt;/b&gt;&lt;br /&gt;: 현재 오브젝트의 자식 방향으로 컴포넌트를 찾는다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 캐릭터 모델 속 애니메이션 찾기, 무기 속 총구 위치 찾기, 전체 UI에서 특정 자식 버튼 찾기 등&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[GetComponentInParent]&lt;/b&gt;&lt;br /&gt;: 현재 오브젝트의 부모 방향으로 컴포넌트를 찾는다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 히트박스 내에서 캐릭터 본체 찾기, UI 버튼 위의 UI 컨트롤러 찾기, 무기를 들고있는 Player 찾기 등&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//대체3: 이름 대신 태그/타입 Find를 사용한다.&lt;/span&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;b&gt;[종류]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. GameObject.Find(&quot;이름&quot;)&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;2. GameObject.FindWithTag(&quot;태그&quot;)&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;/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. GameObjects.FindGameObjectWithTag(&quot;태그&quot;);&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;&lt;b&gt;4. GameObject.FindAnyObjectByType&amp;lt;GameManager&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;5. FindObjectsByType&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;배열 탐색. 매우 무겁다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[코루틴 Coroutine]&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;/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;일반적인 메서드는 호출 시 해당 프레임 안에서 모든걸 마치고 값을 반환한다. 때문에 무거운 연산을 한 프레임에 처리를 시도할 시 렉이 발생한다(Update의 반복호출)&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;이제부턴 상황에 따라 Update와 코루틴을 번갈아가며 사용하게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코루틴을 잘 응용할 시, Update만 사용하는 것 보다 최적화/가독성 을 챙길 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 몇 초 뒤 실행, 일정 시간마다 반복 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(공격 딜레이, 총알 발사 간격 조절, 몬스터 스폰, UI 페이드인/아웃, 재장전, 스킬쿨, 웨이브 시스템 등)&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;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Update 반복 호출 시 문제 발생(Start에서 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 안전하게 사용한다면 OnDisable()에서 StopCoroutine 을 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #a6bc00;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//IEnumerator 타입 메서드를 사용하여 정의되며, &lt;span style=&quot;color: #f3c000;&quot;&gt;StartCoroutine &lt;/span&gt;메서드를 통해 시작된다.&lt;br /&gt;//IEumeator: 컬렉션 요소를 하나씩 순차적으로 접근하는 방법 정의. 콜렉션 네임스페이스 사용.&lt;br /&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;using&lt;/span&gt; System.Collections;&lt;span style=&quot;color: #009a87;&quot;&gt; //네임스페이스&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;void Start&lt;/span&gt;()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #f3c000;&quot;&gt;StartCoroutine&lt;/span&gt;(&lt;span style=&quot;color: #f3c000;&quot;&gt;코루틴 이름&lt;/span&gt;()); &lt;span style=&quot;color: #009a87;&quot;&gt;//코루틴 시작&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;IEumerator&lt;/span&gt; &lt;span style=&quot;color: #f3c000;&quot;&gt;코루틴 이름&lt;/span&gt;()&lt;span style=&quot;color: #009a87;&quot;&gt; //코루틴 내용&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #c1bef9;&quot;&gt;yield return&lt;/span&gt; ~대기조건~;&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;b&gt;[자주 사용되는 yield return 목록]&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield return null;&lt;/span&gt; : 다음 프레임 까지 대기&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield return new WaitForSeconds(float time);&lt;/span&gt; : 지정 시간(초)대기&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield return new WaitForSecondsRealtime(float time);&lt;/span&gt; : (현실시간 기준)지정 시간 대기&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield return new WaitForFixedUpdate();&lt;/span&gt; : 다음 물리 프레임까지 대기(물리 연산 연동시 사용)&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield return StartCoroutine(다른 코루틴 이름)&lt;/span&gt; : 다른 코루틴 종료까지 대기&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;yield break;&lt;/span&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;b&gt;[예제 코드]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 코드는 Update메서드와 Coroutine은 같은 내용을 실행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1779949822119&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections; //IEnumerator 사용
using UnityEngine;

public class CoBasic : MonoBehaviour
{
	//Update메서드와 Coroutine메서드 선택 사용
    public enum TestMode{UpdateMethod, CoroutineMethod }
    [Header(&quot;테스트 선택&quot;)]
    public TestMode currentMode = TestMode.CoroutineMethod;

	//Update용 변수
    private int updateCount = 0; //실행 카운트
    private float updateTimer = 0.0f; //타이머
    private bool updateWaiting = true; //대기

	//Start에서 코루틴 호출
    private void Start()
    {
        if(currentMode == TestMode.CoroutineMethod) //Coroutine메서드 선택 시 실행될 내용
        {
        	//[1]
            StartCoroutine(PrintNumberCo());
            //[2]
            StartCoroutine(PrintDelayCo());
            //[3]
            StartCoroutine(MainRoutineCo());
        }
    }
    
    //업데이트
    void Update()
    {
        if(currentMode == TestMode.UpdateMethod) //Update메서드 선택 시 실행될 내용
        {
            //[1] 매프레임 5번 실행
            if(updateCount&amp;lt;5)
            {
                Debug.Log($&quot;{updateCount}&quot;);
                updateCount++;
            }
            
            //[2] 1초에 1번, 총 3번 실행
            if(updateCount&amp;lt;3)
            {
                updateTimer += Time.deltaTime; //시간보정
                if(updateTimer&amp;gt;=1.0f) //1초 경과시 실행
                {
                    Debug.Log($&quot;{updateCount}&quot;);
                    updateCount++;
                    updateTimer = 0.0f;
                }
            }
            //[3] 2초 대기 후 실행
            if(updateWaiting)
            {
                updateTimer += Time.deltaTime; //시간보정
                if (updateTimer &amp;gt;= 2.0f) //2초 경과시 실행
                {
                    Debug.Log(&quot;딜레이?&quot;);
                    updateWaiting = false;
                }
            }    
        }
    }
    
    //코루틴
    //[1] 매프레임 5번 실행
    IEnumerator PrintNumberCo()
    {
        for (int i = 0; i &amp;lt; 5; i++)
        {
            Debug.Log($&quot;{i}&quot;);
            yield return null; //다음 프레임까지 대기
        }
    }
    
    //[2] 1초에 1번, 총 3번 실행
    IEnumerator PrintDelayCo()
    {
        for(int i = 0; i&amp;lt;3; i++)
        {
            Debug.Log($&quot;{i}&quot;);
            yield return new WaitForSeconds(1.0f); //1초 대기
        }
        /*
        //코루틴 캐싱: 미리 선언 후 재사용, 반복 생성 방지
        자주 반복되는 구문에서 최적화를 위해 사용하기도 한다
        while (true)
        {
            yield return new WaitForSeconds(0.1f);
        }
        */
    }
    
    //[3] 2초 대기(실행 후 중단, WaitPrintCo 종료 후, 실행)
    IEnumerator MainRoutineCo()
    {
        Debug.Log(&quot;코루틴 첫번째&quot;);
        yield return StartCoroutine(WaitPrintCo()); //다른 코루틴(WaitPrintCo)종료까지 대기
        Debug.Log(&quot;모든 루틴 완료&quot;);
    }
    IEnumerator WaitPrintCo()
    {
        yield return new WaitForSeconds(2.0f); //2초 대기 후 실행
        Debug.Log(&quot;딜레이 완료&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;해당 코드는 코루틴을 통해 Update 메서드 없이 오브젝트의 머테리얼 색상을 변경하는 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1779951039109&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections; //IEnumerator 사용
using UnityEngine;

public class CoTest : MonoBehaviour
{
    private Renderer cubeRenderer; //렌더러 = cubeRenderer
    private Material cubeMaterial; //머테리얼 = cubeMaterial
    private WaitForSeconds wait; //코루틴의 WaitForSeconds
    void Start()
    {
        cubeRenderer = GetComponent&amp;lt;Renderer&amp;gt;(); //렌더러 가져오기
        cubeMaterial = cubeRenderer.material; //렌더러의 머테리얼 가져오기
        wait = new WaitForSeconds(1.0f); //wait = 1초 대기

        StartCoroutine(ChangeColorCo()); //코루틴 실행
    }
    
    IEnumerator ChangeColorCo()
    {
        while(true)
        {
        //머테리얼 값이 null일 시
            if (cubeMaterial == null) yield break; //코루틴 즉시 종료
	//null이 아닐 시, rgb(255,255,255)내에서 랜덤 변경
            cubeMaterial.color = new Color(Random.value, Random.value, Random.value);

            yield return wait; //new WaitForSeconds(1.0f)
        }
    }
}&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 data-ke-size=&quot;size16&quot;&gt;[1] Update 사용 코드&lt;/p&gt;
&lt;pre id=&quot;code_1779951404132&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//코루틴 없이 방방 뛰는걸 구현해보자
using UnityEngine;

public class CoTest2 : MonoBehaviour
{
    [SerializeField] private float bounceHeight = 2.0f;
    [SerializeField] private float bounceDuration = 1.0f;

    //Update용 변수값
    private Vector3 startPosition;
    private Vector3 targetPosition;
    private float elapsedTime = 0.0f; //경과시간
    private bool movingUp = true;
    
    void Start()
    {
        startPosition = transform.position; //오브젝트 시작위치
        targetPosition = startPosition + new Vector3(0.0f, bounceHeight, 0.0f); //시작위치 + y축 2.0
    }

    void Update()
    {
        elapsedTime += Time.deltaTime; //프레임 보정

        if(movingUp) //true일 시 상승
        {
            //y값을 부드럽게 이동(시작위치에서, 시작위치 + y축 2.0 까지, 경과시간/1초 값 만큼)
            transform.position = Vector3.Lerp(startPosition, targetPosition, elapsedTime / bounceDuration);
        }
        else //false일 시 하강
        {
            //y값을 부드럽게 이동(시작위치 + y축 2.0 에서, 시작위치까지, 경과시간/1초 값 만큼)
            transform.position = Vector3.Lerp(targetPosition, startPosition, elapsedTime / bounceDuration);
        }
        
        if (elapsedTime &amp;gt;= bounceDuration) //이동시간이 Duration(1초)을 넘으면 한 사이클 종료
        {
            elapsedTime = 0.0f; //경과 시간 초기화 후
            movingUp = !movingUp; //false 반환
        }
    }
}&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] Coroutine 사용 코드&lt;/p&gt;
&lt;pre id=&quot;code_1779951411713&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//코루틴으로 방방 뛰는걸 구현해보자
using System.Collections;
using UnityEngine;

public class CoTest2 : MonoBehaviour
{
    [SerializeField] private float bounceHeight = 2.0f;
    [SerializeField] private float bounceDuration = 1.0f;

    void Start()
    {
        StartCoroutine(BounceCubeCo()); //코루틴 실행
    }

    }
    IEnumerator BounceCubeCo()
    {
        Vector3 startPosition = transform.position; //시작위치
        Vector3 targetPosition = startPosition + Vector3.up * bounceHeight; //시작위치 + y축 2.0

        while(true)//반복문 (실행 순서: [1 - MoveObject] - [2 - MoveObject], 반복)
        {
            //[1]다른 코루틴 종료 시 실행(오브젝트의 transform 값을 start에서 target까지, float duration = 1)
            yield return StartCoroutine(MoveObject(transform, startPosition, targetPosition, bounceDuration));
            //[2]다른 코루틴 종료 시 실행(오브젝트의 transform 값을 target에서 start까지, float duration = 1)
            yield return StartCoroutine(MoveObject(transform, targetPosition, startPosition, bounceDuration));
        }
    }
    //오브젝트의 transform을, start에서, end까지, float duration만큼 이동하는 코루틴
    IEnumerator MoveObject(Transform transform, Vector3 start, Vector3 end, float duration)
    {
        float elapsedTime = 0.0f; //경과시간

        while(elapsedTime &amp;lt; duration) //경과시간이 duration보다 작을 때까지 실행
        {
            //부드럽게 이동(start에서, end까지, 경과시간 / 1만큼)
            transform.position = Vector3.Lerp(start, end, elapsedTime / duration);
            elapsedTime += Time.deltaTime; //프레임 보정
            yield return null; //다음 프레임까지 대기
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;[UI의 Image, Slider 사용법]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI Canvas - Image 에서 이미지 생성&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caFPcy/dJMcajoLP9J/9bcoqH4oEjOzKe4BEoS3ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caFPcy/dJMcajoLP9J/9bcoqH4oEjOzKe4BEoS3ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caFPcy/dJMcajoLP9J/9bcoqH4oEjOzKe4BEoS3ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaFPcy%2FdJMcajoLP9J%2F9bcoqH4oEjOzKe4BEoS3ak%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;325&quot; height=&quot;83&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;83&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Image]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Source Image : 이미지 에셋 드래그 시, 해당 이미지 출력.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Color : 드로잉툴의 곱하기 레이어 개념&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x8sGc/dJMcagTdG2Q/6O9QSwgYtv55YXcFApNfk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x8sGc/dJMcagTdG2Q/6O9QSwgYtv55YXcFApNfk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x8sGc/dJMcagTdG2Q/6O9QSwgYtv55YXcFApNfk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx8sGc%2FdJMcagTdG2Q%2F6O9QSwgYtv55YXcFApNfk1%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;313&quot; height=&quot;139&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Image Type]&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;Simple: (디폴트)원본 비율 그대로 그리거나, Rect Transform에 맞춰 전체를 늘린다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sliced : 모서리는 원본비율 유지, 중앙 영역만 늘려 UI패널 테두리가 깨지지 않게 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tiled: 이미지를 늘리지 않고, 크기에 맞춰 반복 배열(타일링)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filled: 이미지 일부를 특정 방향, 비율만큼 채워지거나 비워지도록 표현&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;- Horizontal: 가로 선형 방식(Hp, Mp, Exp 바, 횡스크롤 로딩 바 등에 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Vertical: 세로 선형 방식(쿨타임 등에 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Radial 계열: 각도에 따른 원형 선형 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Fill Origin: Filed가 시작되는 지점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Fill Amount: 채워지거나 비워지는 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Clockwise/Preserve Aspect: 지점 방향 반전&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;[Slider]&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;Background: 백그라운드(슬라이더 기본 색상)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fill Area: 슬라이더 값이 채워진 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Fill : 슬라이더 값, 색상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handle Slide Area: 슬라이더의 퍼센트를 나타내는 점&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;[Add Component - Button]&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;UI 상호작용 핵심 요소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어 클릭(마우스 입력 또는 터치)에 반응하여 특정 이벤트를 실행하고 시각적 상태를 변경하는 기능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;On Click() : 사용자가 버튼 클릭 시 특정 메서드나 동작을 실행하게 해주는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+로 추가 후, 기능 실행 시 불러올 오브젝트를 드래그 한다. 추가된 스크립트에 따라 기능이 추가될 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; [코루틴을 활용한 스킬 UI 제작]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 이미지 UI 'Skill' 에 자식으로 이미지 'CoolDown' 을 추가&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V1L8L/dJMcaiXJmJq/HSgISFApEwpHs5HgbvOKR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V1L8L/dJMcaiXJmJq/HSgISFApEwpHs5HgbvOKR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V1L8L/dJMcaiXJmJq/HSgISFApEwpHs5HgbvOKR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV1L8L%2FdJMcaiXJmJq%2FHSgISFApEwpHs5HgbvOKR1%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;127&quot; height=&quot;43&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&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;- Color를 회색으로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Image Type을 Filled로 변경, Vertical 또는 Radial 360 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- (Radial 360 사용 시) Origin은 Top, Clockwise를 off&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JcC1b/dJMcahxPmvC/2KMDFHegmkAQLJ3LWJ7BoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JcC1b/dJMcahxPmvC/2KMDFHegmkAQLJ3LWJ7BoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JcC1b/dJMcahxPmvC/2KMDFHegmkAQLJ3LWJ7BoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJcC1b%2FdJMcahxPmvC%2F2KMDFHegmkAQLJ3LWJ7BoK%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;327&quot; height=&quot;334&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 자식 설정을 변경해준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 자식 오브젝트의 &lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;Handle Slide Area 삭제&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;- Background의 Color를 검은색으로 변경&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;- Fill Area의 자식 Fill의 width를 0, color 색상 변경&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;4. 코루틴 기반 코드 작성&lt;/p&gt;
&lt;pre id=&quot;code_1779954517528&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections;
using UnityEngine;
using UnityEngine.UI; //유니티 UI 네임스페이스

public class SkillController : MonoBehaviour
{
    [SerializeField] private float castingTime = 1.5f; //캐스팅(쿨타임 실행까지 걸리는 시간)
    [SerializeField] private float coolTime = 5.0f; //쿨타임 시간
    [SerializeField] private Image coolDownImage; //쿨타임 이미지 드랍
    [SerializeField] private Slider castingSlider; //슬라이더 드랍

    private Coroutine skillSequenceCoroutine; //현재 실행중인 스킬 코루틴을 저장하는 변수
    //저장하는 이유: null 체크 - 중복 실행 방지(버튼 클릭시 코루틴이 돌텐데, 캐스팅 중에 또 눌리는 것을 방지)
    void Start()
    {
        if(coolDownImage != null) //쿨다운 이미지가 null이 아닐 시
        {
            coolDownImage.fillAmount = 0.0f; //Fill Amount는 0
        }
        if(castingSlider != null) //슬라이더가 null이 아닐 시
        {
            castingSlider.gameObject.SetActive(false); //활성화 false
        }

        /* 유니티의 OnClick 컴포넌트 활용 시 생략 가능. 단, 하단의 OnClickSkillButton이 public이어야 함.
        Button btn = GetComponent&amp;lt;Button&amp;gt;(); //Button 컴포넌트 가져오기
        if(btn!=null) //null이 아닐 시
        {
            //해당 버튼을 클릭했을 때, 어디 메서드를 실행할 수 있도록 등록
            btn.onClick.AddListener(OnClickSkillButton); //스킬 클릭시 OnClickSkillButton 메서드 작동
        }
        */
    }

    //인스펙터의 Button 컴포넌트 메뉴 활성화
    public void OnClickSkillButton()
    {
        if (skillSequenceCoroutine != null) //스킬시퀀스코루틴이 null이 아닐 시
        {
            return; //클릭 불가
        }
        skillSequenceCoroutine = StartCoroutine(SkillSequenceCo()); //실행된 코루틴 참조를 SkillSequenceCo에 저장
    }
    //캐스팅 슬라이더(스킬실행중)
    IEnumerator SkillSequenceCo()
    {
        if (castingTime &amp;gt; 0.0f &amp;amp;&amp;amp; castingSlider != null) //캐스팅(1.5)이 0보다 크거나, null이 아닐 시(연결되어 있을 때만)
        {
            //슬라이더 보여주기
            castingSlider.gameObject.SetActive(true); //슬라이더 true 활성화
            castingSlider.value = 0.0f; //값을 0으로
            float castTimer = 0.0f; //타이머
            while(castTimer &amp;lt; castingTime) //타이머가 1.5초보다 작은 동안 반복
            {
                castTimer += Time.deltaTime; //시간당 타이머 더하기
                castingSlider.value = castTimer / castingTime; //진행율 계산(슬라이더 값 = 타이머/1.5)
                yield return null; //중단, 다음 프레임까지 대기
            }
            castingSlider.gameObject.SetActive(false); //while 종료, 슬라이더 off(false)
        }
        //쿨타임 표기
        if(coolTime &amp;gt; 0.0f &amp;amp;&amp;amp; coolDownImage != null) //쿨타임이 0보다 크거나, null이 아닐 시
        {
            coolDownImage.fillAmount = 1.0f; //Fill Amount는 1
            float coolTimer = 0.0f; //타이머
            while(coolTimer &amp;lt; coolTime) //타이머가 쿨타임보다 작은 동안 반복
            {
                coolTimer += Time.deltaTime; //시간당 타이머 더하기
                coolDownImage.fillAmount = 1.0f - (coolTimer / coolTime); //(진행율 계산(Fill Amount = 1-타이머/1)
                yield return null; //중단, 다음 프레임까지 대기
            }
            coolDownImage.fillAmount = 0.0f; //while 종료, FillAmount는 0
        }
        skillSequenceCoroutine = null; //스킬시퀀스코루틴은 null (클릭 가능)
    }
    private void OnDisable() //비활성화시 호출. UI 닫기, 씬 전환, 오브젝트 비활성화 시 사용
    {
        if(skillSequenceCoroutine != null) //스킬시퀀스코루틴이 null이 아닐 시
        {
            StopCoroutine(skillSequenceCoroutine); //스킬시퀀스코루틴 중단
            skillSequenceCoroutine = null; // 스킬시퀀스코루틴은 null
        }
        if (coolDownImage != null) //쿨타임이 null이 아닐 시
        {
            coolDownImage.fillAmount = 0.0f; // 0으로
        }
        if(castingSlider != null) //슬라이더가 null이 아닐 시
        {
            castingSlider.gameObject.SetActive(false); //비활성화
        }
    }
}&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;5. 코드 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Cool Down Image에 자식 이미지 CoolDown 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Casting Slider에 CastingSlider 추가&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-1. Button btn을 사용하지 않았을 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ 후, On Click()에 UI 이미지 추가, SkillController의 OnClickSkillButton 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcg5j1/dJMcaak73yV/KPRRKf61isOvP9Wr1lIiB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcg5j1/dJMcaak73yV/KPRRKf61isOvP9Wr1lIiB1/img.png&quot; data-alt=&quot;null 상태(코루틴 중단)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcg5j1/dJMcaak73yV/KPRRKf61isOvP9Wr1lIiB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdcg5j1%2FdJMcaak73yV%2FKPRRKf61isOvP9Wr1lIiB1%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;410&quot; height=&quot;134&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;null 상태(코루틴 중단)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH1PlR/dJMcad3caKH/FkZMOT4IOSjrlQbDgm9T10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH1PlR/dJMcad3caKH/FkZMOT4IOSjrlQbDgm9T10/img.png&quot; data-alt=&quot;클릭(코루틴 실행: 캐스팅)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH1PlR/dJMcad3caKH/FkZMOT4IOSjrlQbDgm9T10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH1PlR%2FdJMcad3caKH%2FFkZMOT4IOSjrlQbDgm9T10%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;403&quot; height=&quot;131&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;클릭(코루틴 실행: 캐스팅)&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNL7Yf/dJMcacJ5e2H/fisZsc38BaQI3dekL3JZM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNL7Yf/dJMcacJ5e2H/fisZsc38BaQI3dekL3JZM0/img.png&quot; data-alt=&quot;(캐스팅 코루틴 중단, 쿨타임 코루틴 실행)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNL7Yf/dJMcacJ5e2H/fisZsc38BaQI3dekL3JZM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNL7Yf%2FdJMcacJ5e2H%2FfisZsc38BaQI3dekL3JZM0%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;375&quot; height=&quot;141&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(캐스팅 코루틴 중단, 쿨타임 코루틴 실행)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/80</guid>
      <comments>https://nanaya0630.tistory.com/80#entry80comment</comments>
      <pubDate>Thu, 28 May 2026 17:48:54 +0900</pubDate>
    </item>
    <item>
      <title>[Unity]Ray복습, UI, OverLap, Check</title>
      <link>https://nanaya0630.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[RayCast]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작 위치에서, 설정 방향으로 Ray를 쏴서, 내가 설정한 거리 이내에서 물체 충돌 감지를 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 충돌 사전 감지, 상호작용, 바닥 체크, 시야 체크, 히트 스캔 등 사전 확인 용도로 사용&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;RaycastHit hit; &lt;span style=&quot;color: #009a87;&quot;&gt;//충돌 감지 여부 선언. hit 시 코드 실행, 아닐 시 null&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//Physics.RayCast(시작 위치, 설정 방향, 감지할 RaycastHit, 설정 거리);&lt;/span&gt;&lt;br /&gt;Physics.RayCast(origin, direction, out RayCastHit hit, distance)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//Ray 그리기(오브젝트 위치에서, 바라보는 앞방향으로, rayDistance만큼 빨간 광선 쏘기&lt;/span&gt;&lt;br /&gt;Debug.DrawRay(transform.position, transform.forward * rayDistance, Color.red);&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//충돌감지 여부 확인: if(충돌 시)&lt;/span&gt;&lt;br /&gt;if (Physics.Raycast(transform.position, transform.forward, out hit, rayDistance))&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//충돌한 물체의 색상 변경&lt;/span&gt;&lt;br /&gt;hit.transform.GetComponent&amp;lt;MeshRenderer&amp;gt;().material.color = Color.red;&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;b&gt;[RaycastAll]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RayCast가 처음 맞은 오브젝트만 검사한다면, RaycastAll은 경로상 Ray에 닿은 모든 정보를 배열로 반환.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//hits 배열에 담긴 Ray의 위치, 방향, 길이를 잡는다.&lt;/span&gt;&lt;br /&gt;RaycastHit[] hits = Physics.RaycastAll(origin, direction, distance)&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//for문 or foreach문으로 Ray와 충돌한 물체값이 담긴 hits를 모두 반환한다&lt;/span&gt;&lt;br /&gt;foreach(RaycastHit hit in hits)&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;b&gt;[Ray가 맞지 않을 때 체크]&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;- Ray의 방향(direction)이 옳은지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 거리(distance)가 충분한지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 레이어마스크(필터)가 옳게 설정 됐는지&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[Tag]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오브젝트의 정보&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (ex: Player, Enemy, Weapon...)&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;[Layer]&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: #9d9d9d;&quot;&gt;ex)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;물리 충돌 제어: Enemy, Bullet끼리 충돌하지 않게, 특정 layer끼리 충돌 무시 기능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RayCast 필터링: Enemy만 검사하는 등 특정 layer만 검사&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;카메라 렌더링 분리: 미니맵 카메라는 맵만 보는 등, UI 제외 렌더링&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[LayerMask]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 Layer만 검사하기 위한 기능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RayCast 등에서, 혹은 혼용해서도 많이 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Layer는 비트 연산을 기반으로 하기에, 32개만 있으나 연산 속도가 빠르다.&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;Layer와 Tag조합 패턴은 많이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;큰 그룹의 분류를 Layer로 한 뒤(Enemy 분류), 세부 역할을 Tag(Boss, Monster, Animal 등으로 구분.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1779890074581&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class PlayerGun : MonoBehaviour
{
    [SerializeField] private Transform cameraTransform; //트랜스폼에 카메라 넣기
    [SerializeField] private float shootDistance = 50.0f;
    [SerializeField] private LayerMask shootLayer; //레이어마스크
    [SerializeField] private int damage = 25;

    void Update()
    {
        if(Input.GetMouseButtonDown(0)) //0왼쪽버튼, 1오른쪽버튼, 2휠
        {
            Shoot();
        }
    }
    private void Shoot()
    {
        RaycastHit hit;

        Debug.DrawRay(
            cameraTransform.position, //위치
            cameraTransform.forward * shootDistance, //방향 * 거리
            Color.red, //색상
            0.5f); // + 활성화 시간

        if(Physics.Raycast(cameraTransform.position, //시작위치
            cameraTransform.forward, //보는 방향
            out hit, //충돌 대상 정보를 담는 매개변수
            shootDistance, //거리
            shootLayer)) // + 레이어
        {
            if(hit.collider.TryGetComponent&amp;lt;Enemy&amp;gt;(out Enemy enemy))
            {
                enemy.TakeDamage(damage); //에너미 존재시 데미지 처리
            }
            else
            {
                Debug.Log(&quot;허공에 발사&quot;);
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[CharacterController]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유니티에서 제공하는 캐릭터 이동용 컴포넌트.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;GetComponent를 통해 가져온 뒤 사용.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RigidBody 없이 이동, 벽 충돌 가능, 계단 오르기 가능, 중력 처리.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[이동 기능 비교]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RigidBody:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;물리작용&lt;/u&gt;이 중요한 오브젝트, 물리엔진기반&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;캐릭터 컨트롤러:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;캐릭터 이동 전용&lt;/u&gt;. 특성상 FPS/TPS에서 매우 자주 사용된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;ex)&amp;nbsp;characterController.&lt;span style=&quot;color: #f3c000;&quot;&gt;Move&lt;/span&gt;(&lt;span style=&quot;color: #99cefa;&quot;&gt;moveDir&amp;nbsp;&lt;/span&gt;* moveSpeed *&amp;nbsp;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Time&lt;/span&gt;.deltaTime);&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;b&gt;[Character Controller 설정]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0xuAl/dJMcabj5V2f/ArP9f4MPh8jQTztlkjb7o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0xuAl/dJMcabj5V2f/ArP9f4MPh8jQTztlkjb7o1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0xuAl/dJMcabj5V2f/ArP9f4MPh8jQTztlkjb7o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0xuAl%2FdJMcabj5V2f%2FArP9f4MPh8jQTztlkjb7o1%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;325&quot; height=&quot;254&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Slope&amp;nbsp;Limit&amp;nbsp;:&amp;nbsp;오를&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;최대&amp;nbsp;경사각 &lt;br /&gt;Step&amp;nbsp;Offset&amp;nbsp;:&amp;nbsp;자동으로&amp;nbsp;계단을 오르는&amp;nbsp;높이 &lt;br /&gt;Skin&amp;nbsp;Widty&amp;nbsp;:&amp;nbsp;충돌&amp;nbsp;넓이&amp;nbsp;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(떨림이&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있다)&lt;/span&gt; &lt;br /&gt;Center&amp;nbsp;:&amp;nbsp;오브젝트&amp;nbsp;중심 &lt;br /&gt;Radius&amp;nbsp;:&amp;nbsp;반지름 &lt;br /&gt;Height : 높이&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[UI 액자 틀]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Canvas]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Render Mode : UI 표기 위치&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkoyO3/dJMcagTc6rf/vkgvvkDmoKHmkj3mvY7Vt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkoyO3/dJMcagTc6rf/vkgvvkDmoKHmkj3mvY7Vt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkoyO3/dJMcagTc6rf/vkgvvkDmoKHmkj3mvY7Vt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkoyO3%2FdJMcagTc6rf%2FvkgvvkDmoKHmkj3mvY7Vt1%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;238&quot; height=&quot;77&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Screen&amp;nbsp;Space&amp;nbsp;-&amp;nbsp;Overlay&amp;nbsp;:&amp;nbsp;화면&amp;nbsp;고정 &lt;br /&gt;Screen&amp;nbsp;Space&amp;nbsp;-&amp;nbsp;Camera&amp;nbsp;:&amp;nbsp;카메라&amp;nbsp;기준 &lt;br /&gt;World&amp;nbsp;Space&amp;nbsp;:&amp;nbsp;월드&amp;nbsp;공간&amp;nbsp;내&amp;nbsp;배치,&amp;nbsp;상호작용&amp;nbsp;가능&amp;nbsp;(VR에서&amp;nbsp;많이&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;b&gt;[Canvas Scaler]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI Scale Mode : UI 해상도 결정&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buggvT/dJMcabLbiqL/NlsoYJXrEqOFQe7wAkKGyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buggvT/dJMcabLbiqL/NlsoYJXrEqOFQe7wAkKGyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buggvT/dJMcabLbiqL/NlsoYJXrEqOFQe7wAkKGyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuggvT%2FdJMcabLbiqL%2FNlsoYJXrEqOFQe7wAkKGyK%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;325&quot; height=&quot;134&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Constant&amp;nbsp;Pixel&amp;nbsp;Size&amp;nbsp;(디폴트)&amp;nbsp;:&amp;nbsp;UI가&amp;nbsp;화면&amp;nbsp;해상도,&amp;nbsp;크기에&amp;nbsp;관계없이&amp;nbsp;동일&amp;nbsp;픽셀&amp;nbsp;크기로&amp;nbsp;유지 &lt;br /&gt;Scale With Screen Size: UI가 화면 크기, 해상도에 따라 자동 조정, 동일 픽셀 사이즈로 유지(해상도 대응, 비례 조정) &lt;br /&gt;Constant Physical Size : 물리적 사이즈(거의 쓸 일 없음. 의료 장비, 의료 기기, 키오스크 등에 사용)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[UI (Canvas) 하이어라키]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;139&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN620w/dJMcaaFuosw/U3OwKEJFKKYNcXmJ7g6YV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN620w/dJMcaaFuosw/U3OwKEJFKKYNcXmJ7g6YV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN620w/dJMcaaFuosw/U3OwKEJFKKYNcXmJ7g6YV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN620w%2FdJMcaaFuosw%2FU3OwKEJFKKYNcXmJ7g6YV1%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;139&quot; height=&quot;40&quot; data-origin-width=&quot;139&quot; data-origin-height=&quot;40&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;EventSystem: 필수. UI 상호작용에 필요하다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0BvqH/dJMcaaMb4Uz/NR2vbPVgYhjYmw3v8dG1fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0BvqH/dJMcaaMb4Uz/NR2vbPVgYhjYmw3v8dG1fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0BvqH/dJMcaaMb4Uz/NR2vbPVgYhjYmw3v8dG1fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0BvqH%2FdJMcaaMb4Uz%2FNR2vbPVgYhjYmw3v8dG1fK%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;291&quot; height=&quot;394&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Image : 이미지 삽입&lt;br /&gt;TextMesh : 텍스트 삽입&lt;br /&gt;Panel: 여러 UI 요소들을 그룹화 해서 관리하는 컨테이너 &lt;br /&gt;Toggle:&amp;nbsp;토글,&amp;nbsp;체크박스 &lt;br /&gt;Slider:&amp;nbsp;수직바.&amp;nbsp;음량,&amp;nbsp;밝기&amp;nbsp;등&amp;nbsp;조절&amp;nbsp;기능 &lt;br /&gt;Scrollbar:&amp;nbsp;긴&amp;nbsp;콘텐츠를&amp;nbsp;스크롤&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;영역&amp;nbsp;제공 &lt;br /&gt;Button&amp;nbsp;:&amp;nbsp;버튼 &lt;br /&gt;Inputfield: 사용자가 입력가능한 필드&lt;br /&gt;Canvas:&amp;nbsp;UI&amp;nbsp;캔버스&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[UI 인스펙터 설명]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9wwet/dJMcaak7s7b/E5Z634SoAYQz12oduBP8R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9wwet/dJMcaak7s7b/E5Z634SoAYQz12oduBP8R1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9wwet/dJMcaak7s7b/E5Z634SoAYQz12oduBP8R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9wwet%2FdJMcaak7s7b%2FE5Z634SoAYQz12oduBP8R1%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;329&quot; height=&quot;180&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Rect Transform : UI 전용 트랜스폼 &lt;br /&gt;Anchors : 부모 Rect Transform 범위 내 UI가 고정될 위치 지정&lt;br /&gt;Pivot : UI 위치/크기/회전 중심점&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5xhIh/dJMcadPDTDT/6M0c5tV5eRxvFWzYaacSjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5xhIh/dJMcadPDTDT/6M0c5tV5eRxvFWzYaacSjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5xhIh/dJMcadPDTDT/6M0c5tV5eRxvFWzYaacSjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5xhIh%2FdJMcadPDTDT%2F6M0c5tV5eRxvFWzYaacSjk%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;338&quot; height=&quot;449&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;Anchors Presets&lt;/b&gt; : 자주 쓰는 위치를 프리셋으로 모아둠 &lt;br /&gt;(shift: 피벗도 함께 변경 | alt: 포지션도 함께 변경 | 입력X: 앵커만 변경)&lt;br /&gt;&lt;u&gt;보통&amp;nbsp;shift&amp;nbsp;+&amp;nbsp;alt를&amp;nbsp;동시에&amp;nbsp;눌러서&lt;/u&gt;&amp;nbsp;씀(피벗,&amp;nbsp;포지션&amp;nbsp;둘&amp;nbsp;다&amp;nbsp;변경) &lt;br /&gt;stretch : 부모크기에 맞춰서 자동으로 늘어난다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[OverLap 계열]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[OverlapSphere] (구)&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 근처 아이템 탐색(가상의 범위를 탐색하는 구를 씌운다), 플레이어 서치, 적 감지 Ai, 폭발 범위, 판정, 타워 디펜스 등&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//포지션(탐색중심위치), 탐색 반지름, 반환값은 범위 안에 있는 콜라이더 배열), 레이어 마스크 선언도 가능.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Collider&lt;/span&gt;[]&lt;span style=&quot;color: #99cefa;&quot;&gt;hits&lt;/span&gt; = &lt;span style=&quot;color: #7e98b1;&quot;&gt;Physics&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;OverlapSphere&lt;/span&gt;(position, radiius)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1780233723678&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class OverLapBasic : MonoBehaviour
{
    [SerializeField] private float radius = 2.0f; //범위
    void Update()
    {
        Collider[]hits = Physics.OverlapSphere(transform.position, radius); //레이어 마스크 선언 가능

        foreach(Collider hit in hits)
        {
            Debug.Log($&quot;{hit.name}&quot;);
        }
    }
    private void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(transform.position, radius); //센터, 반지름
    }
}&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;[Check 계열]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;True/False만 반환, 범위 안에 무엇이 있는지 체크한다. 단순하기에 오브랩 계열보다 비교적 가볍다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 플레이어 발 밑에 땅의 유무, 근처 적 유무, 점프 가능한 상태 여부&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//(위치, 반지름, 레이어마스크)&lt;/span&gt;&lt;br /&gt;ex) is Grounded = &lt;span style=&quot;color: #7e98b1;&quot;&gt;Physics&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;CheckSphere&lt;/span&gt;(groundCheck.position, checkRadius, groundLayer);&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;b&gt;[충돌 관련 컴포넌트 정리]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. RayCast&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ray를 쏴서 검사.&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;b&gt;2. OverLap/Check&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ray보다 넓게 검사(범위).&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;Check계열은 bool 기반 &lt;u&gt;확인(검사) 행위&lt;/u&gt;라 가볍고, OverLap계열은 물체가 충돌 영역 진입시 &lt;u&gt;겹쳐지는 상태&lt;/u&gt;를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;Collider&lt;/b&gt;: 충돌, 물리연산이 필요할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;Trigger&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;b&gt;[함께 보면 좋은 내용]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Renderer]&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;myRenderer = GetComponent&amp;lt;Renderer&amp;gt;();&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;private Renderer currentRenderer&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;[Interface]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interactable(상호작용 가능)구현. 캐릭터가 문, 아이템, NPC 등 다양한 오브젝트와 상호작용할 때 코드를 깔끔하고 유연하게 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 상호작용할 객체들이 공통적으로 구현해야 할 메서드 정의.&lt;/p&gt;
&lt;pre id=&quot;code_1779888680131&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface IInteractable
{
    void Interact(); //상호작용 시 실행할 동작
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 인터페이스를 상속받은 객체들은 각자의 상호작용 방식을 작성한다. (ex: 문, 상자 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 플레이어는 RayCast 등을 통해 상호작용한 오브젝트가 IInteractable 인터페이스를 가졌는지 확인하고 상호작용을 실행한다.&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;[GetComponent]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 게임 오브젝트에 부착된 특정 컴포넌트(스크립트, Rigidbody, Xollider 등)를 스크립트 상에서 찾아오거나 제어할 때 사용하는 메서드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수명 = &lt;span style=&quot;color: #f3c000;&quot;&gt;GetComponent&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;컴포넌트이름&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[GetAxis 관련 키워드 example]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;mouseX&lt;/span&gt; = &lt;span style=&quot;color: #7e98b1;&quot;&gt;Input&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;GetAxis&lt;/span&gt;(&lt;span style=&quot;color: #ef5369;&quot;&gt;&quot;Mouse X&quot;&lt;/span&gt;) * mouseSensitivity; &lt;span style=&quot;color: #009a87;&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;b&gt;[Input.GetMouseButtonDown(n)]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 클릭 기능 할당. 0(좌클), 1(우클), 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;&lt;b&gt;[Clamp]&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;ex) xRotation = Mathf.Clamp(xRotation, -80.0f, 80.0f);&lt;span style=&quot;color: #009a87;&quot;&gt; //최소 -80 ~ 최대 80도&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;[RaycastNonAlloc]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열을 미리 만들고 재사용한다. 메모리 할당 없이 사용하는 RayCast.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 생성하는 것이 아니기에, GC 부하를 줄이고 최적화에 사용된다. 성능적인 면에선 RaycastAll보다 좋다.&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: #9d9d9d;&quot;&gt;(가끔 한번 검사하거나 누르는건 RayCast로도 충분하다)&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;[OnDrawGizmos ()]&lt;/b&gt; &lt;span style=&quot;color: #009a87;&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;.color : 색 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) Gizmos.color = Color.red; &lt;span style=&quot;color: #009a87;&quot;&gt;//기즈모 색상을 빨강으로 변경&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;유니티에서 제공하는 기능은 어느 한 쪽이 우월한 것이 없다. 상호보충 관계. 상황에 맞춰서 적재적소로 사용해야 한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/79</guid>
      <comments>https://nanaya0630.tistory.com/79#entry79comment</comments>
      <pubDate>Wed, 27 May 2026 23:38:52 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Prefabs, RayCast</title>
      <link>https://nanaya0630.tistory.com/78</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Prefabs]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언제든 재사용할 수 있는, 미리 만들어진 게임 오브젝트 &lt;u&gt;에셋.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 오브젝트 + 컴포넌트 + 설정 등 값을 설계도처럼 저장하고 필요할 때마다 동일한 형태로 재사용할 수 있게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리펩으로 사용할 게임 오브젝트를 하이어라키 창에서 프로젝트 창으로 드래그 앤 드랍.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zNlDa/dJMcada0SPI/Wpilrskk4S4sDoa9zltPBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zNlDa/dJMcada0SPI/Wpilrskk4S4sDoa9zltPBK/img.png&quot; data-alt=&quot;프리펩 설정 변경 후 Overrides 창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zNlDa/dJMcada0SPI/Wpilrskk4S4sDoa9zltPBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzNlDa%2FdJMcada0SPI%2FWpilrskk4S4sDoa9zltPBK%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;362&quot; height=&quot;151&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프리펩 설정 변경 후 Overrides 창&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Revert All(모두 되돌림): 인스턴스에 적용한 모든 변경 사항을 취소, 원본 프리펩의 원래 상태로 되돌린다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Apply All(모두 적용): 씬에 배치된 프리펩의 변경 사항을 원본에 덮어쓴다. (다른 모든 오브젝트도 적용)&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;[Prefabs 생성/파괴와 관련된 메서드]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[InvokeRepeating]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 메서드를 지연 생성 후, 시간마다 반복 생성.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;InvokeRepeating&lt;/span&gt;(메서드, &lt;span style=&quot;color: #a6bc00;&quot;&gt;지연 시간&lt;/span&gt;, 반복 간격)&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//실행 시, SpawnCoin 이름의 클래스를 1초 뒤 호출, 이후 2초 간격 반복 호출&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;InvokeRepeating&lt;/span&gt;(&lt;span style=&quot;color: #006dd7;&quot;&gt;nameof&lt;/span&gt;(&lt;span style=&quot;color: #f3c000;&quot;&gt;SpawnCoin&lt;/span&gt;), &lt;span style=&quot;color: #a6bc00;&quot;&gt;1.0f&lt;/span&gt;, &lt;span style=&quot;color: #a6bc00;&quot;&gt;2.0f&lt;/span&gt;);&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Instantiate]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실행 중 오브젝트 생성.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Instantiate&lt;/span&gt;(복제 대상, 복제 위치, 복제 방향);&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//(총알 Prefab을, 총구 위치에서, 총구 방향으로 생성);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Instantiate&lt;/span&gt;(bulletPrefab, firePoint.Position, firePoint.rotation);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[Quaternion.identity]&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//Instantiate를 통해 오브젝트를 생성할 때, 별개의 회전값 없이 생성&lt;br /&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;//(코인 Prefab을, spawnPos 위치에서, 회전 없이 생성) &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Instantiate&lt;/span&gt;(coinPrefab, &lt;span style=&quot;color: #99cefa;&quot;&gt;spawnPos&lt;/span&gt;, &lt;span style=&quot;color: #a6bc00;&quot;&gt;Quaternion&lt;/span&gt;.identity)&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Destroy]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오브젝트 파괴 기능&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Destroy&lt;/span&gt;(gameObject); &lt;span style=&quot;color: #009a87;&quot;&gt;//게임 오브젝트 파괴&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Destroy&lt;/span&gt;(gameObject, 시간);&amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt;//게임 오브젝트를, 시간 뒤 삭제&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;style5&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;[RayCast]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 위치에서 특정 방향으로 가상의 광선(Ray)을 쏴서, 광선이 어떤 오브젝트에 닿은지 검사.&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: #9d9d9d;&quot;&gt;ex) 충돌 사전 감지, 상호작용, 바닥 체크, 시야 체크, 히트 스캔, 장애물 감지 등 사전 확인 용도로 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Physics&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;RayCast&lt;/span&gt;(위치, 방향, RayCastHit 정보, 거리);&lt;br /&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Physics&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;RayCast&lt;/span&gt;(origin, direction, &lt;span style=&quot;color: #006dd7;&quot;&gt;out&lt;/span&gt; RayCastHit &lt;span style=&quot;color: #99cefa;&quot;&gt;hit&lt;/span&gt;, distance);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; - hit.collider : 맞은 오브젝트의 collider 정보&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; - hit.point : Ray가 맞은 위치&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; - hit.normal : Ray가 맞은 표면의 법선벡터&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; - hit.distance : Ray가 맞은 위치까지의 거리&lt;/span&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;b&gt;[RaycastAll]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RayCast는 처음 맞은 오브젝트만 검사한다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RayCastAll은 경로상 광선에 닿은 &lt;u&gt;모든 정보를 배열로 반환&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Ray가 맞지 않을 때 체크할 사항]&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;- Ray 방향(direction)이 올바른지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 거리(distance)가 충분한지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 레이어마스크(필터)가 올바르게 설정되어 있는지&lt;/p&gt;
&lt;pre id=&quot;code_1779787997137&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class RayCastBasic : MonoBehaviour
{
    private float horizontal;
    private float vertical;

    [SerializeField] private float moveSpeed = 5.0f;
    [SerializeField] private float rayDistance = 5.0f;

    void Update()
    {
        Move();

        //[Raycast]
        RaycastHit hit;
        //Ray 그리기(오브젝트 위치에서, 오브젝트가 바라보는 앞방향으로, rayDistance만큼의 빨간 광선을 쏜다)
        Debug.DrawRay(transform.position, transform.forward * rayDistance, Color.red);

        //현재 오브젝트 위치에서 현재 오브젝트가 바라보는 앞방향으로 rayDistance만큼 Ray를 쏜다)
        if(Physics.Raycast(transform.position, transform.forward,out hit, rayDistance))
        {
            Debug.Log(hit.collider.gameObject.name); //로그출력
        }

        //[RaycastAll] - 배열화
        RaycastHit[] hits = Physics.RaycastAll(transform.position, transform.forward, rayDistance);

        foreach(RaycastHit hit in hits)
        {
            Debug.Log(&quot;맞은 오브젝트: &quot; + hit.collider.name);
        }
        Debug.DrawRay(transform.position, transform.forward * rayDistance, Color.red);
    }
    private void Move()
    {
        horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;);
        vertical = Input.GetAxisRaw(&quot;Vertical&quot;);

        transform.Translate(Vector3.forward * vertical * moveSpeed * Time.deltaTime);
        transform.Translate(Vector3.right * horizontal * moveSpeed * Time.deltaTime);
    }
}&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 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[함께 보면 좋은 내용]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Slerp, Lerp]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;부드러운 무브&lt;/u&gt;는&amp;nbsp;동일하나, &lt;u&gt;직선&lt;/u&gt; 보관과 &lt;u&gt;회전&lt;/u&gt; 보관의 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;Slerp&lt;/span&gt;: 현재 회전에서, 목표 회전까지, 보관값 만큼 부드럽게 &lt;u&gt;회전&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) &lt;span style=&quot;color: #a6bc00;&quot;&gt;Quaternion&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;smoothRotation&lt;/span&gt; = Quaternion.&lt;span style=&quot;color: #f3c000;&quot;&gt;Slerp&lt;/span&gt;(rb.rotation, &lt;span style=&quot;color: #99cefa;&quot;&gt;targetRotation&lt;/span&gt;, rotateSpeed * &lt;span style=&quot;color: #7e98b1;&quot;&gt;Time&lt;/span&gt;.fixedDeltaTime);&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: #f3c000;&quot;&gt;Lerp&lt;/span&gt;: 현재 위치에서, 목표 이동까지, 보관값 만큼 부드럽게 &lt;u&gt;이동&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) transform.position = &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;Lerp&lt;/span&gt;(transform.position, &lt;span style=&quot;color: #99cefa;&quot;&gt;targetPosition&lt;/span&gt;, followSpeed * &lt;span style=&quot;color: #7e98b1;&quot;&gt;Time&lt;/span&gt;.deltaTime);&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;[Random]&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;ex) &lt;span style=&quot;color: #006dd7;&quot;&gt;float&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;spawn&lt;/span&gt; = &lt;span style=&quot;color: #7e98b1;&quot;&gt;Random&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;Range&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;[nameof()]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드명을 문자열로 자동 반환. 오타가 날 시 컴파일러가 오류를 보여준다(오류 찾기 쉬움)&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Transform 클래스]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대상을 따라다니는 기능을 가진 컴포넌트. 카메라가 캐릭터를 따라다니게 할 때 등에 사용된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #7e98b1;&quot;&gt;Transform&lt;/span&gt; target;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ [SerializeField] ]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인스펙터 노출 + 외부 접근 불가(직렬화)&lt;/p&gt;
&lt;pre id=&quot;code_1779787750601&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[SerializeField] private float moveSpeed = 5.0f;
[SerializeField] private float rayDistance = 5.0f;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca3NTf/dJMcaccaPm6/A7yAoeCAJESDl2siX4nXk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca3NTf/dJMcaccaPm6/A7yAoeCAJESDl2siX4nXk1/img.png&quot; data-alt=&quot;시리얼라이즈필드를 붙이면, private를 붙여도 인스펙터에 노출된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca3NTf/dJMcaccaPm6/A7yAoeCAJESDl2siX4nXk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca3NTf%2FdJMcaccaPm6%2FA7yAoeCAJESDl2siX4nXk1%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;312&quot; height=&quot;110&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시리얼라이즈필드를 붙이면, private를 붙여도 인스펙터에 노출된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/78</guid>
      <comments>https://nanaya0630.tistory.com/78#entry78comment</comments>
      <pubDate>Tue, 26 May 2026 18:49:02 +0900</pubDate>
    </item>
    <item>
      <title>[Unity]Rigidbody, Collider</title>
      <link>https://nanaya0630.tistory.com/77</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Rigidbody]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티 물리엔진(PhysicX)을 활용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;Translate는 물리엔진을 거치지 않기에 통과한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;Rigidbody는 충돌&lt;/u&gt;을 거치기에, 캐릭터, 박스, 오브젝트 등에 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Update() 메서드가 아닌, &lt;b&gt;FixedUpdate()에서 처리&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;b&gt;[Rigidbody 이동]&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;1. transform.Translate&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리엔진 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RigidBody가 있는 오브젝트에 지양. 물리엔진을 우회하기에 충돌이 부자연스럽다.&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;2. AddForce&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RigidBody에 힘을 가하는 방식.&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;3. LinearVelocity&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RigidBody에 속도를 직접 지정하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Y축 속도를 잘못 덮어쓰면 중력, 점프 조작에 문제가 발생할 수 있다.&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;4. MovePosition&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RigidBody의 다음 위치를 지정하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리엔진 흐름 안에서 위치를 이동하기 때문에 transform 직접 이동보다 안정적이다.&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;span style=&quot;color: #9d9d9d;&quot;&gt;캐릭터 기본 이동은 Velocity, MovePosition이 많이 사용된다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;AddForce는 점프, 폭발, 넉백 등 물리적 가속이 필요한 상황에 적합하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;rb = &lt;span style=&quot;color: #f3c000;&quot;&gt;GetComponent&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Rigidbody&lt;/span&gt;&amp;gt;();&lt;span style=&quot;color: #009a87;&quot;&gt; // rb = Rigidbody 컴포넌트를 담은 변수&lt;/span&gt;&lt;br /&gt;moveDir &lt;span style=&quot;color: #009a87;&quot;&gt;//이동 방향&lt;/span&gt;&lt;br /&gt;moveSpeed &lt;span style=&quot;color: #009a87;&quot;&gt;//이동 속도&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//[1]AddForce&lt;/span&gt;&lt;br /&gt;rb.&lt;span style=&quot;color: #f3c000;&quot;&gt;AddForce&lt;/span&gt;(moveDir * moveSpeed);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//[2]Velocity&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;float&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;currentYvelocity&lt;/span&gt; = rb.linearVelocity.y; &lt;span style=&quot;color: #009a87;&quot;&gt;//Y 속도 유지(오류 방지)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #a6bc00;&quot;&gt;vector3&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;velocity&lt;/span&gt; = &lt;span style=&quot;color: #006dd7;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;(moveDir.x * moveSpeed, &lt;span style=&quot;color: #99cefa;&quot;&gt;currentYvelocity&lt;/span&gt;, moveDir.z * moveSpeed);&lt;br /&gt;rb.linearVelocity = &lt;span style=&quot;color: #99cefa;&quot;&gt;velocity&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//[3]MovePosition&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//rb.position: 현재 rigidbody 위치&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//moveDir * moveSpeed : 이동 방향으로 이동 속도만큼 이동한다&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;nextPos&lt;/span&gt; = rb.position + moveDir * moveSpeed * &lt;span style=&quot;color: #009a87;&quot;&gt;Time&lt;/span&gt;.fixedDeltaTime;&lt;br /&gt;rb.&lt;span style=&quot;color: #f3c000;&quot;&gt;MovePosition&lt;/span&gt;(&lt;span style=&quot;color: #99cefa;&quot;&gt;nextPos&lt;/span&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;b&gt;[Rigidbody 설정]&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zycYA/dJMcag6HUga/3F1GQ9UpvO5vpbF6l15Bk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zycYA/dJMcag6HUga/3F1GQ9UpvO5vpbF6l15Bk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zycYA/dJMcag6HUga/3F1GQ9UpvO5vpbF6l15Bk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzycYA%2FdJMcag6HUga%2F3F1GQ9UpvO5vpbF6l15Bk1%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;313&quot; height=&quot;335&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Mass : 질량. 값이 클 수록 무겁다(충돌 등에 영향)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Linear Damping : 이동 저항, 값이 클 수록 빨리 멈춘다(공기 저항)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Angular Damping : 회전 저항. 값이 클 수록 빨리 멈춘다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Automatic Center of Mass : 무게 중심 자동 계산&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Automatic Tensor : 회전 관성 자동 계산&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Use Gravity : 중력 적용 여부&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Is Kinematic : 물리엔진의 힘, 중력, 충돌 영향 X(스크립트롤 위치 직접 제어)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex)움직이는 발판, 자동문, 엘리베이터 등에 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Interpolate : Rigidbody의 위치 보간 방법&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Collision Detection : 충돌 감지 방법 아래로 내려갈 수록 무거워진다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tQJdr/dJMcaayGA2Z/kSWadTu3VJ1HIvcAEETOqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tQJdr/dJMcaayGA2Z/kSWadTu3VJ1HIvcAEETOqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tQJdr/dJMcaayGA2Z/kSWadTu3VJ1HIvcAEETOqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtQJdr%2FdJMcaayGA2Z%2FkSWadTu3VJ1HIvcAEETOqK%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;199&quot; height=&quot;98&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- Discrete : 기본. 가장 가볍고 보편적으로 사용된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; &amp;nbsp;- Continuous : 빠른 물체에 적합&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; &amp;nbsp;- Continous Dynamic : 디테일한 충돌 감지&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; &amp;nbsp;- Continous Speculative : 충돌 위치 예측 처리&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Constraints : 체크한 축의 이동/회전 고정&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1779780531779&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class RigidBasic : MonoBehaviour
{
    private Rigidbody rb;
    private Vector3 moveDir;

    private float moveSpeed = 5.0f;
    void Start()
    {
        //RigidBody 컴포넌트를 변수 rb에 저장
        rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
    }
    
    void Update()
    {
        //[Translate 방식]
        //벽과 충돌 시 부들거린다. 물리엔진 입장에서 '터널링'이 발생할 수 있다.
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
        }
        if(Input.GetKey(KeyCode.S))
        {
            transform.Translate(Vector3.back * moveSpeed * Time.deltaTime);
        }
        
        //이동 변수: moveDir
        float horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;);
        float vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
        moveDir = new Vector3(horizontal, 0.0f, vertical).normalized;
    }
    
    //물리엔진 관련 업데이트는 FiedUpdate에서 처리
    private void FixedUpdate()
    {
        //[1]AddForce
        //힘을 누적해서 이동(점진적 가/감속 물리반영)
        //마찰력, 중력, 가감속 영향으로 회전 발생(당구겜 등에서 사용)
        //Rigidbody의 Constraints, FreezeRotation을 체크하면 회전이 발생하지 않는다.
        rb.AddForce(moveDir * 20.0f);

        //[2]Velocity
        //힘을 가하는 게 아닌, 속도 자체를 덮어쓰는 방식
        //물리기반 + 속도를 직접 덮어쓰는 방식
        //입력이 즉각적. Y속도를 잘못 덮어씌우면 이상해질 수 있다.(Y는 유지, X,Z만 제한)
        float currentYvelocity = rb.linearVelocity.y; //현재 Y속도 저장
        //좌우, 앞뒤(Y는 유지)
        Vector3 velocity = new Vector3(moveDir.x * moveSpeed, currentYvelocity, moveDir.z * moveSpeed);
        rb.linearVelocity = velocity;

        //[3]MovePosition
        //rb.position: 현재 rigidbody 위치
        //moveDir: 이동 방향
        //moveSpeed: 이동 속도
        //moveDir * moveSpeed: 어느 방향으로 얼마나 빠르게 이동할지
        //moveSpeed * Time.fixedDeltaTime: 이번 물리 프레임 동안 이동해야 하는 거리
        //rb.position + 이동거리: 현재 위치 + 이번 프레임 이동량
        //제어 깔끔. 일정한 속도 이동에 적합
        Vector3 nextPos = rb.position + moveDir * moveSpeed * Time.fixedDeltaTime;
        rb.MovePosition(nextPos);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[Collider]&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;FPS같이 판정이 중요한 류가 아니라면, 성능을 위해 단순화 된 형태(박스, 스피어, 캡슐 등)를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;형태, 영역을 정하면 실제 물리 계산은 RigidBody의 Collision Detection이 담당한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RH9fQ/dJMcagTb5si/plRyNJdvQH7nu7NyPlizLK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RH9fQ/dJMcagTb5si/plRyNJdvQH7nu7NyPlizLK/img.gif&quot; data-alt=&quot;히트박스 개념을 떠올리면 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RH9fQ/dJMcagTb5si/plRyNJdvQH7nu7NyPlizLK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/RH9fQ/dJMcagTb5si/plRyNJdvQH7nu7NyPlizLK/img.gif&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;264&quot; height=&quot;198&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;240&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;b&gt;[Collision 계열 메서드]&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;두 콜라이더의 is Trigger가 모두 false여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 캐릭터가 벽에 부딪혀 밀릴 때, 물체를 밀거나 물리적 상호작용을 할 때, 투사체가 적이나 벽에 맞아서 파괴될 때&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;OnCollisionEnter : 처음 충돌 발생 시 호출&lt;br /&gt;OnCollisionExit : 충돌 종료 시 호출&lt;br /&gt;OnCollisionStay : 충돌이 유지되는 동안 매 프레임 호출&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;private void OnCollisionXXX&lt;/span&gt;(&lt;span style=&quot;color: #7e98b1;&quot;&gt;Collision&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;collision&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt;//내용&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Collision 안에는 충돌 정보가 들었다.&lt;br /&gt;상대 오브젝트에 접근을 할 땐 &lt;b&gt;gameObject&lt;/b&gt;를 한단계 타고 들어가야 한다.&lt;br /&gt;&lt;span style=&quot;color: #c1bef9;&quot;&gt;if&lt;/span&gt;(&lt;span style=&quot;color: #99cefa;&quot;&gt;collision&lt;/span&gt;.gameObject.&lt;span style=&quot;color: #f3c000;&quot;&gt;CompareTag&lt;/span&gt;(&lt;span style=&quot;color: #ef5369;&quot;&gt;&quot;태그명&quot;&lt;/span&gt;))&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&amp;nbsp; &amp;nbsp; //내용&lt;/span&gt;&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;b&gt;[Trigger 계열 메서드]&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;is Trigger가 true여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 아이템 획득, NPC 대화, 텔레포트, 포탈, 체크포인트&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;OnTriggerEnter : 트리거 영역 처음 진입 시 호출&lt;br /&gt;OnTriggerExit : 트리거 영역에서 벗어날 시 호출&lt;br /&gt;OnTriggerStay : 트리거 영역에 머무를 때 매 프레임 호출&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;private void OnTriggerStay&lt;/span&gt;(&lt;span style=&quot;color: #7e98b1;&quot;&gt;Collider&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;other&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt; //내용&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Trigger 안에는 충돌 정보가 없다. Collider로 &lt;b&gt;바로 접근&lt;/b&gt;할 수 있다.&lt;br /&gt;&lt;span style=&quot;color: #c1bef9;&quot;&gt;if&lt;/span&gt;(&lt;span style=&quot;color: #99cefa;&quot;&gt;other&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;CompareTag&lt;/span&gt;(&lt;span style=&quot;color: #ef5369;&quot;&gt;&quot;태그명&quot;&lt;/span&gt;))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt; //내용&lt;/span&gt;&lt;br /&gt;}&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;212&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzuNj/dJMcaiXHP8F/4nkaRnKSEuqdk2WSDeSEWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzuNj/dJMcaiXHP8F/4nkaRnKSEuqdk2WSDeSEWK/img.png&quot; data-alt=&quot;is Trigger 체크 및 Collider 크기 설정 : Inspector의 Collider&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzuNj/dJMcaiXHP8F/4nkaRnKSEuqdk2WSDeSEWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxzuNj%2FdJMcaiXHP8F%2F4nkaRnKSEuqdk2WSDeSEWK%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;212&quot; height=&quot;95&quot; data-origin-width=&quot;212&quot; data-origin-height=&quot;95&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;is Trigger 체크 및 Collider 크기 설정 : Inspector의 Collider&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[공통 사항]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A, B 두 오브젝트 모두 콜라이더가 있어야 하며, 최소 하나의 오브젝트에는 Rigidbody가 있어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1779782983410&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class ColliderBasic : MonoBehaviour
{
    private Rigidbody rb;
    private Vector3 moveDir;

    private float moveSpeed = 5.0f;
    private float horizontal;
    private float vertical;
    void Start()
    {
    	//Rigidbody 컴포넌트 가져오기
        rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
    }

    void Update()
    {
    	//조작키 지정
        horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;);
        vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
        moveDir = new Vector3(horizontal, 0.0f, vertical).normalized;
    }
    private void FixedUpdate()
    {
    	//MovePosition 방식
        Vector3 nextPos = rb.position + moveDir * moveSpeed * Time.fixedDeltaTime;
        rb.MovePosition(nextPos);
    }
    //[Collision]
    private void OnCollisionEnter(Collision collision) //충돌
    {
        //Debug.Log(&quot;충돌이 처음 발생되었을 때 호출&quot;);
        if(collision.gameObject.CompareTag(&quot;Wall&quot;))//충돌 오브젝트 태그가 Wall일 시
        {
            Debug.Log(&quot;벽과 충돌&quot;);
            Debug.Log($&quot;{collision.gameObject.name}&quot;);
        }
    }
    private void OnCollisionExit(Collision collision) //충돌 종료
    {
        //Debug.Log(&quot;충돌이 끝났을 때 호출&quot;);
        if (collision.gameObject.CompareTag(&quot;Wall&quot;))//충돌 오브젝트 태그가 Wall일 시
        {
            Debug.Log($&quot;{collision.gameObject.name} 와(과) 충돌 종료&quot;);
        }
    }
    private void OnCollisionStay(Collision collision) //충돌 유지
    {
        //Debug.Log(&quot;충돌이 유지되고 있을 때호출&quot;);
        if (collision.gameObject.CompareTag(&quot;Wall&quot;))//충돌 오브젝트 태그가 Wall일 시
        {
            Debug.Log($&quot;{collision.gameObject.name} 와(과) 충돌 유지 중&quot;);
        }
    }
    
    //[Trigger]
    private void OnTriggerEnter(Collider other) //진입
    {
        Debug.Log($&quot;{other.gameObject.name}의 트리거 영역 안에 들어옴&quot;);
    }
    private void OnTriggerExit(Collider other) //나감
    {
        Debug.Log($&quot;{other.gameObject.name}의 트리거 영역에서 나감&quot;);
    }
    private void OnTriggerStay(Collider other) //머무름
    {
        Debug.Log($&quot;{other.gameObject.name}의 트리거 영역 안에 머무르는 중&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;span style=&quot;color: #9d9d9d;&quot;&gt;[예제]&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공을 굴리는 게임을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 벽에 충돌 시 벽의 색상이 변한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ColorZone 진입 시 공의 색상이 변하고, 나갈 시 원래대로 돌아온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. JumpZone 진입 시 공이 순간적으로 높게 점프한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdUdnW/dJMcai4sXrL/39EuyXLKLz5f7UWZrikBKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdUdnW/dJMcai4sXrL/39EuyXLKLz5f7UWZrikBKk/img.png&quot; data-alt=&quot;Inspector의 Tag에서 Wall, JumpZone, ColorZone을 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdUdnW/dJMcai4sXrL/39EuyXLKLz5f7UWZrikBKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdUdnW%2FdJMcai4sXrL%2F39EuyXLKLz5f7UWZrikBKk%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;327&quot; height=&quot;245&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Inspector의 Tag에서 Wall, JumpZone, ColorZone을 추가&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;pre id=&quot;code_1779783491354&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private Rigidbody rb; //오브젝트 물리연산 담당 컴포넌트
    private Renderer playerRenderer; //오브젝트를 화면에 그려주는 컴포넌트
    
    private float horizontal;
    private float vertical;
    private float moveforce = 10.0f;
    void Start()
    {
        //컴포넌트 들고오기
        rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
        playerRenderer = GetComponent&amp;lt;Renderer&amp;gt;();
    }

    void Update()
    {
        horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;);
        vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
    }
    private void FixedUpdate()
    {
    	//Addforce 방식
        Vector3 dir = new Vector3(horizontal, 0.0f, vertical);
        rb.AddForce(dir * moveforce);
    }
    private void OnCollisionEnter(Collision collision)
    {
        //Collision 안에는 충돌 정보가 들었다(Trigger보다 복잡한 구조)
        //상대 오브젝트에 접근하려면 gameObject를 한단계 타고 들어가야 한다.
        if(collision.gameObject.CompareTag(&quot;Wall&quot;)) //Tag가 Wall인 오브젝트와 충돌 시
        {
            //대상체의 컴포넌트를 그리는 Renderer의 material의 색상를 빨간색으로 변경
            collision.gameObject.GetComponent&amp;lt;Renderer&amp;gt;().material.color = Color.red;
            //TryGetComponent는 가져오는 컴포넌트의 존재 확인. 있으면 가져오고 없으면 null
            //때문에 GetComponent보다 좀 더 안전하다
            if (collision.gameObject.TryGetComponent&amp;lt;Renderer&amp;gt;(out Renderer renderer))
            {
                renderer.material.color = Color.red;
            }
        }
    }
    private void OnTriggerEnter(Collider other)
    {
        //Trigger는 충돌 정보가 없기에 Collider로 바로 접근
        if(other.CompareTag(&quot;ColorZone&quot;))
        {
            //playerRenderer의 색상을 빨간색으로 변경
            playerRenderer.material.color = Color.red;
        }
        if(other.CompareTag(&quot;JumpZone&quot;))
        {
            //윗 방향으로 순간적인 힘을 주기 위해 ForceMode 사용
            rb.AddForce(Vector3.up * 10.0f, ForceMode.Impulse);
        }
    }
    private void OnTriggerExit(Collider other)
    {
        if(other.CompareTag(&quot;ColorZone&quot;))
        {
            //Renderer가 사용하는 색상 재질을 화이트로 변경
            playerRenderer.material.color = Color.white;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ GetComponent&amp;lt;&amp;gt;(); ]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 게임 오브젝트에 붙어있는 RigidBody 컴포넌트를 변수에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Start(), Awake()에서만 사용한다. (Update 계열에서 사용하면 안된다. 캐싱해야 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수명 = &lt;span style=&quot;color: #f3c000;&quot;&gt;GetComponent&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Rigidbody&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[터널링 Tunneling]&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;[Time.fixedDeltaTime]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeltaTime의 물리 버전(FixedUpdate)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #222222; text-align: start;&quot;&gt;FPS가 달라도 같은 값을 이동하도록 프레임을 보정한다. (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;b&gt;&lt;span style=&quot;background-color: #fafafa; color: #222222; text-align: start;&quot;&gt;[Render]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #222222; text-align: start;&quot;&gt;오브젝트를 화면에 그려주는 컴포넌트.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #222222; text-align: start;&quot;&gt;특정 오브젝트의 material의 색상을 변경하는 등의 기능이 있다.&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: #fafafa; color: #222222; text-align: start;&quot;&gt;&lt;b&gt;[ForceMode 4가지]&lt;/b&gt; &lt;br /&gt;Impulse : 순간적인 힘을 주는 방식 &lt;br /&gt;Force : (디폴트)미는 힘 &lt;br /&gt;Acceleration : 가속도 &lt;br /&gt;VelocityChange : 속도 변화를 즉시 지정&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/77</guid>
      <comments>https://nanaya0630.tistory.com/77#entry77comment</comments>
      <pubDate>Tue, 26 May 2026 17:35:34 +0900</pubDate>
    </item>
    <item>
      <title>[Unity]이동, 회전</title>
      <link>https://nanaya0630.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[position]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 오브젝트 위치 정보.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//(x, y, z)위치로 순간이동&lt;/span&gt;&lt;br /&gt;transform.position = &lt;span style=&quot;color: #006dd7;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;(&lt;span style=&quot;color: #a6bc00;&quot;&gt;x, y, z&lt;/span&gt;)&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//현재 위치에 (0,0,1)값을 더하며 이동&lt;/span&gt;&lt;br /&gt;transform.position += &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;.forward&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;b&gt;[Translate]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현 오브젝트의 Transform 위치를 이동시키는 메서드.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현 위치에서 지정한 방향과 거리만큼 이동한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;Translate&lt;/span&gt;(이동값);&lt;br /&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;Translate&lt;/span&gt;(이동값, &lt;span style=&quot;color: #a6bc00;&quot;&gt;기준공간&lt;/span&gt;);&lt;/blockquote&gt;
&lt;pre id=&quot;code_1779773130320&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class CTranslate : MonoBehaviour
{
    private float moveSpeed = 5.0f; //moveSpeed = 5.0의 속도로 이동
    void Update()
    {
    	//[자동 이동]
        //[1]
        transform.Translate(Vector3.forward);
        //[2]
        transform.Translate(Vector3.forward * moveSpeed);
        //[3]
        transform.Translate(Vector3.forward * Time.deltaTime); //Time.deltaTime: 프레임 보정
        
        //[입력 이동]
        //[1] 이동키 할당
        float horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;); //string(&quot;축의 이름&quot;)
        float vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
        //[2] 이동 인스턴스 생성
        Vector3 move = new Vector3(horizontal, 0, vertical); //WS x축 |AD z축 이동 |y축 사용X
        
        //[3]대각선 균일화
        move = move.normalized; //normalized: 대각선도 동일 속도만큼 이동하도록 만듬
        
        //[4]
        transform.Translate(move * moveSpeed * Time.deltaTime); //입력 방향으로 moveSpeed만큼 이동

        //기준공간: Space.() (콤마 뒤에 오버로딩 - Space.World, Space.Self)
        transform.Translate(move * moveSpeed * Time.deltaTime, Space.Self);&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Debug.Log()]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 시 Console란에 Log를 출력해준다(코드 배포 전 제거)&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;[Vector3]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3차원 공간(x, y, z)의 위치, 방향, 이동 거리를 나타낼때 사용하는 구조체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;right - left (x축) | up - down(y축) | forward - back(z축)&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;[Time.deltaTime]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FPS가 달라도 같은 값을 이동하도록 프레임을 보정한다. (1 * (1 / 프레임) = 프레임당 시간 보정)&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;[GetAxis(&quot; &quot;), GetAxisRaw(&quot; &quot;)]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;유니티의 InputSystem이나 Project Setting의 Active Input Handling 시스템 등을 이용.&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;GetAxis : -1.0f부터 1.0f까지의 범위 값을 반환(부드러운 이동)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GetAxisRaw : -1, 0, 1 중 하나가 반환(빠른 반응)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;horizontal: (A, D) | vertical (W, S)&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;Vector3 move = new Vector3(x, y, z)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[GetKey(KeyCode.키)]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;if문과 함께 사용. 해당 키 입력 시 if문 안의 내용을 실행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ .normalized]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;피타고라스의 원리로 인해, 대각선 이동 시 루트2(약 1.4)의 거리를 이동하게 된다(더 빠른 이동속도)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Vector3의 방향을 정규화 하여, 균일한 속도로 이동하게 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Space.World]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기준 공간 - 월드 좌표 기준 이동&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Space.Self]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기준 공간 - 오브젝트 회전 방향 기준 이동&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[rotate]&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;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;Rotate&lt;/span&gt;(회전값);&lt;br /&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;Rotate&lt;/span&gt;(회전값, &lt;span style=&quot;color: #a6bc00;&quot;&gt;기준공간&lt;/span&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;b&gt;[eulerAngles]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오브젝트 회전을 사람이 보기 쉬운 각도 값으로 표현한다(4차원 쿼터니언 -&amp;gt; 3차원 오일러)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;쿼터니언(XYZW)은 회전 보간 안정, 회전 보정, 짐벌락 현상 방지 등 3D에서 가장 표현하기 쉬우나, 사람이 보기 힘들다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;때문에 오일러 각으로 표기한다. (직접 수정하면 안된다. 메서드 값을 수정해야 한다.)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;짐벌락 현상: 3차원 공간에서 물체 회전 시, 두 회전 축이 겹쳐 회전 자유도 상실. 특정 각도의 두 축이 겹쳐 보인다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;//Rotate가 회전값 더하기라면, eulerAngles는 회전 값을 직접 설정한다.&lt;/span&gt;&lt;br /&gt;transform.eulerAngles = &lt;span style=&quot;color: #006dd7;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;(&lt;span style=&quot;color: #a6bc00;&quot;&gt;x, y, z&lt;/span&gt;);&lt;/blockquote&gt;
&lt;pre id=&quot;code_1779777221200&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class RotateBasic : MonoBehaviour
{
    private float rotateSpeed = 50.0f; //회전스피드

    private void Start()
    {
        transform.eulerAngles = new Vector3(0.0f, 90.0f, 0.0f); //y축을 90도로 초기화
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Space)) //KeyCode.키 : 해당 키를 누르는 동안 진행
        {
        transform.Rotate(Vector3.up * rotateSpeed * Time.deltaTime, Space.World); //up: y축을 50.0f만큼 회전(월드 기준)
        }
    }
}&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;[Rotation]&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;b&gt;[Quaternion.Euler]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 오일러(3차원)회전 값을 쿼터니언 식으로 변환&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;transform.rotation = &lt;span style=&quot;color: #a6bc00;&quot;&gt;Quaternion&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;Euler&lt;/span&gt;(&lt;span style=&quot;color: #a6bc00;&quot;&gt;x,y,z&lt;/span&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;b&gt;[LookAt]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현 오브젝트의 앞방향이 타겟을 향하게 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;LookAt&lt;/span&gt;(transform target);&lt;/blockquote&gt;
&lt;pre id=&quot;code_1779777943242&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class CLookAt : MonoBehaviour
{
    public Transform target; //인스펙터 표시
    void Update()
    {
        transform.LookAt(target); //앞부분이 타겟을 향한다
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qwj41/dJMcabj4OXH/YqQBgFIhOvSvvXPT14AW60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qwj41/dJMcabj4OXH/YqQBgFIhOvSvvXPT14AW60/img.png&quot; data-alt=&quot;인스펙터에 target이 될 오브젝트 드래그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qwj41/dJMcabj4OXH/YqQBgFIhOvSvvXPT14AW60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqwj41%2FdJMcabj4OXH%2FYqQBgFIhOvSvvXPT14AW60%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;307&quot; height=&quot;82&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;82&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인스펙터에 target이 될 오브젝트 드래그&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;[RotateAround]&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: #9d9d9d;&quot;&gt;ex) 카메라가 플레이어 중심 공전, 아이템이 특정 오브젝트 중심 공전 등의 상황에 사용&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;RotateAround&lt;/span&gt;(Vector3 point, Vector3 axis, float angle); //(회전 중심점, 회전 축, n도 회전)&lt;br /&gt;transform.&lt;span style=&quot;color: #f3c000;&quot;&gt;RotateAround&lt;/span&gt;(target.position, &lt;span style=&quot;color: #a6bc00;&quot;&gt;Vector3&lt;/span&gt;.up, 30.0f); //(target을 중심으로, y축을, 30도 회전)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1779778260087&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class CRotateAround : MonoBehaviour
{
    public Transform target; //인스펙터 표시
    private float rotateSpeed = 50.0f; //회전값

    void Update()
    {
    	//(타겟 위치, y축으로 50도 회전 (프레임 보정)
        transform.RotateAround(target.position, Vector3.up, rotateSpeed * Time.deltaTime); 
    }
}&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;[LookRotation]&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(타겟의 크기까지 포함하기 때문에)방향만 필요하면 노멀라이즈를 함께 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #a6bc00;&quot;&gt;Quaternion&lt;/span&gt;.&lt;span style=&quot;color: #f3c000;&quot;&gt;LookRotation&lt;/span&gt;(Vector3 forward, Vector3 upwards) //(앞방향을 삼을 벡터, 위쪽 기준)&lt;br /&gt;//내 현재 위치에서 타겟의 위치로 향하는 방향을 계산하고, 내 앞방향(forward)이 그 방향을 향하도록 회전한다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1779778688649&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class CLookRotation : MonoBehaviour
{
    public Transform target; //인스펙터 표시

    void Update()
    {
        //내 위치에서 타겟 위치로 향하는 방향 벡터(dir)를 구하는 공식
        //target.position : 목표 위치
        //transform.position : 내 위치
        Vector3 dir = target.position - transform.position;
        //ex) 플레이어 위치 (0,0,0) / 타겟 위치 (10,0,0)
        //타겟 포지션(타겟 위치) - 트랜스폼 포지션(내 위치) : dir = (10,0,0)

        if (dir == Vector3.zero) return; //만약 dir 값이 (0,0,0)이면 하지마라

        Quaternion lookRotation = Quaternion.LookRotation(dir, Vector3.up);

        transform.rotation = lookRotation;
    }
}&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;[LookAt vs LookRotation]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 대상을 바라보게 하는 건 동일하나,&lt;br /&gt;LookAt은 바로 바라보게 한다(즉시 회전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 터렛과 같은 부자연스러운 회전&lt;/span&gt;&lt;br /&gt;LookRotation은 바라보는 회전값만 만든다.(부드러운 회전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ex) 미사일 유도, 보스AI와 같은 회전 직접 컨트롤&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/76</guid>
      <comments>https://nanaya0630.tistory.com/76#entry76comment</comments>
      <pubDate>Tue, 26 May 2026 16:09:30 +0900</pubDate>
    </item>
    <item>
      <title>[Unity]컴포넌트, 라이프 사이클</title>
      <link>https://nanaya0630.tistory.com/75</link>
      <description>&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; text-align: start;&quot;&gt;유연한 설계와 유지보수를 위해 최근에는 상속보다 컴포넌트 방식이 선호되며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;유니티는 컴포넌트 기반 구조&lt;/u&gt;를 띄고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[컴포넌트 패턴]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스를 상속받는 대신, 빈 껍데기인 게임 오브젝트에 &lt;u&gt;기능(컴포넌트)들을 조립하여 넣는 방식&lt;/u&gt;이다. 상속처럼 재사용성이 높으면서, 상속과 달리 &lt;u&gt;독립적&lt;/u&gt;인 부품이기에 유연성이 높고 결합도가 낮다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[컴포넌트 Componunt]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 오브젝트의 &lt;b&gt;기능, 동작&lt;/b&gt;에 관여하는 구성요소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립적인 부품으로, 다른 컴포넌트에 의존하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;하나의 게임 오브젝트에 여러 컴포넌트를 연결할 수 있지만, 모든 게임 오브젝트는 단 하나의 Transform 컴포넌트만 가질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[게임 오브젝트 Game Object]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;씬&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(게임 오브젝트를 시각적으로 편집 가능한 공간)&lt;/span&gt;에 존재할 수 있는 모든 것, 게임 오브젝트의 모양과 기능을 결정하는 &lt;b&gt;컴포넌트를 담는 그릇&lt;/b&gt;.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모든 게임 오브젝트는 처음에 빈 껍데기이나, 껍데기에 컴포넌트를 조립하여 각자 고유한 기능을 가지게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TC2gy/dJMcacJZkRM/oQRjAmIZ6gKXwz7XIXQWfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TC2gy/dJMcacJZkRM/oQRjAmIZ6gKXwz7XIXQWfk/img.png&quot; data-alt=&quot;하이어라키의 게임 오브젝트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TC2gy/dJMcacJZkRM/oQRjAmIZ6gKXwz7XIXQWfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTC2gy%2FdJMcacJZkRM%2FoQRjAmIZ6gKXwz7XIXQWfk%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;250&quot; height=&quot;132&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하이어라키의 게임 오브젝트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;* 하이어라키: 계층창. 현재 씬에 존재하는 모든 오브젝트들이 표기되며 부모자식관계를 설정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LGXsy/dJMcaa6sLZc/WLeLzUhjRBGIhUT50tmNu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LGXsy/dJMcaa6sLZc/WLeLzUhjRBGIhUT50tmNu0/img.png&quot; data-alt=&quot;인스펙터에 컴포넌트(기능)가 모여있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LGXsy/dJMcaa6sLZc/WLeLzUhjRBGIhUT50tmNu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLGXsy%2FdJMcaa6sLZc%2FWLeLzUhjRBGIhUT50tmNu0%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;353&quot; height=&quot;305&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;305&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;[트랜스폼 Transform]&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;u&gt;자식의 트랜스폼은 부모를 기준&lt;/u&gt;으로(Local) 값을 측정하며, 부모가 없는 경우 월드(Global)공간에서 값을 측정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vLFQy/dJMcabc94H7/JeKavhZmocPrukDapr6ftk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vLFQy/dJMcabc94H7/JeKavhZmocPrukDapr6ftk/img.png&quot; data-alt=&quot;트랜스폼 컴포넌트: 좌표, 회전, 크기, 비율 유지 기능&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vLFQy/dJMcabc94H7/JeKavhZmocPrukDapr6ftk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvLFQy%2FdJMcabc94H7%2FJeKavhZmocPrukDapr6ftk%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;351&quot; height=&quot;106&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;106&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;[MonoBehaviour]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티의 모든 스크립트가 &lt;u&gt;상속받는 기본 클래스&lt;/u&gt;로, 에디터에서 스크립트를 게임 오브젝트에 연결할 수 있는 프레임워크를 제공한다. (상속 시 사용자 정의 컴포넌트 제작 가능)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 95.4651%; height: 88px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;Update()&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;게임 오브젝트 프레임 업데이트 처리 코드&lt;br /&gt;(움직임, 동작 트리거, 입력 응답 등 게임 플레이 중 경과에 따라 처리하는 모든 작업)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5814%;&quot;&gt;Start()&lt;/td&gt;
&lt;td style=&quot;width: 84.4186%;&quot;&gt;게임 시작 전(Update 호출 전) Unity에서 호출, 초기화 수행 코드&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: #9d9d9d;&quot;&gt;* 자동 생성되는 메서드. 해당 메서드를 사용하지 않는다면 지운다. 사용하지 않아도 매 프레임마다 호출을 받기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;- &lt;b&gt;Debug.Log()&lt;/b&gt;: Unity 콘솔 출력에 메세지를 출력하는 명령 (소스코드 오픈 전에 지우는 것이 좋다)&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;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 MonoBehaviour 컴포넌트가 수신할 가능성이 있는 사전 정의된 콜백&lt;span style=&quot;color: #9d9d9d;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. [정기 업데이트 이벤트]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;게임 프로그래밍 핵심 개념은 각 &lt;u&gt;프레임 렌더링 직전에 오브젝트 위치, 상태, 동작을 변경&lt;/u&gt;하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Update()&lt;/b&gt;는 Unity에서 이러한 종류의 코드가 주로 사용되는 곳이다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (Update: 프레임 렌더링/애니메이션 계산 전 호출)&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: #9d9d9d;&quot;&gt;(시간이 연속으로 흐르지 않고, 특정 간격(0, 1, 2...)단위로 끊어서 진행되는 것)&lt;/span&gt;로 업데이트 된다. 각 &lt;u&gt;물리 업데이트 직전&lt;/u&gt; &lt;b&gt;FixedUpdate()&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;씬의 모든 오브젝트에 Update() 및 FixedUpdate()가 호출된 시점에 &lt;u&gt;추가 변경 사항을 적용하고 모든 애니메이션이 계산된 후 변경&lt;/u&gt;하는 것이 유용할 때도 있다. &lt;b&gt;LateUpdate()&lt;/b&gt;는 이럴 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;- 카메라가 타겟 오브젝트에 대한 학습 상태를 유지해야 하는 경우(오브젝트 이둥 -&amp;gt; 카메라 방향 조정)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. [초기화 이벤트]&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;b&gt;Start()&lt;/b&gt;는 오브젝트 &lt;u&gt;첫 번째 프레임 or 물리 업데이트 전 호출&lt;/u&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 오브젝트의 Start(), Awake()가 임의 순서로 호출되더라도&lt;b&gt; Awake()&lt;/b&gt;의 모든 인스턴스는 첫번째 &lt;u&gt;Start()가 호출되기 전 완료&lt;/u&gt;된다.&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (Start() 코드는 Awake() 단계에서 이전에 수행된 다른 초기화를 사용할 수 있다)&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;3. [GUI 이벤트]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;씬의 메인 동작 GUI 컨트롤을 렌더링하고, 컨트롤 클릭에 응답하는 시스템은 주기적으로 호출되는 &lt;b&gt;OnGUI()&lt;/b&gt; 에 배치.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 오브젝트 위에 발생하는 마우스 감지, 무기 타겟팅, 현 마우스 포인터 아래 캐릭터 정보 표시 등, 접두사 &lt;b&gt;OnMouse&lt;/b&gt;로 지정된 이벤트 메서드&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(OnMouseOver(), OnMouseDown())&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;4. [물리 이벤트]&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;u&gt;접촉&lt;/u&gt;이 이루어질 때&lt;b&gt;(OnCollisionEnter)&lt;/b&gt;, &lt;u&gt;유지&lt;/u&gt;될 때&lt;b&gt;(OnCollisionStay)&lt;/b&gt;, &lt;u&gt;종료&lt;/u&gt;될 때&lt;b&gt;(OnCollisionExit)&lt;/b&gt; 메서드가 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OnTriggerEnter, OnTriggerStay, OntriggerExit&lt;/b&gt; 메서드는 오브젝트 콜라이더가 &lt;u&gt;트리거&lt;/u&gt;(물리적으로 반응하지 않고, 단순히 &lt;u&gt;무언가 들어갈 때 감지&lt;/u&gt;하는 콜라이더)로 설정될 때 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리 업데이트 중 두 개 이상 접점이 감지되어 충돌 세부 정보&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(위치, 들어오는 오브젝트 ID 등)&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;[스크립트 라이프 사이클 Life cycle]&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;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 354px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 16.2403%; height: 21px; text-align: center;&quot;&gt;&lt;b&gt;단계&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 21px; text-align: center;&quot;&gt;&lt;b&gt;메서드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 21px; text-align: center;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 16.2403%; height: 98px;&quot; rowspan=&quot;3&quot;&gt;초기화&lt;br /&gt;Initialization&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 64px;&quot;&gt;Awake()&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 64px;&quot;&gt;스크립트 실행 시 1번만 호출&lt;br /&gt;스크립트 비활성화에도 호출(오브젝트 비활성화는 호출 X)&lt;br /&gt;생성자처럼 게임 상태, 변수 초기화로 사용&lt;br /&gt;오브젝트 초기화, 프리펩 인스턴스화 진행 후 호출(Find 함수 호출 안정)&lt;br /&gt;코루틴으로 실행 X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;OnEnable&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;오브젝트 or 스크립트 활성화 시 호출&lt;br /&gt;이벤트 연결&lt;br /&gt;코루틴으로 실행 X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Start()&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;스크립트 활성화 시 1번만 호출&lt;br /&gt;오브젝트 or 스크립트 비활성화 시 호출X&lt;br /&gt;코루틴으로 실행 O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.2403%; height: 184px;&quot; rowspan=&quot;5&quot;&gt;물리 엔진&lt;br /&gt;Physics&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;FixedUpdate&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;고정된 프레임 주기로 호출&lt;br /&gt;스크립트가 활성화 되어 있어야 호출 O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 43px;&quot;&gt;OnTrigger&lt;span style=&quot;color: #9d9d9d;&quot;&gt;XXX&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 43px;&quot;&gt;두 오브젝트 충돌 체크&lt;br /&gt;물리 연산 없이 통과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 43px;&quot;&gt;OnCollision&lt;span style=&quot;color: #9d9d9d;&quot;&gt;XXX&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 43px;&quot;&gt;두 오브젝트 충돌 체크&lt;br /&gt;물리 영향O, Rigidbody 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 64px;&quot;&gt;Update&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 64px;&quot;&gt;매 프레임마다 호출되는 메서드. 디바이스 성능, 최적화에 따라 framerate가 변하므로 함수 호출 시간이 매번 달라진다.&lt;br /&gt;스크립트가 활성화 되어 있어야 호출 O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;LastUpdate&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;모든 Update 함수 호출 후 1번씩 호출&lt;br /&gt;스크립트가 활성화 되어 있어야 호출 O&lt;br /&gt;카메라 이동 로직에 주로 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.2403%; height: 51px;&quot; rowspan=&quot;3&quot;&gt;해제/종료&lt;br /&gt;Decommissioning&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;OnApplicationQuit&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;응용 프로그램 종료 전 모든 오브젝트에서 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;OnDissable&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;오브젝트 or 스크립트 비활성화 시 호출&lt;br /&gt;이벤트 연결 종료 시 사용&lt;br /&gt;코루틴으로 실행 X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;OnDestroy&lt;/td&gt;
&lt;td style=&quot;width: 63.1007%; height: 17px;&quot;&gt;오브젝트 생존 기간의 마지막 프레임 업데이트 후 실행&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[Awake VS Start]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8838%; text-align: center;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%; text-align: center;&quot;&gt;&lt;b&gt;Awake&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.4651%; text-align: center;&quot;&gt;&lt;b&gt;Start&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8838%;&quot;&gt;호출 시점&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;게임 오브젝트 초기화 (스크립트 생성 직후)&lt;/td&gt;
&lt;td style=&quot;width: 30.4651%;&quot;&gt;모든 스크립트 Awake 끝, 첫 프레임 업데이트 직전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8838%;&quot;&gt;스크립트 비활성화 시&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;실행&lt;/td&gt;
&lt;td style=&quot;width: 30.4651%;&quot;&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8838%;&quot;&gt;주요 용도&lt;/td&gt;
&lt;td style=&quot;width: 29.6511%;&quot;&gt;변수 초기화, 다른 컴포넌트 참조 가져오기&lt;/td&gt;
&lt;td style=&quot;width: 30.4651%;&quot;&gt;Awake에서 설정한 값을 바탕으로 한 추가 설정 및 로직 시작&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[Awake()]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Start() 호출 전 Scene(씬)의 모든 객체에 대해 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프리팹 인스턴스화 직후 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 게임 오브젝트 비활성화 시 호출X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스크립트간 참조 설정 시 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모든 오브젝트가 초기화되고 호출되기 때문에 타 스크립트와 연결 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 유니티의 MonoBehaviour를 상속 받은 클래스에서 사용 가능&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;[Start()]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스크립트 인스턴스가 활성화된 경우, 첫 번째 프레임 Update() 전 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Awake와 동일하게 스크립트 수명 동안 한 번만 호출, MonoBehabiour를 상속 받은 클래스에서 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(반대로 Awake는 스크립트 활성화 여부 관계 없이 스크립트 개체 초기화 시 호출된다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 씬 에셋에 포함된 모든 오브젝트에 대해 Update 등 이전에 호출된 모든 스크립트를 위한 Start 함수 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;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;- Awake와 Start의 가장 큰 차이는 실행되는 순서가 다른 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Awake는 스크립트 활성화 여부 관계 없이 스크립트 개체 초기화 시 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(비활성화 상태에서도 Awake는 호출되나, Start는 호출되지 않는다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Awake는 모든 오브젝트가 초기화되고 호출. 타 스크립트와 연결을 보장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(&lt;span style=&quot;background-color: #fafafa; text-align: start;&quot;&gt;하지만 모든 객체의 Awake 함수는 무작위로 호출된다. 때문에 한 객체의 Awake가 다른 객체보다 먼저 호출되거나 Awake에서생성한 참조가 Awake의 다른 스크립트에서 사용할 수 있음을 보장할 수 없다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Start는 게임플레이 도중 오브젝트를 인스턴스화 될 때 실행되지 않는다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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: #9d9d9d;&quot;&gt;플로우 차트(Long ver)&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플로우차트 범위는 모노 스크립팅 레퍼런스의 메세지에 문서화 된 적절한 콜백을 구현하여 모든 모노 스크립트에서 구독할 수 있는 빌트인 이벤트 함수로 제한된다. 또한 이벤트를 발생시키는 하위 시스템의 일부 추가 내부 메서드도 컨텍스트에 표시된다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;1798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5809e/dJMcadBZTJ8/EpSr6m1rAKcmcR27QAbB7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5809e/dJMcadBZTJ8/EpSr6m1rAKcmcR27QAbB7K/img.jpg&quot; data-alt=&quot;출처: Unity Documentation, Unity 6.0 (6000.0), 이벤트 함수의 실행 순서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5809e/dJMcadBZTJ8/EpSr6m1rAKcmcR27QAbB7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5809e%2FdJMcadBZTJ8%2FEpSr6m1rAKcmcR27QAbB7K%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;863&quot; height=&quot;1798&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;1798&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: Unity Documentation, Unity 6.0 (6000.0), 이벤트 함수의 실행 순서&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 843px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;순서(상황)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;메서드(함수)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 34px;&quot; rowspan=&quot;2&quot;&gt;씬 시작(오브젝트당 한 번), Start 이전&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;Awake&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;오브젝트 새 인스턴스 생성 시 호출.&lt;br /&gt;게임 오브젝트 비활성화 시 활성화 전까지 호출되지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnEnable&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;Awake 이후(동일 오브젝트 한) ~ Start 전 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 34px;&quot; rowspan=&quot;2&quot;&gt;에디터&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;Reset&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;오브젝트 첫 연결 or&lt;br /&gt;Reset 커맨드 사용 시 스크립트 속성 초기화 용도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnValidate&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;(오브젝트 역직렬화 포함)스크립트 속성이 설정될 때마다&lt;br /&gt;호출(이 외 다양한 시기)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 17px;&quot;&gt;첫 번째 프레임 업데이트 전&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;Start&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;스크립트 인스턴스가 활성화 된 경우, 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 17px;&quot;&gt;프레임 사이&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnApplicationPause&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;일반 프레임 업데이트 사이,&lt;br /&gt;일시 정지가 감지된 프레임 끝에서 호출&lt;br /&gt;게임 일시중지 그래픽스 표시를 위해&amp;nbsp;호출 후 추가 프레임 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 51px;&quot; rowspan=&quot;3&quot;&gt;업데이트 순서&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;FixedUpdate&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;게임 내 시간의 일정 간격으로 발생.&lt;br /&gt;물리 계산 및 업데이트는 해당 함수 이후 즉시 수행.&lt;br /&gt;프레임 속도와 독립적, 값에 Time.deltaTime을 곱할 필요가 없음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;Update&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;프레임 업데이트를 위한 주요 함수. 프레임당 한 번 호출.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;LateUpdate&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;Update 끝, 프레임당 한 번씩 호출&lt;br /&gt;3인칭 카메라. Update에서 캐릭터를 이동하고 회전 시 카메라 이동/회전 계산 수행 용.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 109px;&quot; rowspan=&quot;3&quot;&gt;애니메이션 업데이트 루프&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 35px;&quot;&gt;MonoBehaviour.&lt;br /&gt;OnAnimatorMove&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 70px;&quot; rowspan=&quot;2&quot;&gt;애니메이션 루프 콜백 (내용 생략)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 35px;&quot;&gt;MonoBehaviour.&lt;br /&gt;OnAnimatorIK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 39px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 39px;&quot;&gt;StateMachine&lt;br /&gt;Behaviour 및 파생&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 39px;&quot;&gt;추가 애니메이션 관련 이벤트 메서드 (내용 생략)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 247px;&quot; rowspan=&quot;9&quot;&gt;렌더링&lt;br /&gt;(빌트인 렌더 파이프라인만 적용)&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 43px;&quot;&gt;OnPreCull&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 43px;&quot;&gt;카메라가 씬 컬링 전 호출&lt;br /&gt;컬링에 따라 카메라에 보이는 오브젝트 결정(컬링 직전 호출)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 35px;&quot;&gt;OnBecameVisible/&lt;br /&gt;OnBecameInvisible&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 35px;&quot;&gt;오브젝트가 카메라에 보이거나 보이지 않을 때 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnWillRenderObject&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;오브젝트가 표시되면 각 카메라에 '한 번' 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnPreRender&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;카메라가 씬 렌더링 시작 전 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnRenderObject&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;모든 일반 씬 렌더링 완료 후 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnPostRender&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;카메라가 씬 렌더링을 마친 후 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnRenderImage&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;이미지 포스트 프로세싱 용, 씬 렌더링 완료 후 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 43px;&quot;&gt;OnGUI&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 43px;&quot;&gt;GUI 이벤트에 대한 응답, 프레임당 여러 번 호출&lt;br /&gt;(레이아웃, 리페인트 이벤트 우선)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;OnDrawGizomos&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;시각화 목적, 씬 뷰에 기즈모를 그릴 때 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 108px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 108px;&quot; rowspan=&quot;5&quot;&gt;코루틴&lt;br /&gt;(Update 함수 반환 후 실행)&lt;br /&gt;(주어진 YieldInstruction&lt;br /&gt;완료까지 실행(yield)을&lt;br /&gt;일시 중지 가능&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 108px;&quot;&gt;yield 코루틴&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 108px;&quot;&gt;모든 Update 함수가 다음 프레임에 호출된 후 계속 진행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;yield WaitForSeconds&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;모든 Update 함수가 프레임 호출 후 지정 시간이 지난 후 계속 진행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 43px;&quot;&gt;yield WaitFor&lt;br /&gt;FixedUpdate&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 43px;&quot;&gt;모든 스크립트에서 모든 FixedUpdate 호출 후 계속 진행&lt;br /&gt;FixedUpdate 이후 다시 시작&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 21px;&quot;&gt;yield WWW&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 21px;&quot;&gt;WWW 다운로드가 완료된 후 계속 진행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 39px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 39px;&quot;&gt;yield StartCoroutine&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 39px;&quot;&gt;코루틴 체이닝, 이론 코루틴 coroutineA가 yield &lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;StartCoroutine&lt;/span&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;(coroutineB()); 가 완료될 때까지 기다린 후 계속 진행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 17px;&quot;&gt;오브젝트 파괴&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnDestroy&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;오브젝트가 존재하는 마지막 프레임에&lt;br /&gt;모든 프레임 업데이트를 마친 후 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6755%; height: 17px;&quot; rowspan=&quot;2&quot;&gt;종료&lt;/td&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnApplicationQuit&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;애플 종료 전 모든 게임 오브젝트에서 호출.&lt;br /&gt;에디터에서 사용자가 플레이 모드 중지 시 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.7417%; height: 17px;&quot;&gt;OnDisable&lt;/td&gt;
&lt;td style=&quot;width: 55.5827%; height: 17px;&quot;&gt;동작이 비활성화 되거나 비활성 상태 시 이 함수 호출&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&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: #9d9d9d;&quot;&gt;[씬 뷰 및 기타 단축키]&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 198px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 17px; text-align: center;&quot;&gt;이름&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 17px; text-align: center;&quot;&gt;단축키&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 17px; text-align: center;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;핸드&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;Q&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;화면 드래그 이동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;무브&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;W&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;오브젝트(평행)이동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;회전&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;E&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;오브젝트 회전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;스케일&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;R&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;오브젝트 크기 조정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;렉터&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;T&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;UI, 2D오브젝트 크기 조정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;이동회전스케일 통합 툴&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 17px;&quot;&gt;화면 확대축소&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 17px;&quot;&gt;RC + W / S&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 21px;&quot;&gt;화면 상하 이동&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 21px;&quot;&gt;RC + Q / E&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.7538%; height: 17px;&quot;&gt;화면 좌우 이동&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%; height: 17px;&quot;&gt;RC + A / D&lt;/td&gt;
&lt;td style=&quot;width: 52.771%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.7538%;&quot;&gt;화면 이동&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%;&quot;&gt;휠 클릭&lt;/td&gt;
&lt;td style=&quot;width: 52.771%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.7538%;&quot;&gt;오브젝트 포커싱&lt;/td&gt;
&lt;td style=&quot;width: 21.4751%;&quot;&gt;오브젝트 선택 + F&lt;/td&gt;
&lt;td style=&quot;width: 52.771%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&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: #9d9d9d;&quot;&gt;[기타 팁]&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[파일 정리]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Project - Asset 에 모음집 폴더를 미리 만들고 종류 별로 나눠서 보관한다. (폴더링과 정리는 중요하다)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Prefab, Scripts, Material 등...&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[에셋 구매 팁]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;에셋 구매 시 URP 지원 O 여부 확인할 것 (X 구매시 귀찮아진다)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;습작은 로우폴리로 만들 것&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[축 정렬 기준]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Y를 위, X를 오른쪽(Z축은 보이지 않음)&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;92&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxhR1H/dJMcaf0WGVX/I144KVRZOcnV4obkhKigcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxhR1H/dJMcaf0WGVX/I144KVRZOcnV4obkhKigcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxhR1H/dJMcaf0WGVX/I144KVRZOcnV4obkhKigcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxhR1H%2FdJMcaf0WGVX%2FI144KVRZOcnV4obkhKigcK%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;92&quot; height=&quot;93&quot; data-origin-width=&quot;92&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;* 오브젝트의 정방향 기준과 월드의 정방향 기준은 다르다. (오브젝트는 항상 스스로를 원점으로 삼는다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; 오브젝트의 앞은 월드의 오른쪽이다(큐브 y축 90도 설정 시, 월드 공간의 x축과 큐브 오브젝트 공간이 z축과 일치한다)&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3Ict/dJMcaiwCt3v/eRmhgT87mkXWN8davk24LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3Ict/dJMcaiwCt3v/eRmhgT87mkXWN8davk24LK/img.png&quot; style=&quot;width: 52.1211%; margin-right: 10px;&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;337&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;52.77&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3Ict/dJMcaiwCt3v/eRmhgT87mkXWN8davk24LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3Ict%2FdJMcaiwCt3v%2FeRmhgT87mkXWN8davk24LK%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;365&quot; height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwfkVP/dJMcaicm7Et/aq3WQ4TPIXtSmARPnlFhgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwfkVP/dJMcaicm7Et/aq3WQ4TPIXtSmARPnlFhgk/img.png&quot; style=&quot;width: 46.6564%;&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;361&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;47.23&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwfkVP/dJMcaicm7Et/aq3WQ4TPIXtSmARPnlFhgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwfkVP%2FdJMcaicm7Et%2Faq3WQ4TPIXtSmARPnlFhgk%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;350&quot; height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&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;amp; 상속]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜스폼을 부모로 지정하는 경우, 부모의 위치를 &amp;lt;0,0,0&amp;gt;으로 설정한 후 자식 트랜스폼을 추가하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(로컬 좌표가 전역 좌표와 동일하므로 자식이 올바른 위치에 있는지 확인하기 더 쉬워진다.)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;a href=&quot;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1779286568892&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Unity - 매뉴얼: Unity 6 사용자 매뉴얼&quot; data-og-description=&quot;렌더링 성능 향상 렌더링, 조명, 시각 효과의 최신 고급 기능을 사용하여 확장성을 갖춘 매력적인 비주얼로 더욱 멋진 씬을 구현할 수 있습니다. 멀티플레이어 게임 제작 Unity의 멀티플레이어 패&quot; data-og-host=&quot;docs.unity3d.com&quot; data-og-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&quot; data-og-url=&quot;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLUGwz/dJMb8SXDAl4/gtyPsI8HcN1M7oKmALBKt0/img.jpg?width=240&amp;amp;height=128&amp;amp;face=0_0_240_128,https://scrap.kakaocdn.net/dn/BkgI9/dJMb8WeFt6l/zN7u7UAlWxJs9CFEB5x4m1/img.jpg?width=952&amp;amp;height=567&amp;amp;face=0_0_952_567,https://scrap.kakaocdn.net/dn/bN8PoV/dJMb8QMhOp8/DzNI8cf0Bu6fCFKJfsVHr0/img.png?width=850&amp;amp;height=478&amp;amp;face=0_0_850_478&quot;&gt;&lt;a href=&quot;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.unity3d.com/kr/current/Manual/UnityManual.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLUGwz/dJMb8SXDAl4/gtyPsI8HcN1M7oKmALBKt0/img.jpg?width=240&amp;amp;height=128&amp;amp;face=0_0_240_128,https://scrap.kakaocdn.net/dn/BkgI9/dJMb8WeFt6l/zN7u7UAlWxJs9CFEB5x4m1/img.jpg?width=952&amp;amp;height=567&amp;amp;face=0_0_952_567,https://scrap.kakaocdn.net/dn/bN8PoV/dJMb8QMhOp8/DzNI8cf0Bu6fCFKJfsVHr0/img.png?width=850&amp;amp;height=478&amp;amp;face=0_0_850_478');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Unity - 매뉴얼: Unity 6 사용자 매뉴얼&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;렌더링 성능 향상 렌더링, 조명, 시각 효과의 최신 고급 기능을 사용하여 확장성을 갖춘 매력적인 비주얼로 더욱 멋진 씬을 구현할 수 있습니다. 멀티플레이어 게임 제작 Unity의 멀티플레이어 패&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.unity3d.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>개발일지/Unity</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/75</guid>
      <comments>https://nanaya0630.tistory.com/75#entry75comment</comments>
      <pubDate>Wed, 20 May 2026 23:16:26 +0900</pubDate>
    </item>
    <item>
      <title>[C#]캡슐화, 포함, 상속, 오버라이딩</title>
      <link>https://nanaya0630.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[캡슐화 (EnCalpsulation)]&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필드를 private로 선언, 외부에서 접근을 금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 경우에만 public 메서드나 프로퍼티를 통해 접근&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;데이터 보호: private로 필드 사용, 잘못된 데이터 변경 방지&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;잘못된 값 방지: set에서 유효성 검사 추가로 오류 방지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[사용처]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요 데이터 보호(레벨, 공격력, 경험치 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에서 임의로 데이터를 수정하면 안되는 경우(비밀번호, 은행 계좌 및 금액)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 내부에서 데이터 변화를 안전하게 관리해야 할 때&lt;/p&gt;
&lt;pre id=&quot;code_1778048351292&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	//접근 제한자로 데이터 보호
	private string name;
    private int health;
    
    public Character(string name, int health)
    {
    	this.name = name; //this: 클래스 내 메소드에서 클래스 멤버변수값을 사용할 시 자신을 가리키는 키워드
        this.health = health;
    }
    //공개 메서드를 통해 읽을 수 있는 데이터 제공
    public void ShowStatus()
    {
    	Console.WriteLine($&quot;{name}, {health}&quot;};
    }
    //공개된 메서드를 통해 체력을 감소시킨다.
    public void TakeDamage(int damage)
    {
    	health -= damage;
    }
}
class Character1
{
	private string name;
    private int health;
    //프로퍼티를 통해 name의 값을 읽기 전용으로 제공
    public string Name
    {
    	get { return name; }
    }
    public int Health
    {
    	get { return health; }
        private set //접근제한자로 내부에서만 쓰기 가능
        {
        	if (value &amp;lt; 0) health = 0;
            else health = value;
        }
    }
	public Character1(string name, int health) //생성자
    {
    this.name = name;
    Health = health;
    }
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 클래스가 다른 클래스의 인스턴스를 멤버 변수로 포함하고 그 객체의 기능을 자신의 일부처럼 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포함된 객체는 포함하는 객체가 소멸될 때 함께 소멸한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개된 메서드를 통해 접근해야 외부에서 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식클래스는 부모클래스의 모든 public, protected멤버를 상속한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식클래스는 부모클래스의 기능을 재정의(오버 라이딩)하거나 추가할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#에서 다중 상속은 지원되지 않는다.&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 상속과 오버라이딩을 사용하지 않은 코드의 경우,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;확장성이 없어지며, 중복이 발생하며, 공통 기능을 수정하게 되면 모든 클래스를 갈아엎어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1778049347786&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Warrior
{
	private string Name;
    private int Health;
    private int AttackPower;
    private int Defense;
    
    public Warrior(string name)
    {
    	Name = name;
        Health = 120;
        AttackPower = 15;
        Defense = 5;
    }
    public void Attack()
    {
    	Console.WriteLine($&quot;{Name}이 기본공격을 한다. 공격력: {AttackPower}&quot;);
    }
    public void HeavyAttack()
    {
    	Console.WriteLine($&quot;{Name}이 강한공격을 한다. 공격력: {AttackPower * 2}&quot;);
    }
    public void TakeDamage(int damage)
    {
    	int reduceDamage = Math.Max(damage - Defense, 0); //Math.Max: (값1, 값2)둘 중 더 큰 값을 결과로 선출
        Health -= reduceDamage;
        Console.WriteLine($&quot;{Name}이 {reduceDamage} 피해를 입었다. 체력: {Health}&quot;);
    }
    public void ShowStatus()
    {
    	Console.WriteLine($&quot;{Name} 체력: {Health}, 공격력: {AttackPower}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 부모를 수정할 때마다 자식도 수정해야 하는 번거로움과 실수를 줄일 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1778049693590&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//부모
class Character
{
	public string Name { get; protected set; }
    public int Health { get; protected set; }
    public int AttackPower { get; protected set; }
    
    public Character(string name, int health, int attackPower)
    {
    	Name = name;
        Health = health;
        AttackPower = attackPower;
    }
    public void ShowStatus()
    {
    	Console.WriteLine($&quot;{Name} 체력: {Health}, 공격력: {AttackPower}&quot;);
    }
}
//자식
class Warrior: Character //필수 매개변수 변수name엥 해당하는 인수를 작성한다.
{
	private int defense; //자식클래스 Warrior의 추가 필드
    
    //base: 부모클래스 멤버에 접근할 때 사용. 상속관계에서 부모의 생성자나 멤버 호출용
    public Warrior(string name): base(name, 120, 15)
    {
    	defense = 5;
    }
    //부모의 속성에서 없던 것을 자식에게 별개로 추가할 수 있다.
    public void HeavyAttack()
    {
    	Console.WriteLine($&quot;{Name}이 강한공격을 한다. 공격력: {AttackPower * 2}&quot;);
    }
    public void TakeDamage(int damage)
    {
    	int reduceDamage = Math.Max(damage - Defense, 0);
        Health -= reduceDamage;
        Console.WriteLine($&quot;{Name}이 {reduceDamage} 피해를 입었다. 체력: {Health}&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;[포함 vs 상속]&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.10074%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.5194%;&quot;&gt;포함&lt;/td&gt;
&lt;td style=&quot;width: 49.3798%;&quot;&gt;상속&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.10074%;&quot;&gt;관계&lt;/td&gt;
&lt;td style=&quot;width: 42.5194%;&quot;&gt;(has-a)한 클래스가 다른 클래스를 소유하고 포함&lt;/td&gt;
&lt;td style=&quot;width: 49.3798%;&quot;&gt;자식은 부모의 확장(is-a)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.10074%;&quot;&gt;상속&lt;/td&gt;
&lt;td style=&quot;width: 42.5194%;&quot;&gt;포함된 객체의 기능을 내부적으로 사용&lt;/td&gt;
&lt;td style=&quot;width: 49.3798%;&quot;&gt;부모클래스를 확장하거나 수정할때 유용&lt;br /&gt;두 클래스의 결합도가 높아질 수 있다(다형성)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.10074%;&quot;&gt;예시&lt;/td&gt;
&lt;td style=&quot;width: 42.5194%;&quot;&gt;기능을 조립해서 만들 때(무기, 속성, 스킬 등)&lt;/td&gt;
&lt;td style=&quot;width: 49.3798%;&quot;&gt;몬스터, 캐릭터와 같은 리스트를 다양하게 만들고 관리할 때&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;is-a: (00은 00이다: 사과는 과일이다, 사자는 동물이다... 개념 간의 확장)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;has-a: (00은 00을 가졌다: 검사는 검을 소유한다, 나는 파이어볼 스킬을 가졌다 등... 소유의 영역)&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;/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;virtual: 부모클래스에서 이 메서드는 자식클래스에서 오버라이딩 가능하다를 명시하는 키워드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;override: 부모의 virtual 메서드를 재정의 하는 키워드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sealed: 봉인, 자식클래스에서 더이상 오버라이딩을 허용하지 않는 의미로 사용하는 키워드&lt;/p&gt;
&lt;pre id=&quot;code_1778050631365&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//부모
class Character
{
	protected string Name { get; set; }
    public Character(string name)
    {
    	Name = name;
    }
    public virtual void Attack() //반환형 앞 virtual: 오버라이딩 가능
    {
    	Console.WriteLine($&quot;{name}이(가) 기본공격을 한다.&quot;);
    }
}
//자식Worrior
class Warrior : Character
{
	public Warrior(string name): base(name) { }
    public override void Attack() //오버라이딩 - 재정의
    {
    	Console.WriteLine($&quot;{Name}이 검으로 강하게 내려친다!&quot;);
    }
}
class Mage : Character
{
	public Mage(string name): base(name) { }
    public override void Attack()
    {
    	base.Attack(); //부모의 Attack()메서드 호출(원래 기능도 같이 사용)
        Console.WriteLine($&quot;{Name}의 얼음 공격!&quot;);
    }
}

internal class Program

static void Main()
{
	//다형성: 하나의 인터페이스가 다양한 방식으로 동작할 수 있도록 하는 OOP의 개념
    Character warrior = new Warrior(&quot;홍길동&quot;);
    Character mage = new Mage(&quot;법사&quot;);
    
    warrior.Attack();
    mage.Attack();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;+ 위와 같이 Attack를 한번에 출력하고 싶다면, 배열과 foreach기능을 응용하여 다음과 같이 작성할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1778050800108&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void Main()
{
	Character[] c = new Character[]
    {
    	new Warrior { Name = &quot;전사&quot; },
        new Mage { Name = &quot;법사&quot; }
    };
    foreach(Character unit in c)
    {
    	unit.Attack(); //다형성에 의해 각자 재정의 된 Attack 실행
    }
}&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[오버로딩과 오버라이딩의 차이점]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버로딩(Overloading)은 한 클래스 내 매개변수를 다르게 하여 같은 이름의 메서드를 여러개 정의하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버라이딩(Overriding)은 상속 관계에서 부모의 메서드를 자식 클래스에서 재정의하는 것.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 93.2557%; height: 147px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;오버로딩(Overloading)&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;오버라이딩(Overriding)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;관계&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;&lt;b&gt;같은 클래스&lt;/b&gt; 내&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;&lt;b&gt;상속 관계&lt;/b&gt;(부모 - 자식)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;메서드명&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;동일&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;동일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;매개변수&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;다름(개수, 타입, 순서 등)&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;동일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;리턴&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;상관X&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;동일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;바인딩&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;정적 (컴파일 타임)&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;동적 (실행 타임)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 11.7378%; height: 21px;&quot;&gt;&lt;b&gt;핵심&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.2011%; height: 21px;&quot;&gt;&lt;b&gt;같은 이름의 메서드를 여러개 정의&lt;span style=&quot;color: #ee2323;&quot;&gt;(기능 확장)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.061%; height: 21px;&quot;&gt;&lt;b&gt;상속받은 메서드를 재정의&lt;span style=&quot;color: #ee2323;&quot;&gt;(기능 변경)&lt;/span&gt;&lt;/b&gt;&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;</description>
      <category>개발일지/C#</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/47</guid>
      <comments>https://nanaya0630.tistory.com/47#entry47comment</comments>
      <pubDate>Wed, 6 May 2026 16:16:44 +0900</pubDate>
    </item>
    <item>
      <title>[C#]속성, 생성자, 인스턴스/정적 메서드</title>
      <link>https://nanaya0630.tistory.com/46</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[필드 Field]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;클래스나 구조체 내에서 데이터를 선언(저장)하는 &lt;b&gt;변수&lt;/b&gt;(객체 상태, 데이터를 저장)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[속성 Property]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;클래스 내부 필드 값에 안전하게 접근하는 통로(getter - 가져오다/setter - 값을 넣다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내부 데이터를 &lt;b&gt;보호&lt;/b&gt;하며, 필요할 때만 값을 읽거나 쓸 때 사용한다. &lt;span style=&quot;color: #333333;&quot;&gt;(데이터 &lt;b&gt;캡슐화&lt;/b&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[사용 이유]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- set 블록에 조건문을 사용하여 잘못된 값이 들어오는 것을 차단&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- get과 set의 접근제한자를 달리 설정하여 외부 읽기 전용 상태 등을 만들 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 필요에 따라 get/set을 단독으로만 사용할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 메서드 형태 호출 방식보다 대입 연산자 사용이 보기 편할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 자동구현 프로퍼티를 통해 코드양을 줄일 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(여기서 프로퍼티(속성)는 주로 파스칼케이스가 자주 사용된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;예시 1&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1778044096553&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	string name;
    public string Name
    {
    	get { return name; }
        set { name = value; }
    }
}

Internal class Program
{
	static void Main()
    {
    	Character player = new Character();
        player.Name = &quot;전사&quot;; //set
        Console.WriteLine(player.Name); //get
    }
}&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: 읽기 전용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;get만 제공하고 set이 없을 시 읽기만 가능한 프로퍼티.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 데이터를 외부에서 변경하지 못하도록 보호할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1778044292640&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	private int level = 1;
    public int Level
    {
    	get { return level; }
    }
}

internal class Program
{
	static void Main()
    {
		Character player = new Character();
		Console.WriteLine(player.Level);
		//player1.Level = 2; //읽기 전용, 값을 할당할 수 없다.
	}
}&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: 쓰기 전용&lt;/p&gt;
&lt;pre id=&quot;code_1778044578028&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	string name;
    public string Name
    {
    	set { name = value; }
    }
}

inter class Program
{
	static void Main()
    {
    	Character player = new Character();
        player.Name = &quot;출력되지 않는 비밀 정보입니다.&quot;;
        //Console.WriteLine(player.Name); //쓰기 전용, 출력 불가능(읽기 불가능)
    }
}&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;간단한 속성을 정의할 때 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 set에서 유효성 검사를 통해 잘못된 값이 입력되지 않도록 보호 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1778044889817&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	int level;
    public int Level
    {
    	get { return level; }
        set
        {
        	if (value &amp;lt; 1)
            {
            	Console.WriteLine(&quot;레벨은 1 이상이어야 한다!&quot;);
                level = 1;
            }
            else
            { level = value; }
        }
    }
}

internal class Program
{
	static void Main()
    {
    Character player = new Character();
    player.Level = -5;
    Console.WriteLine(player.Level); //set의 if문을 통해, 레벨이 1미만일 경우 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;[private set]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에선 읽기만 가능, 값 설정은 내부에서만 가능하게 설정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번 설정된 값이 외부에서 변경되지 않도록 보호할 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자나 내부 메서드에서만 값 변경이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1778045426742&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	public string Name { get; private set; }
    public Character(string name)
    {
    	Name = name; //생성자 내부에서는 값 설정 가능
    }
}

internal class Program
{
	static void Main()
    {
    	Character player = new Character(&quot;마법사&quot;);
        Console.WriteLine(player5.Name);
        //player5.Name = &quot;나는야 전사라네&quot; //private set으로 쓰기 불가능
    }
}&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기상태를 설정하는 역할로, &lt;b&gt;클래스 이름과 동일&lt;/b&gt;하고 반환형(void)이 없다.&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;[생성자 오버 로딩]&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 반환값이 없으며 외부에서 한 번은 호출되어야 하기에 public이 기본 상태여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;소멸자(종료자)는 C#에서는 GC가 정리하기에 사용할 필요 없다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1778045683711&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Character
{
	private string name { get; set; }
    private int level { get; set; } //프로퍼티 자동구현
    
    public Character() //생성자: 클래스 이름과 동일하다
    {
    	Name = &quot;초보자&quot;;
        Level = 1;
        Console.WriteLine(&quot;기본 캐릭터가 생성되었다.&quot;);
    }
    //오버로딩: 이름을 입력받은 경우
    public Character(string name)
    {
    	Name = name;
        Level = 1;
        Console.WriteLine($&quot;이름이 설정된 캐릭터 {Name}가 생성되었다.&quot;);
    }
    //오버로딩: 이름과 레벨을 입력받은 경우
    public Character(string name, int level)
    {
    	Name = name;
        Level = level;
        Console.WriteLine($&quot;레벨이 설정된 캐릭터 {Name}(레벨 {Level})가 생성되었다.&quot;);
    }
}

internal class Program
{
	static void Main()
    {
    	//생성자 호출
    	Character player1 = new Character();
        Character player2 = new Character(&quot;악마술사&quot;)
        Character player3 = new Character(&quot;마법사&quot;, 3);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qOOOx/dJMb99M01B1/D7H0So8CiFnngqqruS7zCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qOOOx/dJMb99M01B1/D7H0So8CiFnngqqruS7zCK/img.png&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qOOOx/dJMb99M01B1/D7H0So8CiFnngqqruS7zCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqOOOx%2FdJMb99M01B1%2FD7H0So8CiFnngqqruS7zCK%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;656&quot; height=&quot;74&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;74&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 인스턴스 생성 후 호출 가능한 메서드. 해당 상태를 변경하거나 참조할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[정적 메서드]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 생성 없이 클래스 이름을 통해 호출하며, 인스턴스 필드에 접근할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static 키워드를 사용하여 선언하며, 정적 필드만 접근할 수 있다.&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;static 키워드를 사용하여 선언하며, 인스턴스를 생성할 수 없다.&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;&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;pre id=&quot;code_1778046966023&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//정적 메서드: 공통적으로 사용하거나 응용이 많이 될 때 사용된다.
class GameUtills //게임 공지 메시지 출력(응용 기능)
{
	public static void PrintMessage(string msg)
    {
    	Console.WriteLine(msg);
    }
}
//정적 클래스 + static 사용
//공통적으로 쓰이는 기능이다.
static class MathUtils //지름 계산 기능(공용 기능)
{
	public static double Pi = 3.141592;
    public static int Add(int a, int b)
    {
    	return a + b;
    }
    public static double CircleArea(double radius)
    {
    	return Pi * radius * radius;
    }
}

class Calculator //일반 클래스 + 정적 메서드 포함
{
	//static int num 1; //정적 변수
   	//int a = 1;
    //int d = 3; //인스턴스 필드 a, b
    //public void Print() { } //인스턴스 메서드
    public static int Add(int a, int b) //정적 메서드(정적 필드 (정적 변수))
    {//정적 메서드는 인스턴스와 다른 공간에 올라가기에, 인스턴스 필드에 접근을 허용하지 않는다.
    	//a = 1; //접근 불가능
        //Print(); //접근 불가능
    	return a + b;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발일지/C#</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/46</guid>
      <comments>https://nanaya0630.tistory.com/46#entry46comment</comments>
      <pubDate>Wed, 6 May 2026 15:02:28 +0900</pubDate>
    </item>
    <item>
      <title>[C#]클래스, 인스턴스, 얕은 복사와 깊은 복사, 접근 제한자</title>
      <link>https://nanaya0630.tistory.com/45</link>
      <description>&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[OOP]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;객체 지향 프로그래밍(Object-Oriented Programming)&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로그램을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;객체 단위&lt;/span&gt;로 나눠 만드는 방식&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;OOP를 사용하는 이유&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;1. 코드 정리: 관련 데이터, 기능을 한 곳에 모을 수 있음.(쉬운 유지보수)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;2. 재사용 가능: 한 번 만든 클래스 계속 재사용 가능.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;3. 현실처럼 생각 가능: &quot;캐릭터&quot;, &quot;아이템&quot; 이런식의 직관적 설계 가능.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[객체 Object]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;설계도인 class로부터 만들어진 인스턴스 &lt;b&gt;실체(구성요소)&lt;/b&gt;를 객체로 정의한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;ex)붕어빵은 객체&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[클래스 Class]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;- 참조 형식&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 객체를 생성하는&lt;span&gt; &lt;/span&gt;&lt;b&gt;설계도.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;필드, 속성, 생성자, 메서드 등을 정의하고 &lt;/span&gt;그룹화하여 자체 사용자 지정 형식을 만들 수 있는 구문.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이를 기반으로 여러 인스턴스를 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;ex)붕어빵틀은 클래스&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[필드 Field]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;클래스나 구조체 내에서 데이터를 선언(저장)하는 변수(객체 상태, 데이터를 저장)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[속성 Property]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;클래스 내부 필드 값을 안전하게 접근하는 통로(get - 가져오다/set - 값을 넣다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;데이터 유효성을 검사하거나 읽기 전용으로 만든다(데이터 캡슐화)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[생성자 Constructor]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;객체를 생성될 때 자동으로 실행되는 특수 메서드. 무조건 public, 딱 한번 호출, 안정성 보장&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;클래스 이름과 동일하며, 반환타입이 없다. 주로 객체를 초기화하고 메모리 할당을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;new 키워드를 사용하여 클래스 인스턴스를 생성할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[메서드 Method]&lt;/b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (함수(Function)와 유사하나, 함수는 더 큰 개념이고 &lt;b&gt;독립&lt;/b&gt;적이다)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클래스 내부에 소속&lt;/b&gt;하며 상태, 행위, 기능을 정의한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[인스턴스 Instance]&lt;/b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt; (객체가 더 넓은 개념, 인스턴스는 구체적인 실체)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실체화 결과물, &lt;/b&gt;특정 클래스를 바탕으로 &lt;b&gt;연관된 객체. &lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;'new' 키워드를 사용하여 메모리에 실제 객체를 생성한 결과물.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;객체를 생성하는 것을 인스턴스화 한다고 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;ex)붕어빵이 객체라면, 인스턴스는 팥붕 슈붕 피붕&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;만약 클래스가 없다면, 설계도가 없으니 매번 객체를 만들 때마다 수작업 해야한다.(효율 저하)&lt;br /&gt;하지만 설계도 하나를 잘 만들면 객체 하나를 무한대 찍어낼 수 있다.&lt;br /&gt;또한, 인스턴스들의 공통 기능을 수정할 때 일일이 고칠필요 없이 설계도만 고치면 된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[정적 메서드 Static Method]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클래스 내에 포함되나, 객체와 독립적인 메서드. 클래스에 인스턴스 생성 없이 클래스명으로 바로 사용 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인스턴스마다 메서드를 생성하지 않아&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;효율적&lt;/b&gt;이며, 인스턴스 생성 과정이 생략되어&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드가 간결&lt;/b&gt;해진다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;'static' 키워드로 선언.&lt;/p&gt;
&lt;pre id=&quot;code_1777532912823&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static int Add(int a, int b)
{
	return a + b;
}
Console.WriteLine($&quot;10 더하기 20은 {Add(10, 20)} 입니다.&quot;); //30&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[인스턴스 메서드 Instant Method]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클래스 내 static가 붙지 않았으며, 'new'와 같은 키워드 등으로 인스턴스를 생성해야 사용 가능한 메서드.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 인스턴스는 별도의 메모리 공간을 가지며, 인스턴스 메서드는 공간에 있는 데이터를 처리한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 객체의 상태를 유지하며&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;캡슐화와 유지보수&lt;/b&gt;에 유리하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정적 메소드와 인스턴스 메소드의 차이는 &lt;b&gt;인스턴스 변수 사용 유무&lt;/b&gt;로 나뉜다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #8cb3be;&quot;&gt;클래스명&lt;/span&gt; &lt;span style=&quot;color: #99cefa;&quot;&gt;변수명&lt;/span&gt; = &lt;span style=&quot;color: #006dd7;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #8cb3be;&quot;&gt;클래스명&lt;/span&gt;();&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777531957975&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Car //클래스: 자동차
{
	//변수: 자동차 기능 공간
    public string modelName;
    public string color;
    public int speed;
    //메서드: 자동차가 수행하는 행위
    public void Accel()
    {
    	speed += 10;
        Console.WriteLine($&quot;{modelName}이(가) 가속합니다. 현재 속도: {speed}&quot;);
    }
.
.
static void Main()
{
	//자동차1 인스턴스
    Car regalia = new Car();
    regalia.modelName = &quot;레갈리아 녹티스 오리진&quot;;
    regalia.color = &quot;검정색&quot;;
    regalia.speed = 0;
    //자동차2 인스턴스
    Car lowrider = new Car { modelName = &quot;로우라이더 T1 린드블룸 에디션&quot;, color = &quot;주황색&quot;, speed = 0 };
    
    regalia.Accel();
    lowrider.Accel();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP2feE/dJMcajaX7W8/wl6ZPYJF4INwLqsxK2HLX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP2feE/dJMcajaX7W8/wl6ZPYJF4INwLqsxK2HLX1/img.png&quot; data-alt=&quot;출력 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP2feE/dJMcajaX7W8/wl6ZPYJF4INwLqsxK2HLX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP2feE%2FdJMcajaX7W8%2Fwl6ZPYJF4INwLqsxK2HLX1%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;743&quot; height=&quot;99&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출력 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클래스(참조)는 구조체(값)와 달리 대입연산 시 같은 인스턴스를 참조한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 64.5349%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.06977%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 9.30229%; text-align: center;&quot;&gt;형식&lt;/td&gt;
&lt;td style=&quot;width: 24.9497%; text-align: center;&quot;&gt;복사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.06977%; text-align: center;&quot;&gt;구조체&lt;/td&gt;
&lt;td style=&quot;width: 9.30229%;&quot;&gt;값 형식&lt;/td&gt;
&lt;td style=&quot;width: 24.9497%;&quot;&gt;원본 복사 (deep copy - 깊은 복사)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.06977%; text-align: center;&quot;&gt;클래스&lt;/td&gt;
&lt;td style=&quot;width: 9.30229%;&quot;&gt;참조 형식&lt;/td&gt;
&lt;td style=&quot;width: 24.9497%;&quot;&gt;객체 주소 복사 (shallow copy - 얕은 복사)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[깊은 복사 Deep Copy] &lt;/b&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;- 값 타입&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 자체를 복사하며, 복사된 데이터는 새 메모리 공간에 할당된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 객체는 완전히 독립적인 메모리를 차지하게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1777534110458&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct ValueType //구조체 
{
	public int value;
}

static void Main()
{
	ValueType valueType1 = new ValueType() { value = 10 };
    ValueType valueType2 = valueType1; //값 복사(10)
    valueType2.value = 20; //valueType2을 20으로 초기화
    Console.WriteLine(valueType1.value); //10 //값 복사이기 때문에, 원본에 영향x
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[얕은 복사 Shallow Copy] &lt;span style=&quot;color: #ef5369;&quot;&gt;- 참조 타입&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(최소한의 복사)주소 값을 복사하며, 힙 영역에 새 공간을 생성하지 않고 스택에 같은 주소를 참조한다(힙 영역의 참조 값을 동일하게 보는 상태)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 내용을 수정하면 다른 쪽에도 영향을 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1777534666212&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class RefType
{
	public int value;
}

static void Main()
{
	RefType refType1 = new RefType() { value = 10 };
	RefType refType2 = refType1; //객체 주소 복사
	refType2.value = 20; //값 변경 시, 다른 쪽에도 영향
	Console.WriteLine(refType1.value); // 20
}&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 91.1627%; height: 273px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 17px; text-align: center;&quot;&gt;깊은 복사&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; text-align: center; height: 17px;&quot;&gt;얕은 복사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 21px; text-align: center;&quot;&gt;복사 수준&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 21px;&quot;&gt;데이터 값 복사&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; height: 21px;&quot;&gt;(최소 복사)주소 복사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 21px; text-align: center;&quot;&gt;참조 주소&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 21px;&quot;&gt;복사 값에 새 주소 할당&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; height: 21px;&quot;&gt;원본과 같은 주소 참조&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 21px; text-align: center;&quot;&gt;독립성&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 21px;&quot;&gt;독립적(영향 없음)&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; height: 21px;&quot;&gt;원본 수정 시 복사본도 영향&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 21px; text-align: center;&quot;&gt;속도&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 21px;&quot;&gt;비교적 느림&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; height: 21px;&quot;&gt;빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 8.33829%; height: 21px; text-align: center;&quot;&gt;주요 사용&lt;/td&gt;
&lt;td style=&quot;width: 22.9455%; height: 21px;&quot;&gt;복잡한 중첩 구조 객체&lt;br /&gt;(원본 토대 복사 후 개별 인스턴스 제작 시)&lt;/td&gt;
&lt;td style=&quot;width: 24.3487%; height: 21px;&quot;&gt;단순 구조 객체&lt;br /&gt;(변경 사항이 원본에 반영되어야 할 때)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[+]&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Swap기능을 응용하여 복사에 대해 좀 더 자세히 알아보자&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[깊은 복사]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777535060159&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void Main()
{
	ValueType leftValue = new ValueType() { value = 10 }; //L에 10 초기화
	ValueType rightValue = new ValueType() { value = 20 }; //R에 20 초기화
	Swap(leftValue, rightValue);
    //데이터 복사본이 메서드로 들어가기에, 원본은 바뀌지 않는다.(ValueType 안에서만 유효한 수)
	Console.WriteLine($&quot;{leftValue.value}, {rightValue.value}&quot;); //20, 10
}

static void Swap(ValueType left, ValueType right)
{
	int temp = left.value;
	left.value = right.value;
	right.value = temp;
    //여기서 바뀐건 메서드 안에서만 유효한 복사(값 형식)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[얕은 복사]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777535641728&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void Main()
{
	RefType leftRef = new RefType() { value = 10 };
	RefType rightRef = new RefType() { value = 20 };
	Swap(leftRef, rightRef);
    //원본 주소가 매서드로 들어가기에 원본이 바뀐다.
	Console.WriteLine($&quot;{leftRef.value}, {rightRef.value}&quot;); //20, 10
}

static void Swap(ValueType left, ValueType right)
{
	int temp = left.value;
	left.value = right.value;
	right.value = temp;
    //주소를 따라서 힙에 있는 실제 값을 바꿈으로 원본이 바뀜
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;style5&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[접근 제한자]&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;클래스, 필드, 메서드, 프로퍼티, 변수 등에 접근할 수 있는 범위를 제한하는 키워드.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;캡슐화(Encapsulation)를 통해 &lt;b&gt;데이터 보호, 은닉, 유지보수성&lt;/b&gt;을 높이는 핵심 역할을 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 보호가 우선인 클래스 변수는 private이 기본,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;메서드 변수는 다른 클래스나 외부에서 자유롭게 접근 할 수 있도록 public이 기본이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;접근 제한자&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;접근 가능 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;private&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;클래스 내부에서만 접근 가능&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;같은 클래스 내부에서만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;public&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;어디서든지 접근 가능&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;모든 클래스, 모든 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;protected&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;현재 클래스 + 상속 클래스 접근 가능&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;같은 클래스 + 자식 클래스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;internal&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;같은 프로젝트에서만 접근 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;동일 프로젝트 내&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;protected internal&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;같은 프로젝트 + 상속 클래스 접근 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;같은 프로젝트 모든 클래스 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;+ 다른 프로젝트의 자식 클래스&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.9147%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;private protected&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 44.1472%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;같은 클래스 + 같은 프로젝트 내 상속 클래스 접근 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.938%;&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;같은 프로젝트에서 상속받은 경우에만&lt;/span&gt;&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;</description>
      <category>개발일지/C#</category>
      <author>초코보</author>
      <guid isPermaLink="true">https://nanaya0630.tistory.com/45</guid>
      <comments>https://nanaya0630.tistory.com/45#entry45comment</comments>
      <pubDate>Thu, 30 Apr 2026 17:09:47 +0900</pubDate>
    </item>
  </channel>
</rss>