<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>seonhwan2547 님의 블로그</title>
    <link>https://seonhwan2547.tistory.com/</link>
    <description>seonhwan2547 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Mon, 6 Apr 2026 21:12:57 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>seonhwan2547</managingEditor>
    <item>
      <title>Unreal 상하체 분리 애니메이션 적용하기</title>
      <link>https://seonhwan2547.tistory.com/95</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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 해당 동작에 사용된 애니메이션들은 모두 전신 애니메이션이였기 때문에, 원하는 표현을 위해서는 상체와 하체의 동작을&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분리해서 적용해야 했다.&lt;/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;이에 따라 하체는 이동과 회전에 맞는 Run 모션을 유지하고, 상체는 창을 정비하는 동작을 재생하도록 구성하여 두 동작이 자연스럽게 동시에 보이도록 구현했다.&lt;/p&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/Mj45R/dJMcajawcrp/05cMXumeSIIakJUwjkn8c1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mj45R/dJMcajawcrp/05cMXumeSIIakJUwjkn8c1/img.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;211&quot; data-is-animation=&quot;true&quot; data-filename=&quot;khazan_walk.gif&quot; style=&quot;width: 49.5354%; margin-right: 10px;&quot; data-widthpercent=&quot;50.12&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mj45R/dJMcajawcrp/05cMXumeSIIakJUwjkn8c1/img.gif&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMj45R%2FdJMcajawcrp%2F05cMXumeSIIakJUwjkn8c1%2Fimg.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;400&quot; height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UfyQP/dJMcadH8v6K/4hp2G9BrIpBCgKcclvvSxK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UfyQP/dJMcadH8v6K/4hp2G9BrIpBCgKcclvvSxK/img.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;212&quot; data-is-animation=&quot;true&quot; data-filename=&quot;khazan_attack.gif&quot; style=&quot;width: 49.3018%;&quot; data-widthpercent=&quot;49.88&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UfyQP/dJMcadH8v6K/4hp2G9BrIpBCgKcclvvSxK/img.gif&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUfyQP%2FdJMcadH8v6K%2F4hp2G9BrIpBCgKcclvvSxK%2Fimg.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;400&quot; height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽 Run Motion 오른쪽 Attack Motion&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해당 두 개의 모션을 섞은 결과&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;khazan_animation_divde.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZrjjo/dJMb99Ti4hA/EXR6eDIOBkeIkEU7BiKZiK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZrjjo/dJMb99Ti4hA/EXR6eDIOBkeIkEU7BiKZiK/img.gif&quot; data-alt=&quot;khazan 애니메이션 상하체 분리 애니메이션 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZrjjo/dJMb99Ti4hA/EXR6eDIOBkeIkEU7BiKZiK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bZrjjo/dJMb99Ti4hA/EXR6eDIOBkeIkEU7BiKZiK/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;400&quot; height=&quot;225&quot; data-filename=&quot;khazan_animation_divde.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;khazan 애니메이션 상하체 분리 애니메이션 적용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1977&quot; data-origin-height=&quot;755&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ezBoy6/dJMcahDM7wa/wkqUGHcJXB4H96le8YXO00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ezBoy6/dJMcahDM7wa/wkqUGHcJXB4H96le8YXO00/img.png&quot; data-alt=&quot;Layered blend per bone을 사용하여 상하체 분리 애니메이션 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ezBoy6/dJMcahDM7wa/wkqUGHcJXB4H96le8YXO00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FezBoy6%2FdJMcahDM7wa%2FwkqUGHcJXB4H96le8YXO00%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;1977&quot; height=&quot;755&quot; data-origin-width=&quot;1977&quot; data-origin-height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Layered blend per bone을 사용하여 상하체 분리 애니메이션 적용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Layer Blend Per Bone 노드를 활용하여 상체와 하체 애니메이션을 분리하여 재생하였다.&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;Base Pose&amp;nbsp;&lt;/b&gt;에는 기본적으로 전체 움직임을 담당하는 원래 애니메이션을 연결하고,&amp;nbsp; &lt;b&gt;Blend Pose 0&amp;nbsp;&lt;/b&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;Blend Pose 0&lt;/b&gt;의 블렌드 기준이 되는 본을 저장하여, 해당 본을 기준으로 상위 계층의 뼈들은 Default Slot 몽타주 애니메이션이 덮어쓰도록 설정하였다.&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;여기서는 상체 동작을 확실하게 적용하기 위해 Blend Weight 값을 1.0으로 주어, 지정한 상체 영역이 해당 애니메이션으로 완전히 대체되도록 구성하였다.&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;또한 몽타주에 재생되는 상체 애니메이션의 길이와 타이밍에 맞춰 자연스럽게 전환되도록, Default Slot의 재생 상태를 기준으로 상체 애니메이션의 진행 시점을 동기화 하였다.&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;</description>
      <category>Unreal Project/Khazan 모작 프로젝트</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/95</guid>
      <comments>https://seonhwan2547.tistory.com/95#entry95comment</comments>
      <pubDate>Wed, 25 Mar 2026 19:09:24 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 7 (Camera Shake, State Alias(점프), UI 이벤트)</title>
      <link>https://seonhwan2547.tistory.com/94</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Camera Shake&lt;/b&gt;&lt;/h3&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;이런 연출은 타격감과 액션의 몰입감을 높여주는 중요한 요소이며, 언리얼 엔진에서는 이를 Camera Shake 기능으로&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;이번에는 언리얼 Blueprint에서 Camera Shaking을 적용하는 기본 방법에 대해 정리해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt; Character에 Camera Shake Source 컴포넌트 추가하기&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;먼저 카메라 흔들림의 기준이 될 수 있도록 캐릭터 블루프린트에 Camera Shake Source 컴포넌트를 추가합니다.&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.&lt;/b&gt;&amp;nbsp; Camera Shake Blueprint 생성 및 설정하기&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;다음으로는 Camera Shake Blueprint를 생성한 뒤, 흔들림의 패턴과 강도를 성정해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 블루프린트의 Class Defaults에서는 카메라가 어떤 방식으로 흔들릴지 세부적으로 조절할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2161&quot; data-origin-height=&quot;1268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s80gJ/dJMcadnNuUl/ec7nttNwFqhXWPnFOoWxrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s80gJ/dJMcadnNuUl/ec7nttNwFqhXWPnFOoWxrk/img.png&quot; data-alt=&quot;Camera Shake 설정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s80gJ/dJMcadnNuUl/ec7nttNwFqhXWPnFOoWxrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs80gJ%2FdJMcadnNuUl%2Fec7nttNwFqhXWPnFOoWxrk%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;2161&quot; height=&quot;1268&quot; data-origin-width=&quot;2161&quot; data-origin-height=&quot;1268&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Camera Shake 설정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Jump 구현해보기&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점프 기능을 구현할 때는 애니메이션 상태 머신에서 State Alias를 활용하면 편리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;State Ailas는 모든 상태를 직접 선으로 연결하지 않아도, 특정 상태에서 원하는 상태로 전환할 수 있도록 도와주는 기능입니다.&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;즉, Idle, Run, Walk처럼 여러 상태에서 각각 Jump로 일일이 연결하지 않아도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;State Alias를 통해 공통적으로 점프 전환을 처리할 수 있어 상태 머신을 훨씬 깔끔하게 구성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1979&quot; data-origin-height=&quot;847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nyHbR/dJMcafeVcq9/PmkW9ZEEb4M7bJbVumX4c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nyHbR/dJMcafeVcq9/PmkW9ZEEb4M7bJbVumX4c1/img.png&quot; data-alt=&quot;State Alias 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nyHbR/dJMcafeVcq9/PmkW9ZEEb4M7bJbVumX4c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnyHbR%2FdJMcafeVcq9%2FPmkW9ZEEb4M7bJbVumX4c1%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;1979&quot; height=&quot;847&quot; data-origin-width=&quot;1979&quot; data-origin-height=&quot;847&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;State Alias 추가&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;State Ailas의 사용 방법으로는 먼저 상태 머신에 State Alias를 추가한 뒤, 점프 상태로 연결해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 오른쪽 Details 패널에서 이 Alias가 어떤 상태들에서 동작할지를 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &quot;어떤 상태일 때만 해당 전환을 허용할지&quot; 체크해주면, 원하는 상태에서만 점프가 가능하도록 재현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Idle, Walk, Run 상태에서는 Jump로 전환되도록 허용하고, 공격 중이거나 피격 상태에서는 점프가 되지 않도록 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Door 배치 및 상호작용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문배치를 통한 상호작용에 대해 구현해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3_23.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lYW0Z/dJMcajheRpW/dm8DwOLa2YtKEqa0XioPPK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lYW0Z/dJMcajheRpW/dm8DwOLa2YtKEqa0XioPPK/img.gif&quot; data-alt=&quot;문 구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lYW0Z/dJMcajheRpW/dm8DwOLa2YtKEqa0XioPPK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/lYW0Z/dJMcajheRpW/dm8DwOLa2YtKEqa0XioPPK/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;400&quot; height=&quot;187&quot; data-filename=&quot;3_23.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문 구현 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;그래서 이번 구현에서는 이러한 흐름을 게임의 전반적인 규칙을 관리하는 GameMode에서 다루는 것이 적절하다고 판단했습니다.&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;b&gt;1. GameMode에서 레벨 로드와 이벤트 호풀 처리하기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 먼저 GameMode에서 레벨 로드와 이벤트 호출 처리하기&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;889&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uuVSO/dJMcajatvBB/RWdcQSSkvytIknuOpg6PdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uuVSO/dJMcajatvBB/RWdcQSSkvytIknuOpg6PdK/img.png&quot; data-alt=&quot;BP_GameMode Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uuVSO/dJMcajatvBB/RWdcQSSkvytIknuOpg6PdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuuVSO%2FdJMcajatvBB%2FRWdcQSSkvytIknuOpg6PdK%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;1350&quot; height=&quot;889&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;889&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_GameMode Event Graph&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;2. Door 블루프린트에서 GameStart 이벤트 바인드하기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다음으로 Door 블루프린트에서는 GameMode의 GameStart 이벤트에 Bind 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이후 이벤트가 호출되면 문이 닫히도록 Door의 회전값을 설정합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1357&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9EYm4/dJMcabXRl88/DmR9eW6e8WGwbVZe9Q7mf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9EYm4/dJMcabXRl88/DmR9eW6e8WGwbVZe9Q7mf1/img.png&quot; data-alt=&quot;BP_Door의 Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9EYm4/dJMcabXRl88/DmR9eW6e8WGwbVZe9Q7mf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9EYm4%2FdJMcabXRl88%2FDmR9eW6e8WGwbVZe9Q7mf1%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;1357&quot; height=&quot;904&quot; data-origin-width=&quot;1357&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Door의 Event Graph&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;3. BP_GameStartActor를 통해 트리거 조건 만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 마지막으로 BP_GameStartActor를 생성하여, 플레이어가 특정 구역에 들어왔는지를 Overlap으로 감지하도록 구성합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 해당 엑터와 플레이어가 Overlap 되면 BP_GameStartActor가 GameMode 블루 프린트의 GameStart 이벤트를 호출하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이 호출을 받은 Door 블루프린트는 회전값을 0으로 변경하여 문이 닫히도록 구현합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;895&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc5ouT/dJMcaiimQXt/Do6XlgPeokz5jKlnPPCfg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc5ouT/dJMcaiimQXt/Do6XlgPeokz5jKlnPPCfg1/img.png&quot; data-alt=&quot;BP_GameStarter&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc5ouT/dJMcaiimQXt/Do6XlgPeokz5jKlnPPCfg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc5ouT%2FdJMcaiimQXt%2FDo6XlgPeokz5jKlnPPCfg1%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;1343&quot; height=&quot;895&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;895&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_GameStarter&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;UI 추가하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 게임의 진행 상태를 플레이어에게 직관적으로 전달하기 위해 UI를 구성해보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언리얼 엔진에서는 User Interface의 Widget Blueprint를 생성한 뒤, 해당 에디터 공간에서 버튼, 텍스트, 이미지와 같은 UI요소를 배치하며 화면을 구성할 수 있습니다.&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;이번에는 Main Widget을 중심으로 게임의 상태를 관리하도록 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어가 실패했을 때는 Game Over UI를 띄워 현재 게임이 종료되었음을 알리고, 이 화면에서는 Quit Game 버튼을 통해&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;1090&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7euUM/dJMcagSpFed/tRZWaIcLLcFBNpiWsSsE01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7euUM/dJMcagSpFed/tRZWaIcLLcFBNpiWsSsE01/img.png&quot; data-alt=&quot;MainUI_Widget&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7euUM/dJMcagSpFed/tRZWaIcLLcFBNpiWsSsE01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7euUM%2FdJMcagSpFed%2FtRZWaIcLLcFBNpiWsSsE01%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;2543&quot; height=&quot;1090&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;1090&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MainUI_Widget&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;반대로 스테이지를 클리어 했을 때는 Stage Clear UI를 출력하여 완료 상태를 보여주고, 이 화면에서는 Reset Game 버튼을 통해 게임을 다시 시작할 수 있도록 구성했습니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt; USER CREATED :&amp;nbsp;&lt;/b&gt;사용자가 직접 만든 위젯 영역&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 영역에서 자신이 만든 Widget Blueprint를 재사용할 수 있게 모아둔 항목입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 항목을 이용하여 제가 만든 UI 3가지를 Main Ui Widget에 넣고 ZOrder를 통해 우선순위를 조절하여 화면에 그릴 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCK1mk/dJMcab4CClc/ytONUerrVPclENAClIAKjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCK1mk/dJMcab4CClc/ytONUerrVPclENAClIAKjk/img.png&quot; data-alt=&quot;Stage Clear UI Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCK1mk/dJMcab4CClc/ytONUerrVPclENAClIAKjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCK1mk%2FdJMcab4CClc%2FytONUerrVPclENAClIAKjk%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;1640&quot; height=&quot;1157&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1157&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Stage Clear UI Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1839&quot; data-origin-height=&quot;1048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjFScO/dJMcaciaJbK/b6BOZlAxLKYVQyf5ZKy0h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjFScO/dJMcaciaJbK/b6BOZlAxLKYVQyf5ZKy0h1/img.png&quot; data-alt=&quot;KillCount Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjFScO/dJMcaciaJbK/b6BOZlAxLKYVQyf5ZKy0h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjFScO%2FdJMcaciaJbK%2Fb6BOZlAxLKYVQyf5ZKy0h1%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;1839&quot; height=&quot;1048&quot; data-origin-width=&quot;1839&quot; data-origin-height=&quot;1048&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;KillCount Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;1184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w41zx/dJMcagY9FJs/GUa3wPFtmQmtXbYjdhvS3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w41zx/dJMcagY9FJs/GUa3wPFtmQmtXbYjdhvS3K/img.png&quot; data-alt=&quot;GameOver Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w41zx/dJMcagY9FJs/GUa3wPFtmQmtXbYjdhvS3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw41zx%2FdJMcagY9FJs%2FGUa3wPFtmQmtXbYjdhvS3K%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;1387&quot; height=&quot;1184&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;1184&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GameOver Event Graph&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 구조는 &lt;b&gt;몬스터의 죽음 -&amp;gt; GameMode 판정 -&amp;gt; Player Controller 전달 -&amp;gt; UI 업데이트 순서&lt;/b&gt;로 이루어 집니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;몬스터의 죽음&amp;nbsp; &lt;br /&gt;&lt;/b&gt;- 우선 BP_Bear가 사망 상태에 들어가면, 자신의 죽음 상태를 Game Mode에 알리게 됩니다.&lt;br /&gt;&amp;nbsp; GameMode는 이 알림을 받은 뒤 현재 처치 수를 반영하여 &lt;b&gt;킬 수 UI를 업데이트하는 이벤트를 호출&lt;/b&gt;하고,&amp;nbsp;&lt;br /&gt;&amp;nbsp; &lt;b&gt;동시에 스테이지 클리어 조건이 충족되었는지 검사합니다&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;GameMode 판정&lt;br /&gt;&lt;/b&gt;- 이후 처치해야 할 목표 수를 모두 만족했다면, GameMode는 On Stage Clear 이벤트를 호출하여 스테이지&amp;nbsp;&lt;br /&gt;&amp;nbsp; 클리어 상태가 되었음을 전달합니다.&lt;br /&gt;&amp;nbsp; &lt;b&gt;하지만 실제로 화면에 UI를 출력하는 역할은 GameMode가 아니라 PlayerController가 담당합니다&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;PlayerController 전달&lt;br /&gt;&lt;/b&gt;- PlayerController에서는 미리 바인딩된 이벤트를 통해 이 신호를 전달받고,&amp;nbsp;&lt;br /&gt;&amp;nbsp; 화면에 표시할 UI 클래스(위젯)를 생성하거나 활성화한 뒤, 해당 UI 내부의 Custom Event를 호출하여 필요한&amp;nbsp;&lt;br /&gt;&amp;nbsp; 내용을 갱신합니다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;UI 업데이트&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;- 마지막으로 각 UI 위젯은 자신의 EventGraph에서 이 커스텀 이벤트를 받아 Stage Clear 문구를 띄우거나,&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;처치 수를 갱신하는 방식으로 최종 화면을 구성하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3_23_LAST.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FOgYm/dJMcab4CDoG/KNRog72x14okUKJQtDMV5k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FOgYm/dJMcab4CDoG/KNRog72x14okUKJQtDMV5k/img.gif&quot; data-alt=&quot;구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FOgYm/dJMcab4CDoG/KNRog72x14okUKJQtDMV5k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/FOgYm/dJMcab4CDoG/KNRog72x14okUKJQtDMV5k/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;400&quot; height=&quot;186&quot; data-filename=&quot;3_23_LAST.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NPC 대사 MultiLine 기능&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgsnrf/dJMcaio9Zb1/s9RI8Qc6fuk8YBg7RRaiKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgsnrf/dJMcaio9Zb1/s9RI8Qc6fuk8YBg7RRaiKk/img.png&quot; data-alt=&quot;설정 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgsnrf/dJMcaio9Zb1/s9RI8Qc6fuk8YBg7RRaiKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcgsnrf%2FdJMcaio9Zb1%2Fs9RI8Qc6fuk8YBg7RRaiKk%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;2000&quot; height=&quot;629&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;629&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;해당 Default 값에 shift + Enter로 줄바꿈을 하면서 대사를 작성할 수 있다.&lt;/p&gt;</description>
      <category>Unreal Project/Blueprint</category>
      <category>blueprint</category>
      <category>Unreal</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/94</guid>
      <comments>https://seonhwan2547.tistory.com/94#entry94comment</comments>
      <pubDate>Mon, 23 Mar 2026 12:34:40 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 6 (AI Perception, UI , Billboard , Data Table)</title>
      <link>https://seonhwan2547.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AI Perception&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Perception은 AI가 주변 환경을 감지하고 상황을 인식하는 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어처럼 입력을 받는 것이 아니라, 시야,소리,피해 등의 정보를 기반으로 행동을 결정하기 위한 &lt;b&gt;감각 시스템&lt;/b&gt; 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1841&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQILJQ/dJMcacJdwe7/am7Zk50OEhGqyyNucFQphK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQILJQ/dJMcacJdwe7/am7Zk50OEhGqyyNucFQphK/img.png&quot; data-alt=&quot;BP_Bear에 AI Perception Component 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQILJQ/dJMcacJdwe7/am7Zk50OEhGqyyNucFQphK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQILJQ%2FdJMcacJdwe7%2Fam7Zk50OEhGqyyNucFQphK%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;1841&quot; height=&quot;946&quot; data-origin-width=&quot;1841&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear에 AI Perception Component 추가하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Perception Component를 추가하는 방법은 일반 Component 추가하는 방법과 같다.&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;대신 AI Percption이 인식하는 물체들은 AI Perception StimuliSource를 통해 감지될 속성을 고를 수 있다.&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2549&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSjArJ/dJMcaivQfrv/izy5asj5ot1rFq4soXfA5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSjArJ/dJMcaivQfrv/izy5asj5ot1rFq4soXfA5K/img.png&quot; data-alt=&quot;BP_Player에 AI Perception StimuliSource를 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSjArJ/dJMcaivQfrv/izy5asj5ot1rFq4soXfA5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSjArJ%2FdJMcaivQfrv%2Fizy5asj5ot1rFq4soXfA5K%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;2549&quot; height=&quot;900&quot; data-origin-width=&quot;2549&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Player에 AI Perception StimuliSource를 추가&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;그리고 Sight(시야)에 의해 체크 받도록 다음과 같이 설정해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 BP_Bear에서는 Detection by Affiliation에서 Neutrals로 설정해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐하면 Blueprint에서는 Neutrals만 가능하기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DOXJs/dJMcagdLXyW/z5wcOlbARpTY0IB7AkHvPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DOXJs/dJMcagdLXyW/z5wcOlbARpTY0IB7AkHvPk/img.png&quot; data-alt=&quot;Unreal Engine 공식 문서 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DOXJs/dJMcagdLXyW/z5wcOlbARpTY0IB7AkHvPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDOXJs%2FdJMcagdLXyW%2Fz5wcOlbARpTY0IB7AkHvPk%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;945&quot; height=&quot;384&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Unreal Engine 공식 문서 설명&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1972&quot; data-origin-height=&quot;1125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT4qmE/dJMcacCrg30/qU32BHkZqtlAwEUeAdv850/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT4qmE/dJMcacCrg30/qU32BHkZqtlAwEUeAdv850/img.png&quot; data-alt=&quot;BP_Bear의 AI Perception 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT4qmE/dJMcacCrg30/qU32BHkZqtlAwEUeAdv850/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT4qmE%2FdJMcacCrg30%2FqU32BHkZqtlAwEUeAdv850%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;1972&quot; height=&quot;1125&quot; data-origin-width=&quot;1972&quot; data-origin-height=&quot;1125&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear의 AI Perception 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;911&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCXW5m/dJMcabKjOaP/00MX5rEw5LZ9YbOVh8uLkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCXW5m/dJMcabKjOaP/00MX5rEw5LZ9YbOVh8uLkK/img.png&quot; data-alt=&quot;AI를 각각의 데이터로 분해해서 사용하게 해주는 노드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCXW5m/dJMcabKjOaP/00MX5rEw5LZ9YbOVh8uLkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCXW5m%2FdJMcabKjOaP%2F00MX5rEw5LZ9YbOVh8uLkK%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;1027&quot; height=&quot;911&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;911&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AI를 각각의 데이터로 분해해서 사용하게 해주는 노드&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;Break AIStimulus는 AI가 감지한 정보(AIStimulus 구조체)를 각각의 데이터로 분해해서 사용할 수 있게 해주는 노드이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, AI가 감지한 결과를 꺼내서 분석하는 노드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NvS3G/dJMcajhcMo6/prmvkuR5V2mbkGGlK2B580/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NvS3G/dJMcajhcMo6/prmvkuR5V2mbkGGlK2B580/img.png&quot; data-alt=&quot;AI Perception을 Debugging 하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NvS3G/dJMcajhcMo6/prmvkuR5V2mbkGGlK2B580/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNvS3G%2FdJMcajhcMo6%2FprmvkuR5V2mbkGGlK2B580%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;1371&quot; height=&quot;758&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AI Perception을 Debugging 하는 모습&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;해당 Debugging방법으로는 실행중 어퍼스토리피 키 &quot;&amp;nbsp;&lt;u&gt; '&lt;/u&gt; &quot; 를 입력해주고 Number 키 4번을 눌러주면 해당 정보를 실시간으로 디버깅 할 수 있다.&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;다음 디버깅 하는 단축키는 Project Settings의 GamePlay Debugger 에 나와있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oC3l2/dJMcadnLsWO/U3KNAXrqYhtvkM4ILo33Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oC3l2/dJMcadnLsWO/U3KNAXrqYhtvkM4ILo33Fk/img.png&quot; data-alt=&quot;Project Setting Game Debugger&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oC3l2/dJMcadnLsWO/U3KNAXrqYhtvkM4ILo33Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoC3l2%2FdJMcadnLsWO%2FU3KNAXrqYhtvkM4ILo33Fk%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;1640&quot; height=&quot;908&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Project Setting Game Debugger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HP UI 제작해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Widget Blueprint란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Widget Blueprint는 게임 화면에 표시되는 UI를 제작하기 위한 비주얼 스크립트 기반 UI 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, 플레이어에게 보여지는 모든 UI를 만드는 도구이다.&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;다음은 Widget Blueprint를 추가하는 방법이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1738&quot; data-origin-height=&quot;1297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rvm2d/dJMcah4OA3D/46fdlkB6cTyP8Rc0gbxiRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rvm2d/dJMcah4OA3D/46fdlkB6cTyP8Rc0gbxiRk/img.png&quot; data-alt=&quot;Widget Blueprint 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rvm2d/dJMcah4OA3D/46fdlkB6cTyP8Rc0gbxiRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frvm2d%2FdJMcah4OA3D%2F46fdlkB6cTyP8Rc0gbxiRk%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;1738&quot; height=&quot;1297&quot; data-origin-width=&quot;1738&quot; data-origin-height=&quot;1297&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Widget Blueprint 추가하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2522&quot; data-origin-height=&quot;1258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uWpWu/dJMcaaSaFja/aYhKP2gAxqGBICUxUj6ia1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uWpWu/dJMcaaSaFja/aYhKP2gAxqGBICUxUj6ia1/img.png&quot; data-alt=&quot;Widget Blueprint Desginer Editor 창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uWpWu/dJMcaaSaFja/aYhKP2gAxqGBICUxUj6ia1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuWpWu%2FdJMcaaSaFja%2FaYhKP2gAxqGBICUxUj6ia1%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;2522&quot; height=&quot;1258&quot; data-origin-width=&quot;2522&quot; data-origin-height=&quot;1258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Widget Blueprint Desginer Editor 창&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;상단 위의 Designer을 선택하면 해당 UI의 design요소를 건들 수 있다.&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;그 옆에 있는 Graph를 선택한다면, 해당 UI의 로직을 설정할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2507&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7XoEj/dJMcai3EKBB/gVpldlqF2JiifUnCPOIfbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7XoEj/dJMcai3EKBB/gVpldlqF2JiifUnCPOIfbK/img.png&quot; data-alt=&quot;Widget Blueprint Graph Editor 창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7XoEj/dJMcai3EKBB/gVpldlqF2JiifUnCPOIfbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7XoEj%2FdJMcai3EKBB%2FgVpldlqF2JiifUnCPOIfbK%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;2507&quot; height=&quot;1254&quot; data-origin-width=&quot;2507&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Widget Blueprint Graph Editor 창&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;HP_Bar의 디자인 요소는 간단히 빨간색 네모칸으로 채운다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monster의 위에 HP Bar를 설치하고 화면에 나타내보기&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2532&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAi5V2/dJMcabXPioG/6Zsr6XWoZnxc5pMe6YjEsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAi5V2/dJMcabXPioG/6Zsr6XWoZnxc5pMe6YjEsK/img.png&quot; data-alt=&quot;UI Widget을 BP_Bear에 Widget을 Component로 추가해주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAi5V2/dJMcabXPioG/6Zsr6XWoZnxc5pMe6YjEsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAi5V2%2FdJMcabXPioG%2F6Zsr6XWoZnxc5pMe6YjEsK%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;2532&quot; height=&quot;810&quot; data-origin-width=&quot;2532&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UI Widget을 BP_Bear에 Widget을 Component로 추가해주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 한가지 문제점이 발생한다. 바로 UI의 방향이 카메라의 방향과 연동되어 바뀌지 않으므로,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐릭터가 몬스터 뒤를 바라보면 HP_Bar가 안 보이는 현상이 발생한다.&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;그래서 엔진에서 제공하는 Screen 방식을 사용한다면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2541&quot; data-origin-height=&quot;1062&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Awujp/dJMb99Telvx/viF0Lz4ftL8vUxFAlE6Ho0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Awujp/dJMb99Telvx/viF0Lz4ftL8vUxFAlE6Ho0/img.png&quot; data-alt=&quot;Screen 옵션&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Awujp/dJMb99Telvx/viF0Lz4ftL8vUxFAlE6Ho0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAwujp%2FdJMb99Telvx%2FviF0Lz4ftL8vUxFAlE6Ho0%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;2541&quot; height=&quot;1062&quot; data-origin-width=&quot;2541&quot; data-origin-height=&quot;1062&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Screen 옵션&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;카메라의 회전에 따라 계속 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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이러한 부분을 해결하기 위해 Billboard 기법을 자체적으로 기능을 넣어 해결해보려고 한다.&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;우선, Billboard기법은 카메라의 회전에 따라 물체의 Forward vector가 카메라를 바라보도록 만드는 방법이다.&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;그러므로 일단 Custom Component로 BP_Billboard라는 Scene Component를 만들어 보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Scene Component로 만든 이유는 Transform이 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;1019&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IMHPn/dJMcaa5GEV0/CEoZTuuyCenb7eCLgl149K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IMHPn/dJMcaa5GEV0/CEoZTuuyCenb7eCLgl149K/img.png&quot; data-alt=&quot;BP_Billboard의 Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IMHPn/dJMcaa5GEV0/CEoZTuuyCenb7eCLgl149K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIMHPn%2FdJMcaa5GEV0%2FCEoZTuuyCenb7eCLgl149K%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;1634&quot; height=&quot;1019&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;1019&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Billboard의 Blueprint&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;해당 Blueprint에서는 Billboard 로직을 구현해볼려고 한다.&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;카메라의 회전 방향을 얻기 위해서는 Player Controller를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Player Controller는 Control Rotation을 통해 카메라의 회전 정보를 관리하기 때문이다.&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;해당 Rotation을 매 Tick마다 해당 Component의 회전으로 설정한다.&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;여기까지 진행한다면, 카메라와 같은 방향의 foward vector를 가지게 되지만, 문제가 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 이러면 카메라가 여전히 물체를 뒤에서 바라볼 때 물체의 뒷면을 보게 되므로 Culling에 의해 안보이게 된다.&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;따라서 이제 이 widget에서&amp;nbsp; z축각도를 180도 회전해주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2538&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IpJuh/dJMcaibA2YR/HJf2jHJl8jyGqMX7gMyvoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IpJuh/dJMcaibA2YR/HJf2jHJl8jyGqMX7gMyvoK/img.png&quot; data-alt=&quot;hp bar widget Detail 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IpJuh/dJMcaibA2YR/HJf2jHJl8jyGqMX7gMyvoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIpJuh%2FdJMcaibA2YR%2FHJf2jHJl8jyGqMX7gMyvoK%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;2538&quot; height=&quot;710&quot; data-origin-width=&quot;2538&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;hp bar widget Detail 설정&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;해당 HP_Bar는 BP_Billboard을 Root로 두면서 하위 자신에서는 z축 으로 180도 회전하면 빌보드 방식이 완성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260320_123655.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duKSZd/dJMb996MjWr/YvB2pdjARWoHYmYcf45EG1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duKSZd/dJMb996MjWr/YvB2pdjARWoHYmYcf45EG1/img.gif&quot; data-alt=&quot;구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duKSZd/dJMb996MjWr/YvB2pdjARWoHYmYcf45EG1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/duKSZd/dJMb996MjWr/YvB2pdjARWoHYmYcf45EG1/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;400&quot; height=&quot;189&quot; data-filename=&quot;KakaoTalk_Recording_20260320_123655.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HP 변경 이벤트 추가 및 HP Bar에 퍼센트 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HP가 감소할 때 UI에 이를 반영하기 위해서는 데이터(HP) -&amp;gt; 이벤트 -&amp;gt; UI 갱신 흐름으로 여결해주는 구조가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 몬스터가 데미지를 받으면 HP Controller의&amp;nbsp; Receive Damage Custom Event를 호출하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPie0z/dJMcadg2GzF/X5jJo4UOcTQAnNDvV2XIv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPie0z/dJMcadg2GzF/X5jJo4UOcTQAnNDvV2XIv1/img.png&quot; data-alt=&quot;BP_Bear에서 데미지를 받았을때 Reveive Damage Custom Event 호출&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPie0z/dJMcadg2GzF/X5jJo4UOcTQAnNDvV2XIv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPie0z%2FdJMcadg2GzF%2FX5jJo4UOcTQAnNDvV2XIv1%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;1186&quot; height=&quot;453&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear에서 데미지를 받았을때 Reveive Damage Custom Event 호출&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;2. 호출된 이벤트는 HP_Controller에서 다시 이벤트 On Hp Changed 델리게이트 이벤트 (함수포인터) 를 Call한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1563&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rdSST/dJMcafza4m9/bHTckqRaOU4sTKUJWvXkBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rdSST/dJMcafza4m9/bHTckqRaOU4sTKUJWvXkBk/img.png&quot; data-alt=&quot;HP_Controller의 ReceiveDamage&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rdSST/dJMcafza4m9/bHTckqRaOU4sTKUJWvXkBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrdSST%2FdJMcafza4m9%2FbHTckqRaOU4sTKUJWvXkBk%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;1563&quot; height=&quot;657&quot; data-origin-width=&quot;1563&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HP_Controller의 ReceiveDamage&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;3. BP_Bear에서 미리 Bind된 Event On Hp Changed가 실행된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yoNoK/dJMcabcq7JL/x4PV5Dw3zBRbepszD6ibKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yoNoK/dJMcabcq7JL/x4PV5Dw3zBRbepszD6ibKk/img.png&quot; data-alt=&quot;BP_Bear에서 On Hp Changed Event에 Bind된 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yoNoK/dJMcabcq7JL/x4PV5Dw3zBRbepszD6ibKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyoNoK%2FdJMcabcq7JL%2Fx4PV5Dw3zBRbepszD6ibKk%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;995&quot; height=&quot;685&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear에서 On Hp Changed Event에 Bind된 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 해당 이벤트가 실행되면 우리가 만든 UI WBP_HP Bar의&amp;nbsp; hp 퍼센트를 조절하기 위해 Update Hp Percent Custom Event를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xJwhb/dJMcadadnMp/e6V5cjgD5Xw1G5MpovUur0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xJwhb/dJMcadadnMp/e6V5cjgD5Xw1G5MpovUur0/img.png&quot; data-alt=&quot;WBP_HPBar의 이벤트 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xJwhb/dJMcadadnMp/e6V5cjgD5Xw1G5MpovUur0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxJwhb%2FdJMcadadnMp%2Fe6V5cjgD5Xw1G5MpovUur0%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;1904&quot; height=&quot;881&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;WBP_HPBar의 이벤트 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 호출받은 해당 Custom Event는 다시 percent를 세팅하여 퍼센트 만큼 보이도록 설정하고 죽었을 경우 보이지 않도록 Collapsed 설정을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몬스터 데이터 도입 ( CSV / 데이터 테이블 )&lt;/h3&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;Data Table을 활용하여 데이터를 외부에서 관리하는 방식을 적용하였다.&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. 우선 Data Table 사용하기 위해 몬스터의 능력치 정보를 담은 CSV 형식의 파일을 생성한다.&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;예를 들어 Attack, Defense, WalkSpeed, ChaseSpeed, MaxHp등을 컬럼으로 구성하여 각 몬스터의 데이터를 정리한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RE61y/dJMcagkwesc/jZtnBq68tIEeQDeigdFoAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RE61y/dJMcagkwesc/jZtnBq68tIEeQDeigdFoAk/img.png&quot; data-alt=&quot;MonsterData.csv&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RE61y/dJMcagkwesc/jZtnBq68tIEeQDeigdFoAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRE61y%2FdJMcagkwesc%2FjZtnBq68tIEeQDeigdFoAk%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;670&quot; height=&quot;335&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MonsterData.csv&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. CSV에 정의한 데이터를 Unreal에서 사용하기 위해 해당 값을 담을 구조체(Struct)를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조체는 CSV의 컬럼과 동일한 변수들로 구성되며, 각 데이터 값을 Unreal Engine에서 읽어오기 위한 기반이 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd1OpW/dJMcaaYUtXU/CPphEF0lmrEcdUCdBCUEL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd1OpW/dJMcaaYUtXU/CPphEF0lmrEcdUCdBCUEL1/img.png&quot; data-alt=&quot;Structure 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd1OpW/dJMcaaYUtXU/CPphEF0lmrEcdUCdBCUEL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd1OpW%2FdJMcaaYUtXU%2FCPphEF0lmrEcdUCdBCUEL1%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;1666&quot; height=&quot;748&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Structure 만들기&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEo4gO/dJMcac3tIYw/NwNwt3m3WYiQ5f75scwm4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEo4gO/dJMcac3tIYw/NwNwt3m3WYiQ5f75scwm4K/img.png&quot; data-alt=&quot;Structure에 미리 변수 값과 자료형 타입 지정해주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEo4gO/dJMcac3tIYw/NwNwt3m3WYiQ5f75scwm4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEo4gO%2FdJMcac3tIYw%2FNwNwt3m3WYiQ5f75scwm4K%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;1420&quot; height=&quot;485&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Structure에 미리 변수 값과 자료형 타입 지정해주기&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;3. Data Table 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1390&quot; data-origin-height=&quot;1158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z94n0/dJMcaady6jo/xTUkO0vpyla8UsThOqrnrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z94n0/dJMcaady6jo/xTUkO0vpyla8UsThOqrnrK/img.png&quot; data-alt=&quot;Data Table 생성하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z94n0/dJMcaady6jo/xTUkO0vpyla8UsThOqrnrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz94n0%2FdJMcaady6jo%2FxTUkO0vpyla8UsThOqrnrK%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;1390&quot; height=&quot;1158&quot; data-origin-width=&quot;1390&quot; data-origin-height=&quot;1158&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Data Table 생성하기&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;준비한 CSV 파일을 Unreal Engine 에디터에 Drag and Drop하면 Data Table로 변환할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 앞에서 생성한 구조체를 지정하면 CSV 데이터가 해당 구조체 형태로 매핑되어 Data Table이 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. BP_Bear Blueprint에&amp;nbsp; BP_MonsterData(Actor Component) 추가 해주기&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;1006&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRW0W2/dJMcabjfJBJ/wP7HuT2mFGe7lB596naimk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRW0W2/dJMcabjfJBJ/wP7HuT2mFGe7lB596naimk/img.png&quot; data-alt=&quot;BP_MonsterData GetCurrentLevel 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRW0W2/dJMcabjfJBJ/wP7HuT2mFGe7lB596naimk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRW0W2%2FdJMcabjfJBJ%2FwP7HuT2mFGe7lB596naimk%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;1974&quot; height=&quot;1006&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;1006&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_MonsterData GetCurrentLevel 함수&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;해당 함수의 변수를 Level Data Category를 만드는 방법은 변수를 추가하고 Default에 있던 부분을 직접 지우고 Level Data로 해당 칸에 타이핑 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2532&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cev96B/dJMcafFV8ou/oCxjIyOP47Bb4NJE3P7lgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cev96B/dJMcafFV8ou/oCxjIyOP47Bb4NJE3P7lgK/img.png&quot; data-alt=&quot;변수 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cev96B/dJMcafFV8ou/oCxjIyOP47Bb4NJE3P7lgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcev96B%2FdJMcafFV8ou%2FoCxjIyOP47Bb4NJE3P7lgK%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;2532&quot; height=&quot;850&quot; data-origin-width=&quot;2532&quot; data-origin-height=&quot;850&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;여기서 Pure 의 check의미는 실행핀이 없는 함수를 만들 기 위해서이다.&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;다음으로 Component를 추가해준다 그래야&amp;nbsp; Monster Data를&amp;nbsp; BP_Bear에 연결시킬 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Get Current Level Data는 Pure이므로 하얀색 실행핀이 없음을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;601&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldP3r/dJMcafFV7Zz/qa6MDgf2gwaZ07Huho5Y51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldP3r/dJMcafFV7Zz/qa6MDgf2gwaZ07Huho5Y51/img.png&quot; data-alt=&quot;BP_Bear의 Begin Play에서 해당 Level Data 연결시켜 각 능력치를 Data Asset 기준으로 초기화 시켜주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldP3r/dJMcafFV7Zz/qa6MDgf2gwaZ07Huho5Y51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FldP3r%2FdJMcafFV7Zz%2Fqa6MDgf2gwaZ07Huho5Y51%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;1027&quot; height=&quot;601&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;601&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear의 Begin Play에서 해당 Level Data 연결시켜 각 능력치를 Data Asset 기준으로 초기화 시켜주기&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;마지막 작업으로 MonsterData의 현재 Level 및 Data 적용 시켜주기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1075&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xSGAB/dJMcai3Fhc3/jChy899SbRZb8Rhssf06C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xSGAB/dJMcai3Fhc3/jChy899SbRZb8Rhssf06C0/img.png&quot; data-alt=&quot;MonsterData Blueprint 변수 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xSGAB/dJMcai3Fhc3/jChy899SbRZb8Rhssf06C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxSGAB%2FdJMcai3Fhc3%2FjChy899SbRZb8Rhssf06C0%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;2536&quot; height=&quot;1075&quot; data-origin-width=&quot;2536&quot; data-origin-height=&quot;1075&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MonsterData Blueprint 변수 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260320_164857.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9zquG/dJMcadVBnhS/As32JnFr3503IvmR8BjUBK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9zquG/dJMcadVBnhS/As32JnFr3503IvmR8BjUBK/img.gif&quot; data-alt=&quot;구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9zquG/dJMcadVBnhS/As32JnFr3503IvmR8BjUBK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b9zquG/dJMcadVBnhS/As32JnFr3503IvmR8BjUBK/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;400&quot; height=&quot;185&quot; data-filename=&quot;KakaoTalk_Recording_20260320_164857.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;185&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;</description>
      <category>Unreal Project/Blueprint</category>
      <category>blueprint</category>
      <category>Unreal Engine</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/93</guid>
      <comments>https://seonhwan2547.tistory.com/93#entry93comment</comments>
      <pubDate>Fri, 20 Mar 2026 10:08:41 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 5 ( Pawn Sensing 기반 몬스터 탐지 Behavior Tree, Debug 명령어)</title>
      <link>https://seonhwan2547.tistory.com/92</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;1166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sf6aM/dJMcaf6XMNu/WJSGCq09PNc0ehBR6oPksk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sf6aM/dJMcaf6XMNu/WJSGCq09PNc0ehBR6oPksk/img.png&quot; data-alt=&quot;Pawn Sensing Component&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sf6aM/dJMcaf6XMNu/WJSGCq09PNc0ehBR6oPksk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsf6aM%2FdJMcaf6XMNu%2FWJSGCq09PNc0ehBR6oPksk%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;2543&quot; height=&quot;1166&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;1166&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Pawn Sensing Component&lt;/figcaption&gt;
&lt;/figure&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;다음의 빨간색 박스는 Pawn Sensing의 옵션 값을 의미하며,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 값을 조정함으로써 AI가 플레이어를 인식하는 범위(시야,청각)등을 상황에 맞게 설정할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Pawn Sensing이란?&lt;/b&gt;&amp;nbsp;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pawn Sensing은 Unreal Engine에서 AI가 주변의 플레이어(Pawn)을 감지할 수 있도록 해주는 컴포넌트이다.&lt;/li&gt;
&lt;li&gt;Pawn Sensing Component는 두 가지 감지 기능을 제공한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sight ( 시야 감지 )&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일정 거리 안에 있는 Pawn을 감지&lt;/li&gt;
&lt;li&gt;시야각(Fov)안에 들어와야 감지됨&lt;/li&gt;
&lt;li&gt;벽 등에 가려지면 감지 불가&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hearing ( 소리 감지 )
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pawn이 발생시킨 Noise 감지&lt;/li&gt;
&lt;li&gt;거리 기반으로 감지 여부 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Pawn Sensing을 이용하여 Monster가 Player 감지해보기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pawn Sensing을 BP_Bear의 Component로 추가하기&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bV4h4t/dJMcafsmm9P/jcnNWeQkC5KJicVE0wKTL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV4h4t/dJMcafsmm9P/jcnNWeQkC5KJicVE0wKTL1/img.png&quot; data-alt=&quot;BP_Bear에 Pawn Sensing Component 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV4h4t/dJMcafsmm9P/jcnNWeQkC5KJicVE0wKTL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbV4h4t%2FdJMcafsmm9P%2FjcnNWeQkC5KJicVE0wKTL1%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;1348&quot; height=&quot;909&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear에 Pawn Sensing Component 추가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 OnSeePawn을 Event를 추가해준다.&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;해당 이벤트는 Pawn Sensing Component가 일정 주기마다 주변을 검사하여, 시야 범위 내에 Pawn이 감지되었을 때 엔진에 의해 자동으로 호출된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시야 감지 로직 관련&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1259&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg4SIq/dJMcaiijXH5/K5rBKjHOmer3jDE6bK58L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg4SIq/dJMcaiijXH5/K5rBKjHOmer3jDE6bK58L0/img.png&quot; data-alt=&quot;시야 감지 로직&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg4SIq/dJMcaiijXH5/K5rBKjHOmer3jDE6bK58L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg4SIq%2FdJMcaiijXH5%2FK5rBKjHOmer3jDE6bK58L0%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;1259&quot; height=&quot;585&quot; data-origin-width=&quot;1259&quot; data-origin-height=&quot;585&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 현재 몬스터의 State가 현재 Locomotion State 상태 인지 확인한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Has Tag를 통해 감지된 Pawn이 Player 인지 판별한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 감지된 대상을 Blackboard의 Object 타입 Key에 참조 형태로 저장한다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 이후 AI 상태를 탐지 상태에 맞게 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFSkUF/dJMcahKvyHr/51KMYbM2oxn7JSE0cGgX01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFSkUF/dJMcahKvyHr/51KMYbM2oxn7JSE0cGgX01/img.png&quot; data-alt=&quot;몬스터 상태 변경 이벤트(Custom Event UpdateState)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFSkUF/dJMcahKvyHr/51KMYbM2oxn7JSE0cGgX01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFSkUF%2FdJMcahKvyHr%2F51KMYbM2oxn7JSE0cGgX01%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;1506&quot; height=&quot;705&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;몬스터 상태 변경 이벤트(Custom Event UpdateState)&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;1. 먼저 몬스터의 현재 상태가 Dead 상태인지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Dead 상태가 아니라면, Blackboard의 Enum 타입 Key를 State Key의 기본값(Default)으로 초기화 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이후 해당 State 값을 기준으로 Switch 문을 통해 각 상태별 Max Walk Speed를 설정한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1665&quot; data-origin-height=&quot;1021&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxqAam/dJMcafTrWMF/3kbzlIxSA2854wqDGsQhTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxqAam/dJMcafTrWMF/3kbzlIxSA2854wqDGsQhTK/img.png&quot; data-alt=&quot;BehaviorTree 노드 수정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxqAam/dJMcafTrWMF/3kbzlIxSA2854wqDGsQhTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxqAam%2FdJMcafTrWMF%2F3kbzlIxSA2854wqDGsQhTK%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;1665&quot; height=&quot;1021&quot; data-origin-width=&quot;1665&quot; data-origin-height=&quot;1021&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BehaviorTree 노드 수정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Behavior Tree가 어떻게 수정되었는지 설명해보자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gnbew/dJMcahX1lSS/hqRNWEBiQemMT2ihpKweA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gnbew/dJMcahX1lSS/hqRNWEBiQemMT2ihpKweA0/img.png&quot; data-alt=&quot;Blackboard Decorator 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gnbew/dJMcahX1lSS/hqRNWEBiQemMT2ihpKweA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGnbew%2FdJMcahX1lSS%2FhqRNWEBiQemMT2ihpKweA0%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;1058&quot; height=&quot;761&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blackboard Decorator 추가하기&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;Blackboard Decorator를 추가하여 Blackboard에 저장된 데이터(변수)들을 통해 조건을 체크하여 해당 시퀀스의 실행 여부를 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2520&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5RGNB/dJMcafy9Keh/NPl5dt8n4IgbDZ8fzE8Fwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5RGNB/dJMcafy9Keh/NPl5dt8n4IgbDZ8fzE8Fwk/img.png&quot; data-alt=&quot;Blackboard의 어떤 변수를 사용할 지 및 여러 비교 옵션들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5RGNB/dJMcafy9Keh/NPl5dt8n4IgbDZ8fzE8Fwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5RGNB%2FdJMcafy9Keh%2FNPl5dt8n4IgbDZ8fzE8Fwk%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;2520&quot; height=&quot;775&quot; data-origin-width=&quot;2520&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blackboard의 어떤 변수를 사용할 지 및 여러 비교 옵션들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Blackboard Decorator의 Detail에 대해 설명해 보고자한다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Notify Observer&lt;/b&gt; : Blackboard 값이 변경될 때 Decorator가 다시 평가되도록 하는 옵션이다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;On Value Change&lt;/b&gt; : Blackboard에 저장된 값 자체가 변경될 때마다 Decorator를 재평가하는 방식이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;On Result Change&lt;/b&gt; : Blackboard 값의 변화로 인해 조건의 결과(True/False)가 바뀌었을 때만 Decorator를&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;재평가하는 방식이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Observer Abort&lt;/b&gt; : 조건이 바뀌었을 때, 현재 실행 중인 Behavior를 중단(Abort)할 범위를 결정하는 옵션
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;None&lt;/b&gt; : 아무 것도 중단 안함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Self&lt;/b&gt; : 현재 실행 중인 자기 노드만 중단&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Lower Priority&lt;/b&gt; : 자기보다 우선순위 낮은 노드들을 중단&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Both&lt;/b&gt; : Self의 성격 + Lower Priority 성격 으로 현재 실행중인 노드 중단 + 낮은 우선순위 노드 전부 중단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BlackBoard 의 Tab에서는 Blackboard Key를 설정하고 Key value를 설정해주자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 조건문을 Key Query에서 조정해 주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEg1vl/dJMcabKi5S8/7KlpgVXEIBN6hTSO4pAy8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEg1vl/dJMcabKi5S8/7KlpgVXEIBN6hTSO4pAy8K/img.png&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;557&quot; data-is-animation=&quot;false&quot; width=&quot;413&quot; height=&quot;392&quot; style=&quot;width: 33.5758%; margin-right: 10px;&quot; data-widthpercent=&quot;33.97&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEg1vl/dJMcabKi5S8/7KlpgVXEIBN6hTSO4pAy8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEg1vl%2FdJMcabKi5S8%2F7KlpgVXEIBN6hTSO4pAy8K%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;587&quot; height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ulgP3/dJMcabKi5Uq/OeHgIvCvKYRpZJMcuHQvKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ulgP3/dJMcabKi5Uq/OeHgIvCvKYRpZJMcuHQvKk/img.png&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;372&quot; data-is-animation=&quot;false&quot; width=&quot;414&quot; height=&quot;202&quot; style=&quot;width: 65.2614%;&quot; data-widthpercent=&quot;66.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ulgP3/dJMcabKi5Uq/OeHgIvCvKYRpZJMcuHQvKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FulgP3%2FdJMcabKi5Uq%2FOeHgIvCvKYRpZJMcuHQvKk%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;762&quot; height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;Dead 상태일 시 발생하는 행동트리의&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;Monster의 State가 Dead일 때면 몬스터가 죽은 상태이므로 더 이상 행동트리를 바꿔 줄 필요가 없으므로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Notify Observer는 On Result Change로 그리고 Observer aborts는 None으로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dead 상태에서 다른 행동트리로 옮겨갈 경우가 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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/cxWP7Y/dJMcagSmwbI/Nm8hNkipfDNeDPjdXfyFGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxWP7Y/dJMcagSmwbI/Nm8hNkipfDNeDPjdXfyFGK/img.png&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;541&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.6101%; margin-right: 10px;&quot; data-widthpercent=&quot;32.99&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxWP7Y/dJMcagSmwbI/Nm8hNkipfDNeDPjdXfyFGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxWP7Y%2FdJMcagSmwbI%2FNm8hNkipfDNeDPjdXfyFGK%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;530&quot; height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chDoNK/dJMb996Ly3N/i8dz6fqJ0vDV29q6jgkug0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chDoNK/dJMb996Ly3N/i8dz6fqJ0vDV29q6jgkug0/img.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;384&quot; data-is-animation=&quot;false&quot; style=&quot;width: 66.2271%;&quot; data-widthpercent=&quot;67.01&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chDoNK/dJMb996Ly3N/i8dz6fqJ0vDV29q6jgkug0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchDoNK%2FdJMb996Ly3N%2Fi8dz6fqJ0vDV29q6jgkug0%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;764&quot; height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;State가 Chase일 시 발생하는 행동트리&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;Monster의 상태가 Chase일 시 Attack 상태로 전이될 수 도 있기 때문에 Notify Observer는 On Value Change 혹은 On Result Change 둘 중 하나를 사용해도 문제없다.&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;다만 Observer aborts에서는 Both를 선택하여 해당 상태가 아니라면 다른 상태로 넘어갈 수 있도록 즉시 중단하도록 설정해야 한다.&lt;/p&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/bR9doG/dJMcaflBYtg/t5HtHM3diTYsnQVe6yYiK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR9doG/dJMcaflBYtg/t5HtHM3diTYsnQVe6yYiK0/img.png&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;551&quot; data-is-animation=&quot;false&quot; style=&quot;width: 34.1713%; margin-right: 10px;&quot; data-widthpercent=&quot;34.57&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR9doG/dJMcaflBYtg/t5HtHM3diTYsnQVe6yYiK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR9doG%2FdJMcaflBYtg%2Ft5HtHM3diTYsnQVe6yYiK0%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;606&quot; height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz9UQG/dJMcabjexQC/82ivPcmOJ8PeCANwkMFC4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz9UQG/dJMcabjexQC/82ivPcmOJ8PeCANwkMFC4k/img.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;369&quot; data-is-animation=&quot;false&quot; style=&quot;width: 64.6659%;&quot; data-widthpercent=&quot;65.43&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz9UQG/dJMcabjexQC/82ivPcmOJ8PeCANwkMFC4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcz9UQG%2FdJMcabjexQC%2F82ivPcmOJ8PeCANwkMFC4k%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;768&quot; height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;State가 Attack일 시 발생하는 행동트리&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;Monster의 상태가 Attack에서 Chase, Dead 상태로 전이될 수 도 있기 때문에 Notify Observer는 On Value Change 혹은 On Result Change 둘 중 하나를 사용해도 문제없다.&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;다만 Observer aborts에서는 Both를 선택하여 해당 상태가 아니라면 다른 상태로 넘어갈 수 있도록 즉시 중단하도록 설정해야 한다.&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1617&quot; data-origin-height=&quot;1029&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FF5MP/dJMcacoSVte/ZQyrYPyQXS91Ge5bI72BZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FF5MP/dJMcacoSVte/ZQyrYPyQXS91Ge5bI72BZK/img.png&quot; data-alt=&quot;Set State Task Blue Print&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FF5MP/dJMcacoSVte/ZQyrYPyQXS91Ge5bI72BZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFF5MP%2FdJMcacoSVte%2FZQyrYPyQXS91Ge5bI72BZK%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;1617&quot; height=&quot;1029&quot; data-origin-width=&quot;1617&quot; data-origin-height=&quot;1029&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Set State Task Blue Print&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;여기서는 해당 행동트리가 완료된다면 다음 상태로 전이시켜주기 위해 Blackboard의 Enum 변수 state값과 BP_Bear에 있는 state값을 변경해주기 위해 만든 Task이다.&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;해당 Task가 끝나면 Finish Execute를 해주는 것을 잊지 말자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1519&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KeGF3/dJMcaaxQvWh/DlpfrRKbfJnbfyCPOfIsu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KeGF3/dJMcaaxQvWh/DlpfrRKbfJnbfyCPOfIsu1/img.png&quot; data-alt=&quot;BP_Bear의 Update State(Custom Event)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KeGF3/dJMcaaxQvWh/DlpfrRKbfJnbfyCPOfIsu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKeGF3%2FdJMcaaxQvWh%2FDlpfrRKbfJnbfyCPOfIsu1%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;1519&quot; height=&quot;686&quot; data-origin-width=&quot;1519&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear의 Update State(Custom Event)&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;다음과 같이 BP_Bear에서의 state enum값과 blackboard에서의 enum key값을 통해 접근하여 state값을 바꾸어준다.&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;(Tmi. 구현 중 발생한 이슈들)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2141&quot; data-origin-height=&quot;999&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VCQ9i/dJMcadnK0AQ/ZWqGMUdx9lqCyKdTbDnitK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VCQ9i/dJMcadnK0AQ/ZWqGMUdx9lqCyKdTbDnitK/img.png&quot; data-alt=&quot;게임 실행 도중 Blueprint의 변수값을 바꿀경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VCQ9i/dJMcadnK0AQ/ZWqGMUdx9lqCyKdTbDnitK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVCQ9i%2FdJMcadnK0AQ%2FZWqGMUdx9lqCyKdTbDnitK%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;2141&quot; height=&quot;999&quot; data-origin-width=&quot;2141&quot; data-origin-height=&quot;999&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;게임 실행 도중 Blueprint의 변수값을 바꿀경우&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;Health Power의 값을 게임 실행 도중 바꾸었더니 이벤트 Call 호출은 되지만 Bind 해준 Event가 호출이 안되는 에러가 발생했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chatgpt에 물어보니 다음과 같이 대답이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o4YXt/dJMcag5TNCa/Dy8SD54hyCa36ITb76dQjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o4YXt/dJMcag5TNCa/Dy8SD54hyCa36ITb76dQjK/img.png&quot; data-alt=&quot;오류 발생 원인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o4YXt/dJMcag5TNCa/Dy8SD54hyCa36ITb76dQjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo4YXt%2FdJMcag5TNCa%2FDy8SD54hyCa36ITb76dQjK%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;702&quot; height=&quot;82&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;82&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몬스터의 패턴 복귀 설정해보기 ( 추적-&amp;gt;거리이탈 -&amp;gt; 정찰 복귀 흐름)&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몬스터의 경우 플레이어와 너무 멀어지면 플레이어를 계속 쫓아오는 것이 아닌 일정이상 거리가 차이가 난다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 정찰 페이즈로 넘어가도록 설정해보겠다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;858&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWgS2q/dJMcaiWTLig/RYTuS4huRCCwfD321NHfh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWgS2q/dJMcaiWTLig/RYTuS4huRCCwfD321NHfh1/img.png&quot; data-alt=&quot;BP_Bear의 Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWgS2q/dJMcaiWTLig/RYTuS4huRCCwfD321NHfh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWgS2q%2FdJMcaiWTLig%2FRYTuS4huRCCwfD321NHfh1%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;1317&quot; height=&quot;858&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear의 Event Graph&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;Event Graph에서 Event Tick함수를 활용하여 현재 상태에 따라 각각의 함수를 실행하도록 설정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 Chase 상태일때 플레이어와의 거리가 멀면 다시 Locomotion(정찰)로 넘어가도록 설정해보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1337&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIBzdO/dJMcafy95Za/91c2cFRFfFpgOb8K3GLfcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIBzdO/dJMcafy95Za/91c2cFRFfFpgOb8K3GLfcK/img.png&quot; data-alt=&quot;BP_Bear의 OnChase 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIBzdO/dJMcafy95Za/91c2cFRFfFpgOb8K3GLfcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIBzdO%2FdJMcafy95Za%2F91c2cFRFfFpgOb8K3GLfcK%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;1337&quot; height=&quot;882&quot; data-origin-width=&quot;1337&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear의 OnChase 함수&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;해당 함수 구현을 살펴보면 플레이어의 위치를 Get Location으로 받아오고 해당 몬스터도 마찬가지로 위치를 가져와&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 벡터의 distance를 계산하여 현재 몬스터와 플레이어 사이의 거리를 구하고 현재 감지되는 pawn Sensing의 반지름보다 떨어진 거리가 더 길다면 현재 Chase state에서&amp;nbsp; Locomotion으로 변하도록 설정하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260319_171013.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc9Zf8/dJMcai3Egml/upK07bjXynSYpoFkOBe12K/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc9Zf8/dJMcai3Egml/upK07bjXynSYpoFkOBe12K/img.gif&quot; data-alt=&quot;구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc9Zf8/dJMcai3Egml/upK07bjXynSYpoFkOBe12K/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bc9Zf8/dJMcai3Egml/upK07bjXynSYpoFkOBe12K/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;400&quot; height=&quot;189&quot; data-filename=&quot;KakaoTalk_Recording_20260319_171013.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Debug할 때 알면 좋은 명령어들&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Show Collision&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;655&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bropvb/dJMb99Z1KhB/ge4fqK33IABrRSBx7p8rUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bropvb/dJMb99Z1KhB/ge4fqK33IABrRSBx7p8rUk/img.png&quot; data-alt=&quot;Show Collision을 통해 게임 실행 중에 콜라이더의 상태를 확인할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bropvb/dJMb99Z1KhB/ge4fqK33IABrRSBx7p8rUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbropvb%2FdJMb99Z1KhB%2Fge4fqK33IABrRSBx7p8rUk%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;1392&quot; height=&quot;655&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;655&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Show Collision을 통해 게임 실행 중에 콜라이더의 상태를 확인할 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ShowDebug Collision&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 해당하는 엑터와 충돌되고 있는 정보를 디버깅할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;Stat FPS&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 FPS 정보를 알려준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AcBOt/dJMcah4N6Ud/zgSkTm3WnCuCUQ9AqEg3rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AcBOt/dJMcah4N6Ud/zgSkTm3WnCuCUQ9AqEg3rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AcBOt/dJMcah4N6Ud/zgSkTm3WnCuCUQ9AqEg3rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAcBOt%2FdJMcah4N6Ud%2FzgSkTm3WnCuCUQ9AqEg3rk%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;1380&quot; height=&quot;651&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stat Game
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;게임 로직이 실행 되는 시간 (cpu game thread)을 분석하는 명령어&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;871&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPTZin/dJMcabQ2inU/e8FIFFamMrHBcbSTfipSf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPTZin/dJMcabQ2inU/e8FIFFamMrHBcbSTfipSf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPTZin/dJMcabQ2inU/e8FIFFamMrHBcbSTfipSf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPTZin%2FdJMcabQ2inU%2Fe8FIFFamMrHBcbSTfipSf0%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;1387&quot; height=&quot;871&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;871&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stat sceneRendering
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;화면을 그리는 과정(Rendering)의 세부 비용을 보여주는 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1381&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rgo9g/dJMcaiCCeE7/S2OXcqlHoYzBhNYguztXo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rgo9g/dJMcaiCCeE7/S2OXcqlHoYzBhNYguztXo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rgo9g/dJMcaiCCeE7/S2OXcqlHoYzBhNYguztXo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frgo9g%2FdJMcaiCCeE7%2FS2OXcqlHoYzBhNYguztXo0%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;1381&quot; height=&quot;872&quot; data-origin-width=&quot;1381&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Unreal Project/Blueprint</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/92</guid>
      <comments>https://seonhwan2547.tistory.com/92#entry92comment</comments>
      <pubDate>Thu, 19 Mar 2026 14:03:31 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 4 ( 충돌 Channel 및 이펙트, 피격효과, Behavior Tree )</title>
      <link>https://seonhwan2547.tistory.com/91</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Object Channel 생성 및 Collider 상호작용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 콜리전 채널 추가 및 충돌 처리에 대해 다뤄보고 아이템 박스와 Player Weapon의 충돌을 시켜보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcrY9b/dJMcaiCAu4J/3veruE79TbCyHZHYUxLZT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcrY9b/dJMcaiCAu4J/3veruE79TbCyHZHYUxLZT1/img.png&quot; data-alt=&quot;Collision Channel 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcrY9b/dJMcaiCAu4J/3veruE79TbCyHZHYUxLZT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcrY9b%2FdJMcaiCAu4J%2F3veruE79TbCyHZHYUxLZT1%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;1730&quot; height=&quot;632&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Collision Channel 설정&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;Object Channel : &quot;충돌 대상의 타입&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Trace Channel : &quot;Ray Cast시 사용할 필터 기준 &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;이제 아이템 박스를 만들어보자&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;위에서는 PlayerWeapon 과 Item 채널을 추가해주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2523&quot; data-origin-height=&quot;844&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXRvqR/dJMcad2jD89/Ztsq8sR0bt9S3WhlZCphu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXRvqR/dJMcad2jD89/Ztsq8sR0bt9S3WhlZCphu1/img.png&quot; data-alt=&quot;BP_Box BluePrint Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXRvqR/dJMcad2jD89/Ztsq8sR0bt9S3WhlZCphu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXRvqR%2FdJMcad2jD89%2FZtsq8sR0bt9S3WhlZCphu1%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;2523&quot; height=&quot;844&quot; data-origin-width=&quot;2523&quot; data-origin-height=&quot;844&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Box BluePrint Event Graph&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;다음과 같이 세부 설정을 한다 Object Type은 Item이고 Player Weapon만 충돌 처리를 할 수 있도록 설정하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Event Graph에서는 원래 해당 Actor가 무엇인지 체크해야하지만 현재는 Player Weapon 하나만 검사하므로 그냥 Get Actor를 통해 받아온다 ( 원래 이러면 안됨!)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 박스와 충돌할 PlayerWeapon을 설정해보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2548&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxW8uZ/dJMcagSk2Mz/wtcjZh6wkzdjVoybBEOQV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxW8uZ/dJMcagSk2Mz/wtcjZh6wkzdjVoybBEOQV0/img.png&quot; data-alt=&quot;BP_Weapon의 BluePrint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxW8uZ/dJMcagSk2Mz/wtcjZh6wkzdjVoybBEOQV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxW8uZ%2FdJMcagSk2Mz%2FwtcjZh6wkzdjVoybBEOQV0%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;2548&quot; height=&quot;836&quot; data-origin-width=&quot;2548&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Weapon의 BluePrint&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;다음과 같이 Item만 충돌 검사를 하도록 설정한다.&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;마지막으로 아이템과 충돌했을때 아이템이 터지는 이펙트가 나오도록 EventGraph 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;880&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L2r5X/dJMcagrfAZK/xtSzRWeOHHbnucVjIYXXDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L2r5X/dJMcagrfAZK/xtSzRWeOHHbnucVjIYXXDk/img.png&quot; data-alt=&quot;BP_Box의 Event Graph에서 이펙트 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L2r5X/dJMcagrfAZK/xtSzRWeOHHbnucVjIYXXDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL2r5X%2FdJMcagrfAZK%2FxtSzRWeOHHbnucVjIYXXDk%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;1174&quot; height=&quot;880&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;880&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Box의 Event Graph에서 이펙트 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애니메이션 이펙트 추가해보기&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1837&quot; data-origin-height=&quot;1359&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBU1L4/dJMcaaxOZSM/1WlJNJg0yj8VpfpaKGj0Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBU1L4/dJMcaaxOZSM/1WlJNJg0yj8VpfpaKGj0Q1/img.png&quot; data-alt=&quot;Anim notify에 Trail 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBU1L4/dJMcaaxOZSM/1WlJNJg0yj8VpfpaKGj0Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBU1L4%2FdJMcaaxOZSM%2F1WlJNJg0yj8VpfpaKGj0Q1%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;1837&quot; height=&quot;1359&quot; data-origin-width=&quot;1837&quot; data-origin-height=&quot;1359&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Anim notify에 Trail 추가하기&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;추가하고 이펙트를 출력할 위치를 start와 end 장소 설정하기 ( Effect Start , Effect&amp;nbsp; End )&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1517&quot; data-origin-height=&quot;1298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vxxHs/dJMcaadwm6y/UmM4dTfauqQNuAOxVf0sLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vxxHs/dJMcaadwm6y/UmM4dTfauqQNuAOxVf0sLk/img.png&quot; data-alt=&quot;Effect가 출력될 곳의 부분 설정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vxxHs/dJMcaadwm6y/UmM4dTfauqQNuAOxVf0sLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvxxHs%2FdJMcaadwm6y%2FUmM4dTfauqQNuAOxVf0sLk%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;1517&quot; height=&quot;1298&quot; data-origin-width=&quot;1517&quot; data-origin-height=&quot;1298&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Effect가 출력될 곳의 부분 설정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 몽타주로 돌아와서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2031&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWSLvp/dJMcafy8nKp/kdyofcSARpqgKVL0rGMJl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWSLvp/dJMcafy8nKp/kdyofcSARpqgKVL0rGMJl0/img.png&quot; data-alt=&quot;Trail Detail 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWSLvp/dJMcafy8nKp/kdyofcSARpqgKVL0rGMJl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWSLvp%2FdJMcafy8nKp%2FkdyofcSARpqgKVL0rGMJl0%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;2031&quot; height=&quot;1280&quot; data-origin-width=&quot;2031&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Trail Detail 설정&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;Trail이 나올 위치 설정을 Trail notify를 클릭 후 Detail에서 사용할 trail effect와 소켓 위치 설정해주기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파티클 이펙트 추가해보기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2161&quot; data-origin-height=&quot;1295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duDD89/dJMcacCo6lh/hFPwka8wK2ESnX2fG9crFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duDD89/dJMcacCo6lh/hFPwka8wK2ESnX2fG9crFK/img.png&quot; data-alt=&quot;Add Notify한 후 Play Particle Effect 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duDD89/dJMcacCo6lh/hFPwka8wK2ESnX2fG9crFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduDD89%2FdJMcacCo6lh%2FhFPwka8wK2ESnX2fG9crFK%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;2161&quot; height=&quot;1295&quot; data-origin-width=&quot;2161&quot; data-origin-height=&quot;1295&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Add Notify한 후 Play Particle Effect 추가하기&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2045&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5OWtu/dJMcadVyDYk/hSvlu5JvI2Z2V8AyKMNUnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5OWtu/dJMcadVyDYk/hSvlu5JvI2Z2V8AyKMNUnK/img.png&quot; data-alt=&quot;Particle Effect가 나올 위치 지정 및 이펙트 설정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5OWtu/dJMcadVyDYk/hSvlu5JvI2Z2V8AyKMNUnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5OWtu%2FdJMcadVyDYk%2FhSvlu5JvI2Z2V8AyKMNUnK%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;2045&quot; height=&quot;799&quot; data-origin-width=&quot;2045&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Particle Effect가 나올 위치 지정 및 이펙트 설정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260318_100950.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4SSRI/dJMcac3q020/s8pN0GL54dtC36cNThCMi0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4SSRI/dJMcac3q020/s8pN0GL54dtC36cNThCMi0/img.gif&quot; data-alt=&quot;시연 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4SSRI/dJMcac3q020/s8pN0GL54dtC36cNThCMi0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/4SSRI/dJMcac3q020/s8pN0GL54dtC36cNThCMi0/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;400&quot; height=&quot;183&quot; data-filename=&quot;KakaoTalk_Recording_20260318_100950.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시연 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몬스터 추가 및 피격효과 추가해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 몬스터를 추가해주자&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몬스터는 추가하는 과정은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Character 클래스를 상속받은 Blueprint 생성&lt;/li&gt;
&lt;li&gt;해당 몬스터가 사용할 Animation Blueprint 생성&lt;/li&gt;
&lt;li&gt;해당 몬스터의 상태를 나타낼 Enum 자료형 Enumeration Blueprint 만들기&amp;nbsp;&lt;/li&gt;
&lt;li&gt;PlayerWeapon과 충돌 체크 및 BP_Weapon에서도 Monster와 충돌 체크하기&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 작업까지 마쳤으면, BP_Monster의&amp;nbsp; Animation의 Anim Class를 만들어준 Anmation Blueprint 설정해주기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1823&quot; data-origin-height=&quot;1230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LGEN5/dJMcad2jIgb/wS4ZfxrRHrJMrjSkt3jBXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LGEN5/dJMcad2jIgb/wS4ZfxrRHrJMrjSkt3jBXk/img.png&quot; data-alt=&quot;몬스터를 추가하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LGEN5/dJMcad2jIgb/wS4ZfxrRHrJMrjSkt3jBXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLGEN5%2FdJMcad2jIgb%2FwS4ZfxrRHrJMrjSkt3jBXk%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;1823&quot; height=&quot;1230&quot; data-origin-width=&quot;1823&quot; data-origin-height=&quot;1230&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;몬스터를 추가하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;우선 해당 몬스터의 Material로 들어가 현재 어떻게 노드 구성이 이루어 졌는지 확인해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;927&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lLQQz/dJMcahKuiMv/jfoN3I0EezmJFekwCbwzx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lLQQz/dJMcahKuiMv/jfoN3I0EezmJFekwCbwzx0/img.png&quot; data-alt=&quot;Bear Material&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lLQQz/dJMcahKuiMv/jfoN3I0EezmJFekwCbwzx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlLQQz%2FdJMcahKuiMv%2FjfoN3I0EezmJFekwCbwzx0%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;1544&quot; height=&quot;927&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;927&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Bear Material&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 나와있으며, 해당 노드에 이제 피격효과를 주기 위해서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2377&quot; data-origin-height=&quot;1033&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKlDcw/dJMcaibyQtt/1FVDIcOEc5WSMVk7YAhMXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKlDcw/dJMcaibyQtt/1FVDIcOEc5WSMVk7YAhMXk/img.png&quot; data-alt=&quot;외곽선 효과 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKlDcw/dJMcaibyQtt/1FVDIcOEc5WSMVk7YAhMXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKlDcw%2FdJMcaibyQtt%2F1FVDIcOEc5WSMVk7YAhMXk%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;2377&quot; height=&quot;1033&quot; data-origin-width=&quot;2377&quot; data-origin-height=&quot;1033&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;Fresnel 효과를 통한 즉 외곽선만 빨간색으로 칠해주는 효과를 주어봤다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잠시 효과를 확인하기 위해 &lt;b&gt;HitValue의 Default Value을 1로 설정했으므로 다시 0으로 바꾸고 저장하자&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;그리고 해당 Material을 Instance로 만들어 Parameter만 쉽게 따로 관리할 수 있도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSXNq8/dJMcaaLlFx8/waNtkzDlqcI2IoptWJNmn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSXNq8/dJMcaaLlFx8/waNtkzDlqcI2IoptWJNmn1/img.png&quot; data-alt=&quot;Matreial Instance 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSXNq8/dJMcaaLlFx8/waNtkzDlqcI2IoptWJNmn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSXNq8%2FdJMcaaLlFx8%2FwaNtkzDlqcI2IoptWJNmn1%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;1378&quot; height=&quot;523&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Matreial Instance 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2544&quot; data-origin-height=&quot;1175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C7c2R/dJMcaadwsgf/eNE25XjWgDFa0albAyznX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C7c2R/dJMcaadwsgf/eNE25XjWgDFa0albAyznX1/img.png&quot; data-alt=&quot;Material Instance 에디터 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C7c2R/dJMcaadwsgf/eNE25XjWgDFa0albAyznX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC7c2R%2FdJMcaadwsgf%2FeNE25XjWgDFa0albAyznX1%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;2544&quot; height=&quot;1175&quot; data-origin-width=&quot;2544&quot; data-origin-height=&quot;1175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Material Instance 에디터 화면&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;이제 해당 Material을 다시 적용하기 위해 BP_Bear로 돌아가준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2544&quot; data-origin-height=&quot;1124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9sx6d/dJMcadH1CVg/zCVvRwpSh74TfQWxK1dijk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9sx6d/dJMcadH1CVg/zCVvRwpSh74TfQWxK1dijk/img.png&quot; data-alt=&quot;BP_Bear Event Graph 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9sx6d/dJMcadH1CVg/zCVvRwpSh74TfQWxK1dijk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9sx6d%2FdJMcadH1CVg%2FzCVvRwpSh74TfQWxK1dijk%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;2544&quot; height=&quot;1124&quot; data-origin-width=&quot;2544&quot; data-origin-height=&quot;1124&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear Event Graph 설정&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;Paramet Name은 Material에서 설정한 해당 Parameter Name 으로 그리고 Material은 만들어준 Instance로 교체하자&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;여기서 HitEffect은 Add Timeline을 통해 추가한 Component로 더블 클릭하면 다음과 같은 창이 열린다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ovgPj/dJMcacPVP5h/KIL7R7Bz93sODltDx77EKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ovgPj/dJMcacPVP5h/KIL7R7Bz93sODltDx77EKk/img.png&quot; data-alt=&quot;Timeline Template&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ovgPj/dJMcacPVP5h/KIL7R7Bz93sODltDx77EKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FovgPj%2FdJMcacPVP5h%2FKIL7R7Bz93sODltDx77EKk%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;1890&quot; height=&quot;790&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Timeline Template&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;해당 창에서는 이제 Material Parameter에 설정한 HitValue 값을&amp;nbsp; 1에서 0으로 감소하는 그래프를 만들어 줄 것이다 .&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;해당 component는 tick처럼 작동하여 해당 시간동안 계속해서 업데이트 되어 Value 값을 세팅해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260318_122249.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ecOWLn/dJMcabXM8Rc/Hk2kTaoQ8MTHfJd39wvUmK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ecOWLn/dJMcabXM8Rc/Hk2kTaoQ8MTHfJd39wvUmK/img.gif&quot; data-alt=&quot;구현 영상&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ecOWLn/dJMcabXM8Rc/Hk2kTaoQ8MTHfJd39wvUmK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/ecOWLn/dJMcabXM8Rc/Hk2kTaoQ8MTHfJd39wvUmK/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;400&quot; height=&quot;183&quot; data-filename=&quot;KakaoTalk_Recording_20260318_122249.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몬스터에게 데미지 전달하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몬스터에게 데미지를 전달하기 위해서는 다음과 같은 순서가 필요합니다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BP_Weapon의 Attack Collision의 OnComponentBeginOverLap 이벤트에서 Apply Damage 이벤트를 통해 데미지를 전달&lt;/li&gt;
&lt;li&gt;Apply Damage 이벤트를 받기 위해서는 Event AnyDamage 이벤트를 받아와야 한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;따라서 데미지를 받을 BP_Bear에 Event Any Damage 노드를 추가&amp;nbsp;&lt;/li&gt;
&lt;li&gt;데미지를 받는다면 Monster의 Hp가 깍여야 하므로 몬스터에 Hp Component를 추가 하여 hp를 관리&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Hp를 담당하는 Actor Component ( BP_HpController)를 추가한다&lt;/li&gt;
&lt;li&gt;BP_Controller에서는 데미지를 받을 시 어떤식으로 hp을 깍을 지 계산하고 hp가 0보다 작다면 Dead 이벤트를 Call한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monster Death 이펙트 ( Dissolve 표현해보기 )&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2209&quot; data-origin-height=&quot;1062&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mcdHE/dJMcag5SvSc/WrULf6068feXxW8kcZeIo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mcdHE/dJMcag5SvSc/WrULf6068feXxW8kcZeIo0/img.png&quot; data-alt=&quot;Dissolve Effect를 Material에서 표현하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mcdHE/dJMcag5SvSc/WrULf6068feXxW8kcZeIo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmcdHE%2FdJMcag5SvSc%2FWrULf6068feXxW8kcZeIo0%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;2209&quot; height=&quot;1062&quot; data-origin-width=&quot;2209&quot; data-origin-height=&quot;1062&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dissolve Effect를 Material에서 표현하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Dissolve Effect를 표현하기 위해서는 투명도를 설정하는 기능의 노드를 풀어줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 노드가 바로 Opacity이다.&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;우선 Opacity Mask를 사용하기 위해 왼쪽 Detail에서 Blend Mode를 Masked으로 바꾼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 Opacity Mask 값이 1이면 완전 투명 0이면 불투명으로 바꿔준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2557&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I2WSx/dJMcahcDaw9/zcK6sVLmUkVsofouQCEeIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I2WSx/dJMcahcDaw9/zcK6sVLmUkVsofouQCEeIk/img.png&quot; data-alt=&quot;Material을 조작할 때 편의성을 위해 Parameter화 하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I2WSx/dJMcahcDaw9/zcK6sVLmUkVsofouQCEeIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2WSx%2FdJMcahcDaw9%2FzcK6sVLmUkVsofouQCEeIk%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;2557&quot; height=&quot;1002&quot; data-origin-width=&quot;2557&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Material을 조작할 때 편의성을 위해 Parameter화 하기&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;Matreial을 다룰 때 Conver to Parameter 하여 Material Instance에서 다음과 같이 조절하면서 볼 수 있으니깐 잊지말자!.&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;위와 같이 노드를 설정하고 나서 BP_Bear에서 다음과 같이 Material Parameter 로직 처리를 진행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c93CXT/dJMcafy8NgJ/N8GHPt5zeo2c8g7mItZqc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c93CXT/dJMcafy8NgJ/N8GHPt5zeo2c8g7mItZqc1/img.png&quot; data-alt=&quot;BP_Bear Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c93CXT/dJMcafy8NgJ/N8GHPt5zeo2c8g7mItZqc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc93CXT%2FdJMcafy8NgJ%2FN8GHPt5zeo2c8g7mItZqc1%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;1193&quot; height=&quot;650&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear Blueprint&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;981&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yDSC7/dJMcai3CYnz/aTkxZSvAogPy54aDABLhxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yDSC7/dJMcai3CYnz/aTkxZSvAogPy54aDABLhxK/img.png&quot; data-alt=&quot;Death Effect Timeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yDSC7/dJMcai3CYnz/aTkxZSvAogPy54aDABLhxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyDSC7%2FdJMcai3CYnz%2FaTkxZSvAogPy54aDABLhxK%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;1454&quot; height=&quot;981&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;981&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Death Effect Timeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몬스터 행동트리 만들어보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몬스터 Ai를 만들기 위해서는 3가지가 필요하다&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AIController
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pawn을 조종하는 컨트롤러로 사람이 조종하면 Player Controller 이며 AI가 조종하면 AIController이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;실제 역활로는 Behavior Tree 실행 및 Blackboard 값을 관리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;behavior Tree
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;행동을 트리로 나눠서 관리하는 장소&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Root(시작점) 트리 시작 노드로&amp;nbsp; Blackboard와 연결된다.&lt;/li&gt;
&lt;li&gt;Composite(흐름 제어)로 어떤 행동을 실행할지 결정한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sequence ( 순차 실행 ) : 위에서 아래로 순차적으로 실행하며 다 성공해야 원활하게 움직이며 하나라도 실패하면 중단한다.&lt;/li&gt;
&lt;li&gt;Selector ( 우선 순위 ) : 왼쪽에서 오른쪽으로 조건 체크하면서 가능한 것 하나라도 성공하면 &quot;OK&quot;&lt;/li&gt;
&lt;li&gt;Task ( 실제 행동 ) : 진짜 실행되는 코드&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;black board
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AI가 사용하는 공유 변수 저장소 ( 기억 공간으로 메모장으로 생각해도 좋다 )&lt;/li&gt;
&lt;li&gt;즉, 판단하려면 데이터가 필요한데 이 데이터를 저장하는 곳이 Blackboard 이다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;1201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lNTIQ/dJMcaiWSAx5/mjkiruRKP2IIU5Kp27fcxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lNTIQ/dJMcaiWSAx5/mjkiruRKP2IIU5Kp27fcxK/img.png&quot; data-alt=&quot;Behavior Tree를 만들기 위한 3가지 요소 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lNTIQ/dJMcaiWSAx5/mjkiruRKP2IIU5Kp27fcxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlNTIQ%2FdJMcaiWSAx5%2FmjkiruRKP2IIU5Kp27fcxK%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;1387&quot; height=&quot;1201&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;1201&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Behavior Tree를 만들기 위한 3가지 요소 만들기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 우선 데이터로 사용할 변수들을 blackboard에 만들어 주자&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;742&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QTUFT/dJMcadnJPrx/26DpvdjlMPOC8vIs5JS1pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QTUFT/dJMcadnJPrx/26DpvdjlMPOC8vIs5JS1pK/img.png&quot; data-alt=&quot;BlackBoard에 key값 생성해주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QTUFT/dJMcadnJPrx/26DpvdjlMPOC8vIs5JS1pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQTUFT%2FdJMcadnJPrx%2F26DpvdjlMPOC8vIs5JS1pK%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;2543&quot; height=&quot;742&quot; data-origin-width=&quot;2543&quot; data-origin-height=&quot;742&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BlackBoard에 key값 생성해주기&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;이러면 3개의 변수가 생성된다&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;그 다음으로는 해당 행동 트리를 동작시킬 AIController를 생성해주자&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1779&quot; data-origin-height=&quot;1270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp8JV3/dJMcagY5AD7/mqSqPu0RwBeGXG6DpGtRCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp8JV3/dJMcagY5AD7/mqSqPu0RwBeGXG6DpGtRCK/img.png&quot; data-alt=&quot;AIController Blueprint 생성하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp8JV3/dJMcagY5AD7/mqSqPu0RwBeGXG6DpGtRCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp8JV3%2FdJMcagY5AD7%2FmqSqPu0RwBeGXG6DpGtRCK%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;1779&quot; height=&quot;1270&quot; data-origin-width=&quot;1779&quot; data-origin-height=&quot;1270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AIController Blueprint 생성하기&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;우선 Event on Possess를 블록을 만들어준다&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;Event On Possess란?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AIController가 Pawn(캐릭터)을 점유하는 순간 호출되는 이벤트이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;즉 AI의 초기화 이벤트라고 보면 될 것 같다&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확히 언제 호출되는가?&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;레벨 시작 시 (Auto Possess AI)&lt;/li&gt;
&lt;li&gt;Spawn된 Pawn을 AlController가 소유할 때&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Controller가 Pawn을 바꿔 탈 때&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;1077&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p8dm0/dJMcacCpDak/rfXa34R1kPk0mn2hvJ5I61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p8dm0/dJMcacCpDak/rfXa34R1kPk0mn2hvJ5I61/img.png&quot; data-alt=&quot;AIController 의 실행 명령 순서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p8dm0/dJMcacCpDak/rfXa34R1kPk0mn2hvJ5I61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp8dm0%2FdJMcacCpDak%2FrfXa34R1kPk0mn2hvJ5I61%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;986&quot; height=&quot;1077&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;1077&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AIController 의 실행 명령 순서&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Sequnce Then 0 으로 Use Blackboard block을 실행하여 사용할 Blackboard을 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Sequnce Then 1 으로 Behavior Tree를 실행 시켜 준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Sequnce Then 2 으로 Blackboard에사 저장한 Home Location 키값을 통해 해당 변수에 값을 저장해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; (반드시 Default 값을 키 값으로 저장할 것 HomeLocation 으로 외부에 보이는 key는 내가 지어준 것 )&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Sequnce Then 3 으로 Blackboard에서 마찬가지로 저장한 키값을 통해 해당 변수에 값을 저장해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2001&quot; data-origin-height=&quot;1264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KqPLZ/dJMcahwXqG8/4Oy7FWlBis7KPCQ04gNm31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KqPLZ/dJMcahwXqG8/4Oy7FWlBis7KPCQ04gNm31/img.png&quot; data-alt=&quot;Debug 하고 싶을 때는 해당 BP를 선택 해준다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KqPLZ/dJMcahwXqG8/4Oy7FWlBis7KPCQ04gNm31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKqPLZ%2FdJMcahwXqG8%2F4Oy7FWlBis7KPCQ04gNm31%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;2001&quot; height=&quot;1264&quot; data-origin-width=&quot;2001&quot; data-origin-height=&quot;1264&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Debug 하고 싶을 때는 해당 BP를 선택 해준다.&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;오른쪽 상단 위의 빨간 박스에서 디버깅 할 Controller을 설정해 주어야만 Behavior Tree또한 simulate과정이 진행된다.&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;여기까지가 Blackboard와&amp;nbsp; AIController을 설정한 것이다.&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;다음으로는 BehaviorTree을 생성하고 위에서 만든 것을 넣어서 연결해보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;1067&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN4gxC/dJMcaibzkKb/W25TjbpaPRigXNurL8JXE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN4gxC/dJMcaibzkKb/W25TjbpaPRigXNurL8JXE1/img.png&quot; data-alt=&quot;Behavior Tree Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN4gxC/dJMcaibzkKb/W25TjbpaPRigXNurL8JXE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN4gxC%2FdJMcaibzkKb%2FW25TjbpaPRigXNurL8JXE1%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;1900&quot; height=&quot;1067&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;1067&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Behavior Tree Blueprint&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행동트리 블루프린트를 만들면 일단 Root에서 어떤 Blackboard을 사용할 것인지 선택해주어야 한다.&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;다음으로는 Sequnce block을 만들어주고&amp;nbsp; 다음으로는 3가지 Task가 있는데 왼쪽부터 살펴보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Wait Blackboard Time&amp;nbsp;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;언리얼에서 기본 제공하는 Task 노드로 blackboard에서 시간을 가져온다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2358&quot; data-origin-height=&quot;1072&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ6tkZ/dJMcabDvflx/v14TKzdvVAklnM5k6fd5g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ6tkZ/dJMcabDvflx/v14TKzdvVAklnM5k6fd5g1/img.png&quot; data-alt=&quot;Task에 blackboard에 설정한 변수 설정하는 작업&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ6tkZ/dJMcabDvflx/v14TKzdvVAklnM5k6fd5g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ6tkZ%2FdJMcabDvflx%2Fv14TKzdvVAklnM5k6fd5g1%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;2358&quot; height=&quot;1072&quot; data-origin-width=&quot;2358&quot; data-origin-height=&quot;1072&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Task에 blackboard에 설정한 변수 설정하는 작업&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;설정한 변수의 시간만큼 대기하다 FinsishExecute를 반환하여 다음 Task을 진행 시키도록 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BTTask_SelectPatrolLocation&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 Task는 내가 만든 Task Node로 Blueprint 생성에서&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQnp7E/dJMcabco2xD/aUfGttdEgflL42Yj710X71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQnp7E/dJMcabco2xD/aUfGttdEgflL42Yj710X71/img.png&quot; data-alt=&quot;Task Blueprint 만드는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQnp7E/dJMcabco2xD/aUfGttdEgflL42Yj710X71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQnp7E%2FdJMcabco2xD%2FaUfGttdEgflL42Yj710X71%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;888&quot; height=&quot;376&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Task Blueprint 만드는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 메뉴를 선택해주면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/euDKE5/dJMcahReC36/bWyqfikLgJBZDvJeamgrF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euDKE5/dJMcahReC36/bWyqfikLgJBZDvJeamgrF1/img.png&quot; data-alt=&quot;BTTask_SelectPatrolLocation&amp;amp;nbsp; 의 Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euDKE5/dJMcahReC36/bWyqfikLgJBZDvJeamgrF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuDKE5%2FdJMcahReC36%2FbWyqfikLgJBZDvJeamgrF1%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;1601&quot; height=&quot;577&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BTTask_SelectPatrolLocation&amp;nbsp; 의 Event Graph&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;해당 블루프린트에서는 네비게이션을 기반으로 랜덤으로 이동 가능한 위치를 검색하는 Task를 담당한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 HomeLocation을 시작지점을 기준으로 반지름 400인 원의 범위 만큼 주위를 배회하도록 랜덤으로 값을 제공해주는 기능&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;Move To Task&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Move To Task는 AIController가 Navigation 시스템(NaviMesh)을 기반으로 목표 위치까지의 경로를 계산하고, Pawn의 Movement Component를 통해 해당 위치로 이동시키는 Task이다.&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;이렇게 하면 간단한 몬스터 AI가 완성되고 적용하는 방법은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2547&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIwJpZ/dJMcafTq9xN/scMqf5tpU78cQk2mJ3FyP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIwJpZ/dJMcafTq9xN/scMqf5tpU78cQk2mJ3FyP0/img.png&quot; data-alt=&quot;BP_Bear에 AIController 설정하여 행동트리가 실행될 수 있도록 하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIwJpZ/dJMcafTq9xN/scMqf5tpU78cQk2mJ3FyP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIwJpZ%2FdJMcafTq9xN%2FscMqf5tpU78cQk2mJ3FyP0%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;2547&quot; height=&quot;706&quot; data-origin-width=&quot;2547&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Bear에 AIController 설정하여 행동트리가 실행될 수 있도록 하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;NaviMesh 설치하는 방법&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;961&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mOLjp/dJMcahKuN9x/Rs7AZTJjtP6XYZbiiIXdqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mOLjp/dJMcahKuN9x/Rs7AZTJjtP6XYZbiiIXdqk/img.png&quot; data-alt=&quot;Navi Mesh 설치하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mOLjp/dJMcahKuN9x/Rs7AZTJjtP6XYZbiiIXdqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmOLjp%2FdJMcahKuN9x%2FRs7AZTJjtP6XYZbiiIXdqk%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;1803&quot; height=&quot;961&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;961&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Navi Mesh 설치하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 사진과 같이 Navi Mesh를 설치하기 위해서는 Place Actors 에 Bolumes를 선택하고 Nav Mesh Bounds Volume를 드래그하면 된다.&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x3rYU/dJMcadutPQD/qZtDDLYK5VT3ZVvKidpju1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x3rYU/dJMcadutPQD/qZtDDLYK5VT3ZVvKidpju1/img.png&quot; data-alt=&quot;Navi mesh bound volume size 조정후의 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x3rYU/dJMcadutPQD/qZtDDLYK5VT3ZVvKidpju1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx3rYU%2FdJMcadutPQD%2FqZtDDLYK5VT3ZVvKidpju1%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;921&quot; height=&quot;644&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Navi mesh bound volume size 조정후의 모습&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;해당 네비 매쉬를 바닥에 설치할때는 MainLevel에서 설치해주어야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 해당 사진처럼 영역을 보기 위해서는 Lit 옵션이나 혹은 p를 누르면 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;1218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lp8xT/dJMcaaq3MyV/QKlcnfQJ2nLU87zsgSgmm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lp8xT/dJMcaaq3MyV/QKlcnfQJ2nLU87zsgSgmm1/img.png&quot; data-alt=&quot;Navi Mesh를 생성한 뒤 Build Path 하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lp8xT/dJMcaaq3MyV/QKlcnfQJ2nLU87zsgSgmm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flp8xT%2FdJMcaaq3MyV%2FQKlcnfQJ2nLU87zsgSgmm1%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;677&quot; height=&quot;1439&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;1218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Navi Mesh를 생성한 뒤 Build Path 하기&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;Nav Build Paths를 하는 이유는 네비 매쉬를 배치한 이후 언리얼이 지형을 분석하고 이동 가능한 영역 판별하고 경사 및 장애물 체크를 하고 Nav Mesh를 최종적으로 생성하기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260318_180554.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BdDsQ/dJMcadnJTZi/5xm8CgXNpzj6K9kIRilKn0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BdDsQ/dJMcadnJTZi/5xm8CgXNpzj6K9kIRilKn0/img.gif&quot; data-alt=&quot;구현 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BdDsQ/dJMcadnJTZi/5xm8CgXNpzj6K9kIRilKn0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/BdDsQ/dJMcadnJTZi/5xm8CgXNpzj6K9kIRilKn0/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;400&quot; height=&quot;280&quot; data-filename=&quot;KakaoTalk_Recording_20260318_180554.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>blueprint</category>
      <category>Unreal</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/91</guid>
      <comments>https://seonhwan2547.tistory.com/91#entry91comment</comments>
      <pubDate>Wed, 18 Mar 2026 10:12:49 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 3 ( Player Camera Manager, Animation Montage)</title>
      <link>https://seonhwan2547.tistory.com/90</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;언리얼에서 Player 카메라의 회전 범위를 조절하기 위해서는 Player Camera Blueprint로 범위를 제한할 수&amp;nbsp; 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cksA7p/dJMcaa5DCzb/417qk1M4X0IdIAyjxTiOrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cksA7p/dJMcaa5DCzb/417qk1M4X0IdIAyjxTiOrk/img.png&quot; data-alt=&quot;Player Camera Blueprint 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cksA7p/dJMcaa5DCzb/417qk1M4X0IdIAyjxTiOrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcksA7p%2FdJMcaa5DCzb%2F417qk1M4X0IdIAyjxTiOrk%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;1076&quot; height=&quot;1080&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Player Camera Blueprint 만들기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2017&quot; data-origin-height=&quot;1092&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mSql8/dJMcaiWRivi/wAHUAa6hIzneNRlaqSt8XK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mSql8/dJMcaiWRivi/wAHUAa6hIzneNRlaqSt8XK/img.png&quot; data-alt=&quot;Player Camera Manager Blueprint의 회전 각도 조절하는 옵션 값들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mSql8/dJMcaiWRivi/wAHUAa6hIzneNRlaqSt8XK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmSql8%2FdJMcaiWRivi%2FwAHUAa6hIzneNRlaqSt8XK%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;2017&quot; height=&quot;1092&quot; data-origin-width=&quot;2017&quot; data-origin-height=&quot;1092&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Player Camera Manager Blueprint의 회전 각도 조절하는 옵션 값들&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;현재는 위 아래 회전각도인 Pitch값의 범위를 -45도에서 45도 사이로 제한 해 둔 것을 볼 수있다.&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;이제 해당 Player Camera Manager는 Controller에 적용시키면 게임에 적용된다.&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;다시 BP_Controller로 돌아가서 설정을 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;1013&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/54aUC/dJMcab4w8Ju/bEgLA9bXk9KKaGyaZ5A0gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/54aUC/dJMcab4w8Ju/bEgLA9bXk9KKaGyaZ5A0gk/img.png&quot; data-alt=&quot;BP_Controller에서 Player 카메라 매니저 설정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/54aUC/dJMcab4w8Ju/bEgLA9bXk9KKaGyaZ5A0gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F54aUC%2FdJMcab4w8Ju%2FbEgLA9bXk9KKaGyaZ5A0gk%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;2052&quot; height=&quot;1013&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;1013&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Controller에서 Player 카메라 매니저 설정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;공격 애니메이션 넣어보기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(갑작스런 Tmi,&amp;nbsp; AnimInstance에서 Event Graph가 AnimGraph보다 먼저 실행된다.)&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;일반적으로는 로직을 담당하는 블루프린트 or C++에서 상태를 관리하는게 일반적이다.&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;이전 Directx11 프로젝트를 진행할 때 enum값을 통해 상태를 관리함으로써 각 상태에 따른 로직을 명확하게 분리하고&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;따라서 Unreal Engine에서도 마찬가지로 Enum 기반의 상태 관리 방식을 적용하여 보다 직관적이고 안정적인 캐릭터 상태 관리를 구현하고자 한다.&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;우선 캐릭터의 상태를 Enum값으로 보관할 Enumeration을 만들자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;1226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN1zA7/dJMb99ZZdLm/HPekPzYmwYyRHHKUtHepuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN1zA7/dJMb99ZZdLm/HPekPzYmwYyRHHKUtHepuK/img.png&quot; data-alt=&quot;Enum 자료형 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN1zA7/dJMb99ZZdLm/HPekPzYmwYyRHHKUtHepuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN1zA7%2FdJMb99ZZdLm%2FHPekPzYmwYyRHHKUtHepuK%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;1107&quot; height=&quot;1226&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;1226&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Enum 자료형 만들기&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;해당 Enum 자료형을 열면&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kZx9O/dJMcabKgMmA/VXStCJe40NuErsXwSOouGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kZx9O/dJMcabKgMmA/VXStCJe40NuErsXwSOouGK/img.png&quot; data-alt=&quot;Enum 값 설정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kZx9O/dJMcabKgMmA/VXStCJe40NuErsXwSOouGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkZx9O%2FdJMcabKgMmA%2FVXStCJe40NuErsXwSOouGK%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;2517&quot; height=&quot;371&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Enum 값 설정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 Enum 값을 설정해 줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 본격적으로&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnY7pA/dJMcaaq2pCt/CZTgfqWa2Ku639B4bIeuP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnY7pA/dJMcaaq2pCt/CZTgfqWa2Ku639B4bIeuP1/img.png&quot; data-alt=&quot;Character Blueprint Event Graph 작업&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnY7pA/dJMcaaq2pCt/CZTgfqWa2Ku639B4bIeuP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnY7pA%2FdJMcaaq2pCt%2FCZTgfqWa2Ku639B4bIeuP1%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;1303&quot; height=&quot;638&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Character Blueprint Event Graph 작업&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;Character Class에서 Input_Action 을 가져와서 해당 Input에 입력 ( started&amp;nbsp; = 입력이 들어오는 한 순간)을 체크해서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 입력이 들어온다면서 현재 상태를 switch case문으로 분류하고 만약 현재 상태가 Locomotion 이라면 현재 State 를 Battle 로 set 해주는 것을 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHhEtU/dJMcahKtwoW/NdErxaz2oCTr3yWl7IWYk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHhEtU/dJMcahKtwoW/NdErxaz2oCTr3yWl7IWYk0/img.png&quot; data-alt=&quot;공격이 끝났을 때 상태 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHhEtU/dJMcahKtwoW/NdErxaz2oCTr3yWl7IWYk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHhEtU%2FdJMcahKtwoW%2FNdErxaz2oCTr3yWl7IWYk0%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;1023&quot; height=&quot;391&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;391&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;다음은 Customer Event를 통한 공격이 끝났을 때는 다시 상태를 Locomotion으로 설정하는 블루프린트이다.&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;해당 Customer Event는 notify가 호출될 때 Animation Blueprint의 EventGrpah에 로직 추가해줘 작동하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhbnJS/dJMcaio4FW6/y1k7BZ6fTEAviqNw5dBxaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhbnJS/dJMcaio4FW6/y1k7BZ6fTEAviqNw5dBxaK/img.png&quot; data-alt=&quot;Animation Blueprint Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhbnJS/dJMcaio4FW6/y1k7BZ6fTEAviqNw5dBxaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhbnJS%2FdJMcaio4FW6%2Fy1k7BZ6fTEAviqNw5dBxaK%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;1078&quot; height=&quot;383&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation Blueprint Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;그럴 땐 다음과 같이 블루 프린트를 디버깅하면 된다. ( F9 = breakpoint 단축키 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블루 프린트 디버깅하기&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;899&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q1slU/dJMcaaxOeMe/msUEQhZvfghJ6gnk4tIGzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q1slU/dJMcaaxOeMe/msUEQhZvfghJ6gnk4tIGzk/img.png&quot; data-alt=&quot;Blueprint Debug&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q1slU/dJMcaaxOeMe/msUEQhZvfghJ6gnk4tIGzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq1slU%2FdJMcaaxOeMe%2FmsUEQhZvfghJ6gnk4tIGzk%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;1613&quot; height=&quot;899&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;899&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blueprint Debug&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1987&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckjWDy/dJMcajuH6iK/XBhMCtYqjOqOBIs1hOrEF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckjWDy/dJMcajuH6iK/XBhMCtYqjOqOBIs1hOrEF0/img.png&quot; data-alt=&quot;Blueprint Debug Window&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckjWDy/dJMcajuH6iK/XBhMCtYqjOqOBIs1hOrEF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckjWDy%2FdJMcajuH6iK%2FXBhMCtYqjOqOBIs1hOrEF0%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;1987&quot; height=&quot;888&quot; data-origin-width=&quot;1987&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blueprint Debug Window&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Notify 이벤트 등록&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1739&quot; data-origin-height=&quot;1100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pWK9i/dJMcadnIJEY/7K9UbIMIfRpYcKtKI38kkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pWK9i/dJMcadnIJEY/7K9UbIMIfRpYcKtKI38kkK/img.png&quot; data-alt=&quot;Animation File Notify 등록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pWK9i/dJMcadnIJEY/7K9UbIMIfRpYcKtKI38kkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpWK9i%2FdJMcadnIJEY%2F7K9UbIMIfRpYcKtKI38kkK%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;1739&quot; height=&quot;1100&quot; data-origin-width=&quot;1739&quot; data-origin-height=&quot;1100&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation File Notify 등록&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;Animation Notify를 사용하는 이유&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 애니메이션 타임라인 상의 특정 시점에 이벤트를 발새시키기 위한 기능이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 단순히 애니메이션을 재생하는 것을 넘어 &lt;u&gt;&lt;b&gt;정확한 타이밍에 로직을 실행하기 위해 사용된다&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Notify 이벤트가 호출을 가져오는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w8CMf/dJMcafskvbq/wdJYGRmZtHcYUT7CZaF0W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w8CMf/dJMcafskvbq/wdJYGRmZtHcYUT7CZaF0W0/img.png&quot; data-alt=&quot;Animation Blueprint EventGraph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w8CMf/dJMcafskvbq/wdJYGRmZtHcYUT7CZaF0W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw8CMf%2FdJMcafskvbq%2FwdJYGRmZtHcYUT7CZaF0W0%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;1125&quot; height=&quot;376&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation Blueprint EventGraph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;776&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K7bNa/dJMcadaaaqU/SHqfjAzkC8GW4wlkyDRlOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K7bNa/dJMcadaaaqU/SHqfjAzkC8GW4wlkyDRlOk/img.png&quot; data-alt=&quot;Animation Noitfy를 가져오는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K7bNa/dJMcadaaaqU/SHqfjAzkC8GW4wlkyDRlOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK7bNa%2FdJMcadaaaqU%2FSHqfjAzkC8GW4wlkyDRlOk%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;1184&quot; height=&quot;776&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;776&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation Noitfy를 가져오는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 Animation notify가 호출되면 다음과 같이 실행되도록 처리할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Montage 와 일반 Animation 시스템 차이 정리&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;State Machine 기반 Animation&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;State Machine은 조건(상태)에 따라 애니메이션을 전환한다.&lt;/li&gt;
&lt;li&gt;상태가 변경되면 현재 애니메이션과 관계없이 즉시 다음 상태의 애니메이션으로 전이된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 상태 변화가 곧 애니메이션 변경이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Montage&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Montage는 State Machine과 독립적으로 재생된다.&lt;/li&gt;
&lt;li&gt;Slot을 통해 최종 애니메이션 위에 덮여씌워지는 구조로 동작한다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 Idle -&amp;gt; Run으로 바뀌더라도 Montage는 영향을 받지 않고 계속 재생된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 상태와 무관하게 재생이 유지된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;왜 Montage는 끊기지 않는가?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;State Machine은 상태 기반 -&amp;gt; 즉시 전이됨&lt;/li&gt;
&lt;li&gt;Montage는 명령 기반 -&amp;gt; 한 번 실행되면 유지됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 State 변화로 인해 애니메이션이 중간에 끊기는 일이 발생하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Montage를 실행하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;755&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA5Vjm/dJMcaaR7LfA/sWqdzfZDUkqXleaub33190/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA5Vjm/dJMcaaR7LfA/sWqdzfZDUkqXleaub33190/img.png&quot; data-alt=&quot;Montage을 넣은 Character Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA5Vjm/dJMcaaR7LfA/sWqdzfZDUkqXleaub33190/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA5Vjm%2FdJMcaaR7LfA%2FsWqdzfZDUkqXleaub33190%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;1197&quot; height=&quot;755&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Montage을 넣은 Character Blueprint&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzUsq/dJMcajaoGZu/YWSxELcJI0xNJDF5KIgsZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzUsq/dJMcajaoGZu/YWSxELcJI0xNJDF5KIgsZK/img.png&quot; data-alt=&quot;AnimGraph안의 Battle State&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzUsq/dJMcajaoGZu/YWSxELcJI0xNJDF5KIgsZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzUsq%2FdJMcajaoGZu%2FYWSxELcJI0xNJDF5KIgsZK%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;1253&quot; height=&quot;545&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AnimGraph안의 Battle State&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Character Blueprint에서 Montage Animation을 실행하면서 State안에서는 현재 실행되고 있는 애니메이션 포즈와 현재 시간의&amp;nbsp; 몽타주 포즈를 블랜드(A자세에서 B자세로 섞는거 즉 자연스럽게 애니메이션을 전환하기 위한 보간 작업이라고 보면 된다) 하여 진행하면서 애니메이션을 실행시킨다&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;몽타주 애니메이션을 이용한 콤보 공격 구현 방법&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2018&quot; data-origin-height=&quot;1286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP7MI7/dJMcag5RDO1/o9zKBE9KAWvKHh31YMf7MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP7MI7/dJMcag5RDO1/o9zKBE9KAWvKHh31YMf7MK/img.png&quot; data-alt=&quot;Montage Combo Attack Section&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP7MI7/dJMcag5RDO1/o9zKBE9KAWvKHh31YMf7MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP7MI7%2FdJMcag5RDO1%2Fo9zKBE9KAWvKHh31YMf7MK%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;2018&quot; height=&quot;1286&quot; data-origin-width=&quot;2018&quot; data-origin-height=&quot;1286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Montage Combo Attack Section&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;각 Montage의 Section 마다 마우스 클릭을 통한 Attack의 모션을 바꿀려고 한다.&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;해당 작업을 하기 위해서는 일단 마우스 좌클릭으로 인한 콤보 Attack의 넘버링을 바꿔줄려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;813&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN9rNr/dJMcaiWRCaN/6lin4jXVpekZVg9lwdKIe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN9rNr/dJMcaiWRCaN/6lin4jXVpekZVg9lwdKIe1/img.png&quot; data-alt=&quot;Character Blueprint 에서 Montage Section name 구분 짓기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN9rNr/dJMcaiWRCaN/6lin4jXVpekZVg9lwdKIe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN9rNr%2FdJMcaiWRCaN%2F6lin4jXVpekZVg9lwdKIe1%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;1209&quot; height=&quot;813&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;813&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Character Blueprint 에서 Montage Section name 구분 짓기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Weapon을 캐릭터에 붙히는 방법 2가지 &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Socket에 Weapon을 붙혀넣기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2533&quot; data-origin-height=&quot;1324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8wbqU/dJMcabcn2FO/VZzRWGtcEkcYxPJR4mQ9Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8wbqU/dJMcabcn2FO/VZzRWGtcEkcYxPJR4mQ9Hk/img.png&quot; data-alt=&quot;Weapon position을 preview로 미리 붙혀넣어서 해당 위치 확인하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8wbqU/dJMcabcn2FO/VZzRWGtcEkcYxPJR4mQ9Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8wbqU%2FdJMcabcn2FO%2FVZzRWGtcEkcYxPJR4mQ9Hk%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;2533&quot; height=&quot;1324&quot; data-origin-width=&quot;2533&quot; data-origin-height=&quot;1324&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Weapon position을 preview로 미리 붙혀넣어서 해당 위치 확인하기&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;해당 화면은 해당 모델의 skeleton으로 들어가면 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;1267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vNtis/dJMb99MoW6T/oCNFKtTQ0RAGejHyLkekL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vNtis/dJMb99MoW6T/oCNFKtTQ0RAGejHyLkekL0/img.png&quot; data-alt=&quot;Character Mesh의 하위에 Skeletal Mesh Component를 추가하여 무기를 부착&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vNtis/dJMb99MoW6T/oCNFKtTQ0RAGejHyLkekL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvNtis%2FdJMb99MoW6T%2FoCNFKtTQ0RAGejHyLkekL0%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;2517&quot; height=&quot;1267&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;1267&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Character Mesh의 하위에 Skeletal Mesh Component를 추가하여 무기를 부착&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해야할 것으로는 무기 위치에 해당할 Parent Socket 값 넣기 그리고 매쉬 Asset 추가하기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 이벤트 방식으로 ( 칼과 충돌했을 때 플레이어와 붙히기 )&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 방식으로 칼을 획득하게 하기 위해서는 다음과 같은 과정이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무기에 Collider Componnet를 부착하여 충돌 속성을 부여하고 해당 충돌 발생 이벤트를 OnComponent Begin Overlap를 사용하여 충돌한 Actor 객체를 가져와서 해당 Actor의 custom Event를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1947&quot; data-origin-height=&quot;1157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bER4Rc/dJMcahRdE4t/6nCu3ZYZJXaql4fDlgIDMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bER4Rc/dJMcahRdE4t/6nCu3ZYZJXaql4fDlgIDMk/img.png&quot; data-alt=&quot;BP_Weapon Event Graph Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bER4Rc/dJMcahRdE4t/6nCu3ZYZJXaql4fDlgIDMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbER4Rc%2FdJMcahRdE4t%2F6nCu3ZYZJXaql4fDlgIDMk%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;1947&quot; height=&quot;1157&quot; data-origin-width=&quot;1947&quot; data-origin-height=&quot;1157&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Weapon Event Graph Blueprint&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpBxza/dJMcaaYRnuD/6RH6LyvHMkzmRjYXSoT1eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpBxza/dJMcaaYRnuD/6RH6LyvHMkzmRjYXSoT1eK/img.png&quot; data-alt=&quot;BP_Character Event Graph Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpBxza/dJMcaaYRnuD/6RH6LyvHMkzmRjYXSoT1eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpBxza%2FdJMcaaYRnuD%2F6RH6LyvHMkzmRjYXSoT1eK%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;1247&quot; height=&quot;622&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Character Event Graph Blueprint&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Socket Name : 부착할 위치를 지정하는 곳 ( 캐릭터의 Bone 또는 Socket 이름을 사용한다 )&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Location Rule : 부착 시 대상 컴포넌트의 위치를 어떤 기준으로 맞출지 결정하는 규칙&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rotation Rule : 부착 시 회전을 어떤 기준으로 적용할지 결정하는 규칙&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scale Rule : 부착 시 스케일을 어떤 기준으로 유지 또는 적용할지 결정하는 규칙&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Rule에 적용되는 옵션들&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Keep Relative : 기존 상대 위치 유지 &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Keep World : 월드 위치 유지 &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Snap to Target : 대상 위치에 정확히 맞춤&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260317_155505.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ818L/dJMcajhadCD/8eG8xjq108TknkxkADlHN0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ818L/dJMcajhadCD/8eG8xjq108TknkxkADlHN0/img.gif&quot; data-alt=&quot;구현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ818L/dJMcajhadCD/8eG8xjq108TknkxkADlHN0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cZ818L/dJMcajhadCD/8eG8xjq108TknkxkADlHN0/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;400&quot; height=&quot;183&quot; data-filename=&quot;KakaoTalk_Recording_20260317_155505.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;183&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;특정 순간에만 Collider를 On/Off 구현&lt;/b&gt;&lt;/h4&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. Animation Notify 발생&amp;nbsp;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp; 공격 애니메이션 타임라인에 설정된 Notify가 호출된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. AnimBlueprint Event Graph에서 처리&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 Notify 이벤트를 수신한다&amp;nbsp;&lt;/li&gt;
&lt;li&gt;현재 애니메이션을 재생 중인 Pawn을 가져온 뒤, Character로 캐스팅 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Character로 이벤트 전달&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터의 Custom Event를 호출한다 ( BP_Character의 OnAttackCheckBegin, BP_Character의 OnAttackCheckEnd )&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Weapon Mesh로 전달&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐릭터는 자신이 소유한 Weapon Mesh에 접근하여 Weapon의 Custom Event를 호출한다. ( BP_Weapon의 OnAttackCheckBegin, BP_ Weapon의 OnAttackCheckEnd )&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Animation notify를 사용하여 어느 애니메이션 key frame에 Collider을 키고 어느 key Frame에 Collider를 끌 지를&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 notify 이름으로 &quot;AttackCheckBegin&quot; , &quot;AttackCheckEnd&quot;으로 설정합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;1269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lxE7U/dJMcafZ9Ye4/K3X0z6PrbxT0ayCBZ8YYq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lxE7U/dJMcafZ9Ye4/K3X0z6PrbxT0ayCBZ8YYq0/img.png&quot; data-alt=&quot;Animation Montage에 notify를 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lxE7U/dJMcafZ9Ye4/K3X0z6PrbxT0ayCBZ8YYq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlxE7U%2FdJMcafZ9Ye4%2FK3X0z6PrbxT0ayCBZ8YYq0%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;1352&quot; height=&quot;1269&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;1269&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation Montage에 notify를 추가&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;주의할 점으로는 ComboCheck 뒤에 notify를 설정하면 jump section하면서&amp;nbsp; notify가 호출이 안될 수 있기 때문에 앞에다가 설정하도록 하자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;883&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2jFLT/dJMcafFS2gN/VPj9eFflil497aaRgnaK01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2jFLT/dJMcafFS2gN/VPj9eFflil497aaRgnaK01/img.png&quot; data-alt=&quot;Animation Blueprint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2jFLT/dJMcafFS2gN/VPj9eFflil497aaRgnaK01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2jFLT%2FdJMcafFS2gN%2FVPj9eFflil497aaRgnaK01%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;1772&quot; height=&quot;883&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;883&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Animation Blueprint&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;다음과 같이 Animation Event Graph를 설정하여 Anim notify를 호출 받으면 Character의 Custom Event를 호출하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1939&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tEEkH/dJMcagrfd8j/kMFjuAvJwVEyrjBHZ12Knk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tEEkH/dJMcagrfd8j/kMFjuAvJwVEyrjBHZ12Knk/img.png&quot; data-alt=&quot;Character Event Graph에서 BP_Weapon의 Custom Event 호출하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tEEkH/dJMcagrfd8j/kMFjuAvJwVEyrjBHZ12Knk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtEEkH%2FdJMcagrfd8j%2FkMFjuAvJwVEyrjBHZ12Knk%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;1939&quot; height=&quot;907&quot; data-origin-width=&quot;1939&quot; data-origin-height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Character Event Graph에서 BP_Weapon의 Custom Event 호출하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1927&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ShpE6/dJMcahqaCvM/GXG2th8BuE52XEiTSrMjKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ShpE6/dJMcahqaCvM/GXG2th8BuE52XEiTSrMjKk/img.png&quot; data-alt=&quot;BP_Weapon의 Attack Collider On/Off 제어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ShpE6/dJMcahqaCvM/GXG2th8BuE52XEiTSrMjKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FShpE6%2FdJMcahqaCvM%2FGXG2th8BuE52XEiTSrMjKk%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;1927&quot; height=&quot;946&quot; data-origin-width=&quot;1927&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Weapon의 Attack Collider On/Off 제어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 주의 깊게 봐야할 것은 바로 Set Collision Enabled의 New Type의 속성으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;No Collision &lt;/b&gt;&lt;b&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;충돌을 전혀 수행하지 않음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;물리 충돌 및 충돌 검사( = 트레이스 ) 모두 비활성화&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Query Only &lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;물리적인 충돌 반응은 없지만 충돌 검사 ( 트레이스 , 오버랩 등)는 가능 &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;즉, 실제로 부딪히지는 않지만, 충돌 판정은 체크할 수 있는 상태&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;EVENT DISPATCHERS 사용해보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Event Dispatcher는 Blueprint에서 사용하는 Delegate 입니다.&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;Delegate란?&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;Bind -&amp;gt; 이벤트 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Call -&amp;gt;&amp;nbsp; 이벤트 실행&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhRf84/dJMcadVyitC/ZAtE5DxwVrbrmSCJC2b6J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhRf84/dJMcadVyitC/ZAtE5DxwVrbrmSCJC2b6J0/img.png&quot; data-alt=&quot;무기 줍는 이벤트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhRf84/dJMcadVyitC/ZAtE5DxwVrbrmSCJC2b6J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhRf84%2FdJMcadVyitC%2FZAtE5DxwVrbrmSCJC2b6J0%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;1393&quot; height=&quot;417&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;417&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1445&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czPKgU/dJMcacbjIbU/cytYKB23t0EPkMdYaU9pNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czPKgU/dJMcacbjIbU/cytYKB23t0EPkMdYaU9pNk/img.png&quot; data-alt=&quot;무기 줍는 이벤트에 공격 판정 시작 및 종료 이벤트 함수를 연결(Bind) 하는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czPKgU/dJMcacbjIbU/cytYKB23t0EPkMdYaU9pNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczPKgU%2FdJMcacbjIbU%2FcytYKB23t0EPkMdYaU9pNk%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;1445&quot; height=&quot;346&quot; data-origin-width=&quot;1445&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;무기 줍는 이벤트에 공격 판정 시작 및 종료 이벤트 함수를 연결(Bind) 하는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1427&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cb04p7/dJMcacWFIxJ/r7MdpGSL7k15KrroqquKLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cb04p7/dJMcacWFIxJ/r7MdpGSL7k15KrroqquKLk/img.png&quot; data-alt=&quot;전체 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cb04p7/dJMcacWFIxJ/r7MdpGSL7k15KrroqquKLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcb04p7%2FdJMcacWFIxJ%2Fr7MdpGSL7k15KrroqquKLk%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;1427&quot; height=&quot;227&quot; data-origin-width=&quot;1427&quot; data-origin-height=&quot;227&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYMO4n/dJMcafskIbg/tY2FBaV4Of5okthoEI281k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYMO4n/dJMcafskIbg/tY2FBaV4Of5okthoEI281k/img.png&quot; data-alt=&quot;이벤트를 Call(실행) 하는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYMO4n/dJMcafskIbg/tY2FBaV4Of5okthoEI281k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYMO4n%2FdJMcafskIbg%2FtY2FBaV4Of5okthoEI281k%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;1202&quot; height=&quot;893&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이벤트를 Call(실행) 하는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>blueprint</category>
      <category>Unreal</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/90</guid>
      <comments>https://seonhwan2547.tistory.com/90#entry90comment</comments>
      <pubDate>Tue, 17 Mar 2026 14:01:21 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 2 (플레이어 움직임 및 애니메이션, Level Streaming)</title>
      <link>https://seonhwan2547.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 플레이어의 움직임을 블루프린트로 구현해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;플레이어 생성 및 입력 처리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어가 움직이기 위해서는 단순히 위치를 이동시키는 것뿐만 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러(Controller), 입력 처리(Input), 그리고 Movement Component와 같은 요소들이 함께 필요합니다.&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;Pawn&lt;/b&gt;을 생성하여 간단한 이동을 구현해보고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 보다 확장된 기능을 제공하는 &lt;b&gt;Character&lt;/b&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;p data-ke-size=&quot;size16&quot;&gt;이를 위해 먼저 Input Action과 Input Mapping Context를 생성해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGamdC/dJMcajg84uj/NKlXOopMoTOKSD4OQAgwPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGamdC/dJMcajg84uj/NKlXOopMoTOKSD4OQAgwPK/img.png&quot; data-alt=&quot;Input Action (Move)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGamdC/dJMcajg84uj/NKlXOopMoTOKSD4OQAgwPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGamdC%2FdJMcajg84uj%2FNKlXOopMoTOKSD4OQAgwPK%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;1410&quot; height=&quot;627&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Input Action (Move)&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;위에서 생성한 Input Action은 어떤 입력 값을 받아올지 정의하는 Data Asset으로, 이번 예제에서는 키보드 입력(WASD)을 처리하기 위해 Value Type을 Axis 2D(Vector2D)로 설정하였습니다.&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;이를 통해 W,A,S,D 입력을 각각 하나의 벡터 값으로 받아와, 플레이어의 이동 방향을 보다 직관적으로 제어할 수 있도록 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfdY1r/dJMcaiig9SB/mGrk42kcqWLPspkbxKECf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfdY1r/dJMcaiig9SB/mGrk42kcqWLPspkbxKECf0/img.png&quot; data-alt=&quot;Input Mapping Context ( IMC_Game)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfdY1r/dJMcaiig9SB/mGrk42kcqWLPspkbxKECf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfdY1r%2FdJMcaiig9SB%2FmGrk42kcqWLPspkbxKECf0%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;1520&quot; height=&quot;498&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Input Mapping Context ( IMC_Game)&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;위에서 생성한 IMC_Game은 Input Mapping Context로, 앞서 선언한 IA_Move(Input Action)에 대해 어떤 키 입력이 어떤 축 값(X,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;즉, IMC는 단순히 키를 등록하는 것이 아니라&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입력값을 하나의 방향 데이터 (Vector2D)로 변환해주는 관리 역할을 한다고 볼 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속해서 살펴보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드 입력은 기본적으로 0 또는 1의 1차원 값으로 들어오기 때문에 이 단계에서 어떤 값이 X축인지, Y축인지 직접 매핑해주어야 합니다.&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;이를 위해 Swizzle Input Axis을 사용하여 입력 값을 원하는 축으로 재배치해줍니다.&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;W/S 입력을 Y축으로 사용하고 싶다면 Swizzle을 통해 해당 값을 Y축으로 전달하도록 설정합니다.&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;(Tmi. 입력은 기본적으로 PlayerController에서 처리된 후 Pawn으로 전달되는 구조입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;따라서 입력을 Controller에서 직접 처리할 수도 있고, Pawn(또는 Character)에서 처리할 수도 있으며, &lt;/b&gt;&lt;b&gt;프로젝트 구조에 맞게 적절한 위치를 선택하여 구현할 수 있습니다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmO7Vg/dJMcaaxNvQw/apmko5igwkPqPykjLFnXkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmO7Vg/dJMcaaxNvQw/apmko5igwkPqPykjLFnXkK/img.png&quot; data-alt=&quot;BP_Pawn Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmO7Vg/dJMcaaxNvQw/apmko5igwkPqPykjLFnXkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmO7Vg%2FdJMcaaxNvQw%2Fapmko5igwkPqPykjLFnXkK%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;1073&quot; height=&quot;644&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Pawn Event Graph&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐릭터가 이동하기 위해서는 Movement Component가 필요하며,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 예제에서는 중력의 영향을 받지 않는 FloatingPawnMovement를 추가하여 기본적인 이동을 구현하엿습니다.&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;(Tmi,&amp;nbsp; 만약 이동처리를 offset을 이용해 한다면 충돌처리가 되지 않는다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2529&quot; data-origin-height=&quot;986&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/viJxM/dJMcahwVqSO/wURgzmo0Kg2spVpQFrkeVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/viJxM/dJMcahwVqSO/wURgzmo0Kg2spVpQFrkeVK/img.png&quot; data-alt=&quot;BP_GameMode&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/viJxM/dJMcahwVqSO/wURgzmo0Kg2spVpQFrkeVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FviJxM%2FdJMcahwVqSO%2FwURgzmo0Kg2spVpQFrkeVK%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;2529&quot; height=&quot;986&quot; data-origin-width=&quot;2529&quot; data-origin-height=&quot;986&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_GameMode&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;다음으로는, 앞서 생성한 IMC(Input Mapping Context)과 플레이어를 실제 게임에 적용하기 위해 GameMode Blueprint를 설정해보겠습니다.&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;GameMode는 해당 월드에서 사용할 기본 클래스(플레어어, 컨트롤러 등)를 결정하는 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 월드 설정에서 Game Mode를 BP_GameMode로 지정해주어야 우리가 설정한 입력 시스템과 플레이어 로직이 정상적으로 작동하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;플레이어 애니메이션 동작&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 플레이어(캐릭터)를 만들고 플레이어 에 애니메이션을 적용하여, 단순한 이동 구현을 넘어 실제 게임과 같은 형태로 확장해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU7Kpw/dJMcaa5CUsk/TiajWvOb5sO36XRzplbXq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU7Kpw/dJMcaa5CUsk/TiajWvOb5sO36XRzplbXq1/img.png&quot; data-alt=&quot;BP_Character Viewport&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU7Kpw/dJMcaa5CUsk/TiajWvOb5sO36XRzplbXq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU7Kpw%2FdJMcaa5CUsk%2FTiajWvOb5sO36XRzplbXq1%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;1050&quot; height=&quot;618&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;618&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BP_Character Viewport&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;우선 플레이어에 기본적으로 추가된 Component를 살펴보자&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Capsule Component :&amp;nbsp; &amp;nbsp;캐릭터의 충돌을 담당하는 컴포넌트&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Arrow Component&amp;nbsp; &amp;nbsp; &amp;nbsp;:&amp;nbsp; &amp;nbsp;캐릭터의 Forward 방향(전방 방향)을 나타내는 기준&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Character Movement :&amp;nbsp; &amp;nbsp;플레이어의 이동 및 물리 동작을 처리하는 컴포넌트&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 플레이어를 화면에 비추기 위해 카메라 설정이 필요합니다.&lt;/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;이를 위해 Add 버튼을 통해 Spring Arm을 추가하고, 해당 Spring Arm 끝에 Camera를 부착하여 플레이어를 따라다니는 카메라를 구성합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBhblz/dJMcaiJjp3A/zR2BOpok68V1ulqtPqxqO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBhblz/dJMcaiJjp3A/zR2BOpok68V1ulqtPqxqO1/img.png&quot; data-alt=&quot;Player Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBhblz/dJMcaiJjp3A/zR2BOpok68V1ulqtPqxqO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBhblz%2FdJMcaiJjp3A%2FzR2BOpok68V1ulqtPqxqO1%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;1422&quot; height=&quot;739&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;739&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Player Event Graph&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;다음은 플레이어에 전달된 입력 값을 실제 이동으로 처리하는 Event Graph 입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 값은 Vector2D로 전달되기 때문에, 이를 각각 분리하여 앞/뒤 이동(Y축) 과 좌/우 이동(X축)에 사용합니다.&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;이후 각 축의 값을 Add Movement Input 노드에 전달하여 플레이어가 입력 방향에 맞게 이동하도록 구현합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만,&amp;nbsp;&lt;/b&gt;&lt;b&gt;이렇게 구현하면 플레이어는 단순히 이동만 하고 방향은 바뀌지 않는 문제가 발생합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;따라서 이번에는 카메라 기준으로 회전까지 함께 적용해보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnYwHd/dJMcagY3VVI/ZMaAYzoHWV8dV2GLRLfi70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnYwHd/dJMcagY3VVI/ZMaAYzoHWV8dV2GLRLfi70/img.png&quot; data-alt=&quot;회전을 추가한 노드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnYwHd/dJMcagY3VVI/ZMaAYzoHWV8dV2GLRLfi70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnYwHd%2FdJMcagY3VVI%2FZMaAYzoHWV8dV2GLRLfi70%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;923&quot; height=&quot;737&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;737&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;Get Control Rotation&lt;/b&gt; 입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Get Control Rotation이란?&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt; &amp;rarr; 현재 카메라(컨트롤러)가 바라보는 방향(회전값)을 의미합니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; 즉, 언리얼 엔진의 기준 축으로 부터 현재 카메라의 회전량을 의미합니다.&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력값은 보통 다음과 같이 나뉩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;X 입력 (A/D)&amp;nbsp; &amp;nbsp;&amp;rarr;&amp;nbsp; 좌/우 이동&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Y 입력 (W/S)&amp;nbsp; &amp;nbsp;&amp;rarr;&amp;nbsp; 앞/뒤 이동&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 처리하기 위해&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;X 입력&amp;nbsp; &amp;rarr; 카메라의 Right Vector 사용&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Y 입력&amp;nbsp; &amp;rarr; 카메라의 Yaw 값을 기반으로 Forward Vector 생성&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기서 Get Right Vector/ Get Foward Vector는 해당 주어진 회전값을 기준으로 해당 방향의 벡터를 생성해주는 노드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2297&quot; data-origin-height=&quot;755&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdovCN/dJMcafZ9a6m/W0D9TUqsBHRHskU7unJLS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdovCN/dJMcafZ9a6m/W0D9TUqsBHRHskU7unJLS1/img.png&quot; data-alt=&quot;Spring Arm의 Camera Setting 체크하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdovCN/dJMcafZ9a6m/W0D9TUqsBHRHskU7unJLS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdovCN%2FdJMcafZ9a6m%2FW0D9TUqsBHRHskU7unJLS1%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;2297&quot; height=&quot;755&quot; data-origin-width=&quot;2297&quot; data-origin-height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Spring Arm의 Camera Setting 체크하기&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;Use Pawn Control Rotation을 체크 안하면 카메라가 Control Rotation을 따라가지 않으므로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DnJIJ/dJMcacWEVwl/xmf4zVcl9nTRh8AiMooKkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DnJIJ/dJMcacWEVwl/xmf4zVcl9nTRh8AiMooKkK/img.png&quot; data-alt=&quot;마우스가 움직임으로써 Controller 회전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DnJIJ/dJMcacWEVwl/xmf4zVcl9nTRh8AiMooKkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDnJIJ%2FdJMcacWEVwl%2Fxmf4zVcl9nTRh8AiMooKkK%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;1042&quot; height=&quot;352&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;마우스가 움직임으로써 Controller 회전&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;위와 같은 노드에서 Control Rotation이 따라가지 않게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 체크한다면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;마우스 움직임 &amp;rarr; Control Rotation 변경 &lt;b&gt;&amp;rarr; &lt;/b&gt;Spring Arm 회전 &lt;b&gt;&lt;b&gt;&lt;b&gt;&amp;rarr;&amp;nbsp;&amp;nbsp;&lt;/b&gt;끝에 달린 카메라도 자연스럽게 회전&amp;nbsp;&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p 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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;805&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWY79J/dJMcaakfWhZ/kZ5bfc87gSkAWGCdPjq2gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWY79J/dJMcaakfWhZ/kZ5bfc87gSkAWGCdPjq2gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWY79J/dJMcaakfWhZ/kZ5bfc87gSkAWGCdPjq2gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWY79J%2FdJMcaakfWhZ%2FkZ5bfc87gSkAWGCdPjq2gk%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;1401&quot; height=&quot;805&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;805&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어의 애니메이션은 보통 AnimInstance에서 관리합니다.&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;AnimInstance의 Evenet Graph 역할&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 캐릭터의 상태(속도,점프 여부 등)를 기반으로 어떤 애니메이션을 재생할지 판단하기 위한 값을 업데이트하는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(즉, 애니메이션에 필요한 변수들을 계산하는 곳 )&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AnimInstance의 AnimGraph 역할&amp;nbsp;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; AnimGraph는 Event Graph에서 계산된 값을 기반으로 실제 애니메이션을 조합하고 최종 포즈를 만들어 출력하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;(주로, 다음애니메이션과 현재 애니메이션 사이 보간 시간 및 보간 그래프 조절&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Level Streaming이란?&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level Streaming은 하나의 큰 맵을 여러 개의 Level로 나누고, 필요한 부분만 실시간으로 로드/언로드하는 기능입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Level Streaming은 왜 필요한가?&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;gt; 메모리 과다 사용&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로딩시간 증가 -&amp;gt; 끊김 현상 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- FPS 저하&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이유로 Unreal에서는 Level Streaming을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;603&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s8MzP/dJMcahXYWlV/RjZfmcBzpIK7ZzK8svJzpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s8MzP/dJMcahXYWlV/RjZfmcBzpIK7ZzK8svJzpk/img.png&quot; data-alt=&quot;Level Streamming 자료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s8MzP/dJMcahXYWlV/RjZfmcBzpIK7ZzK8svJzpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs8MzP%2FdJMcahXYWlV%2FRjZfmcBzpIK7ZzK8svJzpk%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;741&quot; height=&quot;603&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;603&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Level Streamming 자료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 Level Streamming을 만들기 위해서는 3개의 Level이 필요하다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Persistent Level은 전체 맵을 의미하며&amp;nbsp; 그 이후로 SubLevel01, SubLevel02은 각각 나눠진 레벨 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;1222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZa3wU/dJMcacbiXjT/62aACPtUdRWMg2KGSWONS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZa3wU/dJMcacbiXjT/62aACPtUdRWMg2KGSWONS0/img.png&quot; data-alt=&quot;Levels UI 추가하는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZa3wU/dJMcacbiXjT/62aACPtUdRWMg2KGSWONS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZa3wU%2FdJMcacbiXjT%2F62aACPtUdRWMg2KGSWONS0%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;1270&quot; height=&quot;1222&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;1222&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Levels UI 추가하는 방법&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;Levels 추가하면 다음과 같이 Level 구조를 확인할 수 있는 UI가 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 원하는 Level을 Drag &amp;amp; Drop으로 추가하면 Sub Level 구조를 구성할 수 있습니다.&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;이번에 구현할 Level Streaming 방식&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.&amp;nbsp; 특정 지점을 기준으로 로딩 (Trigger 방식)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;rarr;&lt;span&gt;&amp;nbsp; 플레이어가 특정 경로를 지나갈 때 SubLevel02를 로딩하는 방식&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Trigger Volume을 이용하여 구현&lt;/li&gt;
&lt;li&gt;이벤트 기반 (플레이어 진입 시 로드, 즉 특정 조건 만족 시 발동)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;1073&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eVCQ1y/dJMcabcnlOw/jU8enw0SvZ0EYKc6vQeKJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eVCQ1y/dJMcabcnlOw/jU8enw0SvZ0EYKc6vQeKJ0/img.png&quot; data-alt=&quot;Trigger Volume 추가하는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eVCQ1y/dJMcabcnlOw/jU8enw0SvZ0EYKc6vQeKJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeVCQ1y%2FdJMcabcnlOw%2FjU8enw0SvZ0EYKc6vQeKJ0%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;472&quot; height=&quot;1073&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;1073&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Trigger Volume 추가하는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방식을 추가하기 위해서는 해당 맵을 클릭후&amp;nbsp; 왼쪽 Place Actor 창에서 Volumes 항목에서 Trigger Volume을 추가하면 된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dT501g/dJMcadVxueS/kKm9Jer0GXw9AHclR8QEl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dT501g/dJMcadVxueS/kKm9Jer0GXw9AHclR8QEl1/img.png&quot; data-alt=&quot;TriggerVolume을 추가한 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dT501g/dJMcadVxueS/kKm9Jer0GXw9AHclR8QEl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdT501g%2FdJMcadVxueS%2FkKm9Jer0GXw9AHclR8QEl1%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;1293&quot; height=&quot;673&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;TriggerVolume을 추가한 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2369&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wSZID/dJMcaaq13vS/PVKUUk5BR8zkHRZxBnOD91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wSZID/dJMcaaq13vS/PVKUUk5BR8zkHRZxBnOD91/img.png&quot; data-alt=&quot;MainLevel의 BluePrint 여는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wSZID/dJMcaaq13vS/PVKUUk5BR8zkHRZxBnOD91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwSZID%2FdJMcaaq13vS%2FPVKUUk5BR8zkHRZxBnOD91%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;2369&quot; height=&quot;686&quot; data-origin-width=&quot;2369&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MainLevel의 BluePrint 여는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2198&quot; data-origin-height=&quot;1241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRay6N/dJMcahwVNtT/UvvLRlRUqbck3uKFanrV5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRay6N/dJMcahwVNtT/UvvLRlRUqbck3uKFanrV5k/img.png&quot; data-alt=&quot;BluePrint에 Actor 넣는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRay6N/dJMcahwVNtT/UvvLRlRUqbck3uKFanrV5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRay6N%2FdJMcahwVNtT%2FUvvLRlRUqbck3uKFanrV5k%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;2198&quot; height=&quot;1241&quot; data-origin-width=&quot;2198&quot; data-origin-height=&quot;1241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BluePrint에 Actor 넣는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;852&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LVLfs/dJMcacPUDlM/MSmgGSDcmzkJaHnve2DqlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LVLfs/dJMcacPUDlM/MSmgGSDcmzkJaHnve2DqlK/img.png&quot; data-alt=&quot;MainLevel의 BluePrint Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LVLfs/dJMcacPUDlM/MSmgGSDcmzkJaHnve2DqlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLVLfs%2FdJMcacPUDlM%2FMSmgGSDcmzkJaHnve2DqlK%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;1481&quot; height=&quot;852&quot; data-origin-width=&quot;1481&quot; data-origin-height=&quot;852&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MainLevel의 BluePrint Event Graph&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;해당 방법은 Cpp로는 작성할 수 없고 오직 블루프린트로만 가능한 기능으므로 잊지말고 알고있자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260316_173940.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C7Mcw/dJMcagSjVUw/A29jtl8VKYRIFKbCMc2u10/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C7Mcw/dJMcagSjVUw/A29jtl8VKYRIFKbCMc2u10/img.gif&quot; data-alt=&quot;적용 후 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C7Mcw/dJMcagSjVUw/A29jtl8VKYRIFKbCMc2u10/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/C7Mcw/dJMcagSjVUw/A29jtl8VKYRIFKbCMc2u10/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;400&quot; height=&quot;194&quot; data-filename=&quot;KakaoTalk_Recording_20260316_173940.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;적용 후 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp; 카메라 위치 기반 로딩 (Level Streaming Volume 방식)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;rarr;&lt;span&gt;&amp;nbsp; 카메라의 위치에 따라 자동으로 SubLevel02를 로딩을 OnOff하는 방식&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Level Streaming Volume 사용&amp;nbsp;&lt;/li&gt;
&lt;li&gt;영역 기반 자동 로딩 ( = 위치 기반 자동 로딩으로 영역 진입 시 발생 )&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1iDYt/dJMcaaYQGoH/19FbuQCKy9L2kGSEzKHmp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1iDYt/dJMcaaYQGoH/19FbuQCKy9L2kGSEzKHmp1/img.png&quot; data-alt=&quot;Level Streaming Volume 추가하는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1iDYt/dJMcaaYQGoH/19FbuQCKy9L2kGSEzKHmp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1iDYt%2FdJMcaaYQGoH%2F19FbuQCKy9L2kGSEzKHmp1%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;1798&quot; height=&quot;898&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;898&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Level Streaming Volume 추가하는 방법&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p0bJT/dJMcaio4fsl/wzy5KZer8oe6ADrsPhZjr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p0bJT/dJMcaio4fsl/wzy5KZer8oe6ADrsPhZjr1/img.png&quot; data-alt=&quot;LevelStreamingVolume이 추가된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p0bJT/dJMcaio4fsl/wzy5KZer8oe6ADrsPhZjr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp0bJT%2FdJMcaio4fsl%2Fwzy5KZer8oe6ADrsPhZjr1%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;1280&quot; height=&quot;639&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LevelStreamingVolume이 추가된 모습&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2338&quot; data-origin-height=&quot;1115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkgibw/dJMcaa5Dioi/qXUQ5YmCktAEP0HLyhyN11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkgibw/dJMcaa5Dioi/qXUQ5YmCktAEP0HLyhyN11/img.png&quot; data-alt=&quot;LevelStreamingVolume을 적용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkgibw/dJMcaa5Dioi/qXUQ5YmCktAEP0HLyhyN11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkgibw%2FdJMcaa5Dioi%2FqXUQ5YmCktAEP0HLyhyN11%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;2338&quot; height=&quot;1115&quot; data-origin-width=&quot;2338&quot; data-origin-height=&quot;1115&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LevelStreamingVolume을 적용&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260316_175252.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dd7mTb/dJMcaibxGhU/8tZS57kK1qKXJXdFsnsABK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dd7mTb/dJMcaibxGhU/8tZS57kK1qKXJXdFsnsABK/img.gif&quot; data-alt=&quot;Level streaming을 적용한 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dd7mTb/dJMcaibxGhU/8tZS57kK1qKXJXdFsnsABK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dd7mTb/dJMcaibxGhU/8tZS57kK1qKXJXdFsnsABK/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;400&quot; height=&quot;196&quot; data-filename=&quot;KakaoTalk_Recording_20260316_175252.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Level streaming을 적용한 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(Tmi. 블루프린트로 맵을 로드 할때 잊지 말아야 할 것!)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I9QPW/dJMcahjpZyH/A4kgui0CxWPkPYrhUH2al0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I9QPW/dJMcahjpZyH/A4kgui0CxWPkPYrhUH2al0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I9QPW/dJMcahjpZyH/A4kgui0CxWPkPYrhUH2al0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI9QPW%2FdJMcahjpZyH%2FA4kgui0CxWPkPYrhUH2al0%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;964&quot; height=&quot;506&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(Tmi+. 그림자가 이상하게 남겨질때 virtual shadow -&amp;gt; shadow map으로 변경하면 해결!)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1996&quot; data-origin-height=&quot;1150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWdG7k/dJMcahcBVp3/C6bl8vx1XozSHeLjRTyjg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWdG7k/dJMcahcBVp3/C6bl8vx1XozSHeLjRTyjg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWdG7k/dJMcahcBVp3/C6bl8vx1XozSHeLjRTyjg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWdG7k%2FdJMcahcBVp3%2FC6bl8vx1XozSHeLjRTyjg1%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;1996&quot; height=&quot;1150&quot; data-origin-width=&quot;1996&quot; data-origin-height=&quot;1150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Unreal Project/Blueprint</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/89</guid>
      <comments>https://seonhwan2547.tistory.com/89#entry89comment</comments>
      <pubDate>Mon, 16 Mar 2026 12:48:20 +0900</pubDate>
    </item>
    <item>
      <title>Blueprint 공부 일기 1 ( 오브젝트 생성 및 충돌 상호작용 )</title>
      <link>https://seonhwan2547.tistory.com/87</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Level에 Object를 생성 및 Blueprint란? &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Blueprint란?&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 언리얼 엔진에서 제공하는 비주얼 스크립팅 시스템으로, 노드를 연결해 로직을 구현하는 &lt;b&gt;클래스 기반 시스템&lt;/b&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; C++ 코드를 작성하지 않고도 &lt;b&gt;게임 로직, 이벤트, 동작 등을 구현&lt;/b&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;Object를 Level에 생성하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이번 과정에서는 블루프린트만 이용해서 오브젝트를 레벨에 배치 해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1407&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdIeL0/dJMcagShXpc/bUngvpV6skZfeHQIFdVGWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdIeL0/dJMcagShXpc/bUngvpV6skZfeHQIFdVGWk/img.png&quot; data-alt=&quot;Blueprint 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdIeL0/dJMcagShXpc/bUngvpV6skZfeHQIFdVGWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdIeL0%2FdJMcagShXpc%2FbUngvpV6skZfeHQIFdVGWk%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;1407&quot; height=&quot;738&quot; data-origin-width=&quot;1407&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blueprint 생성&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;621&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caI9gH/dJMcadHYv0M/DlNLVVG92vXdEK1j0RHHK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caI9gH/dJMcadHYv0M/DlNLVVG92vXdEK1j0RHHK0/img.png&quot; data-alt=&quot;parent class를 actor로 지정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caI9gH/dJMcadHYv0M/DlNLVVG92vXdEK1j0RHHK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaI9gH%2FdJMcadHYv0M%2FDlNLVVG92vXdEK1j0RHHK0%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;928&quot; height=&quot;621&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;621&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;parent class를 actor로 지정&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;Actor로 지정한 이유는 움직이지 않을 고정 객체이며 controller를 이용하지 않을 객체이기 때문입니다.&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;생성하고 클릭하여 blueprint editor 창을 활성화 시킵니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2475&quot; data-origin-height=&quot;1255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tky4M/dJMcagdGOpa/qb4V8jrFAjqo05zhMxXTy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tky4M/dJMcagdGOpa/qb4V8jrFAjqo05zhMxXTy0/img.png&quot; data-alt=&quot;editor 창 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tky4M/dJMcagdGOpa/qb4V8jrFAjqo05zhMxXTy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTky4M%2FdJMcagdGOpa%2Fqb4V8jrFAjqo05zhMxXTy0%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;2475&quot; height=&quot;1255&quot; data-origin-width=&quot;2475&quot; data-origin-height=&quot;1255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;editor 창 화면&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;왼쪽 Component 부분부터 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DefaultSceneRoot : 최상위 노드인 루트 노드로 빈 루트 컴포턴트입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 오브젝트와 플레이어가 상호작용하기 위해 Collider Component로&amp;nbsp; Box Collider와 해당 Collider의 위치를 표현해줄&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cube Box를 추가해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가 방법은 간단히 왼쪽 상단 위 &quot;Add&quot; 버튼을 클릭후 추가해주시면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2490&quot; data-origin-height=&quot;990&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/516yV/dJMcaflxnEB/OZQNyO002PjW8syCktBrx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/516yV/dJMcaflxnEB/OZQNyO002PjW8syCktBrx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/516yV/dJMcaflxnEB/OZQNyO002PjW8syCktBrx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F516yV%2FdJMcaflxnEB%2FOZQNyO002PjW8syCktBrx0%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;2490&quot; height=&quot;990&quot; data-origin-width=&quot;2490&quot; data-origin-height=&quot;990&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 진행되며&amp;nbsp; Compile 후 이제 게임 로직을 다루기 위해 EventGrpah를 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1719&quot; data-origin-height=&quot;1013&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0UrJr/dJMcabwEERL/rkNfCcoUGSESsKKIrhdWO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0UrJr/dJMcabwEERL/rkNfCcoUGSESsKKIrhdWO1/img.png&quot; data-alt=&quot;event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0UrJr/dJMcabwEERL/rkNfCcoUGSESsKKIrhdWO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0UrJr%2FdJMcabwEERL%2FrkNfCcoUGSESsKKIrhdWO1%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;1719&quot; height=&quot;1013&quot; data-origin-width=&quot;1719&quot; data-origin-height=&quot;1013&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;event Graph&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;Event Graph에 있는 내용을 살펴보겠습니다.&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;Event BeginPlay : 오브젝트가 생성되고 나서 게임로직이 실행되기 전에 최초 1번 실행되는 이벤트 입니다&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;Event ActorBeginOverlap: 오브젝트의 Collider가 플레이어와 겹칠 때 최초 1번 발생하는 이벤트 입니다.&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;Event Tick: 매 프레임의 Tick마다 호출되는 이벤트 입니다.&amp;nbsp;&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;여기서 우리는 Overlap을 이용해 간단히 Debug로 게임 실행 viewport에 메세지를 띄어 상호작용을 확인해보고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1725&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4MGGC/dJMcaaYOMz9/CiQkO27KdQzhcSBC7QV5a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4MGGC/dJMcaaYOMz9/CiQkO27KdQzhcSBC7QV5a0/img.png&quot; data-alt=&quot;print string을 이용한 디버깅&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4MGGC/dJMcaaYOMz9/CiQkO27KdQzhcSBC7QV5a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4MGGC%2FdJMcaaYOMz9%2FCiQkO27KdQzhcSBC7QV5a0%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;1725&quot; height=&quot;865&quot; data-origin-width=&quot;1725&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;print string을 이용한 디버깅&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;언리얼에는 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;&lt;b&gt;-&lt;/b&gt; &lt;b&gt;Name&lt;/b&gt; &lt;b&gt;: 해시(Hash)기반 구조로 관리&lt;/b&gt;되는 타입으로, 이미 로드된 리소스나 객체의 이름을 빠르게 비교하교 참조하기 위해 사용됩니다. 내부적으로 해시 알고리즘을 사용하기 때문에 평균적으로 O(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;- String :&lt;/b&gt;&amp;nbsp; 일반적인 문자열 데이터를 저장하기 위한 타입으로, 문자열의 생성, 수정, 가공 등에 주로 사용됩니다.&lt;b&gt;텍스트 처리나 데이터 저장과 같은 일반적인 문자열 작업&lt;/b&gt;에 적합한 타입입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Text&amp;nbsp; &amp;nbsp; : &lt;/b&gt;&lt;b&gt;사용자에게 표시되는 UI 문자열&lt;/b&gt;을 위한 타입입니다. 다국어를 지원하며, 게임 내 표시되는 텍스트나 UI 문구와 같이 &lt;b&gt;번역이 필요한 문자열을 처리할 때 사용&lt;/b&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 간단히 디버깅용으로 문자를 띄울 것이므로 String 자료형을 사용하겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWNe9/dJMcahczHoq/jDGQxK07ftGyVkgHDakCFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWNe9/dJMcahczHoq/jDGQxK07ftGyVkgHDakCFk/img.png&quot; data-alt=&quot;Collision 된 상황&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWNe9/dJMcahczHoq/jDGQxK07ftGyVkgHDakCFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWNe9%2FdJMcahczHoq%2FjDGQxK07ftGyVkgHDakCFk%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;1371&quot; height=&quot;766&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Collision 된 상황&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;사진의 왼쪽 상단 위에 &quot;Collision Enter&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 충돌함으로써 Box에 색깔이 변하고 다시 충돌이 해제되면 원래 색으로 돌아가도록 만들어 보겠습니다.&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;그렇게 하기위해선 일단 해당 박스 Material 부분을 생성해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2439&quot; data-origin-height=&quot;925&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CAkDT/dJMcaflxqvL/1kH9MkExJBinwjlvVY4SNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CAkDT/dJMcaflxqvL/1kH9MkExJBinwjlvVY4SNK/img.png&quot; data-alt=&quot;material&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CAkDT/dJMcaflxqvL/1kH9MkExJBinwjlvVY4SNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCAkDT%2FdJMcaflxqvL%2F1kH9MkExJBinwjlvVY4SNK%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;2439&quot; height=&quot;925&quot; data-origin-width=&quot;2439&quot; data-origin-height=&quot;925&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;material&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;여기서 해당 Constant 노드는 &lt;b&gt;&quot; 마우스&amp;nbsp; LButton +&amp;nbsp; 3 &quot;&amp;nbsp;&lt;/b&gt; 단축키를 통해 간단히 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단일 vector value는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&quot; 마우스&amp;nbsp; LButton +&amp;nbsp; 1 &quot; &lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp; , Lerp 도드는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&quot; 마우스&amp;nbsp; LButton +&amp;nbsp; L &quot;&lt;/b&gt; 으로 만들 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;Lerp 노드는 A의 값에 따라 &lt;/span&gt;&lt;/span&gt;&lt;/span&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;481&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vf7ug/dJMcagLwWJu/P8t9JkCEkLqC131jIBttok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vf7ug/dJMcagLwWJu/P8t9JkCEkLqC131jIBttok/img.png&quot; data-alt=&quot;Lerp 계산식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vf7ug/dJMcagLwWJu/P8t9JkCEkLqC131jIBttok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvf7ug%2FdJMcagLwWJu%2FP8t9JkCEkLqC131jIBttok%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;481&quot; height=&quot;59&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lerp 계산식&lt;/figcaption&gt;
&lt;/figure&gt;
&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;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;다음과 같이 결과를 Base Color ( = Diffuse Color) 로 나타냅니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 충돌하기전의 색깔은 &quot;빨간색&quot; 충돌한 후에는 &quot;파란색&quot;으로 나타낼 결과를 만들 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nt60I/dJMcabKezno/DnaWOD6chAIFpzbmIHLZak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nt60I/dJMcabKezno/DnaWOD6chAIFpzbmIHLZak/img.png&quot; data-alt=&quot;Box Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nt60I/dJMcabKezno/DnaWOD6chAIFpzbmIHLZak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnt60I%2FdJMcabKezno%2FDnaWOD6chAIFpzbmIHLZak%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;1360&quot; height=&quot;841&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Box Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 Set Scalar Parameter Value 노드를 추가합니다. ( alpha 는 값이 1개이므로 Sclar로 합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 &quot;Parameter Name&quot;은 반드시 Material에서 설정한 alpha 노드의 변수명과 똑같게 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;충돌을 한다면 &quot;Parameter Value&quot;가 1이 되도록 해당 값을 1로 작성합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260313_174026.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BEiEo/dJMb99S88ca/jRDOmlDXA9gObkPiHNX2Xk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BEiEo/dJMb99S88ca/jRDOmlDXA9gObkPiHNX2Xk/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BEiEo/dJMb99S88ca/jRDOmlDXA9gObkPiHNX2Xk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/BEiEo/dJMb99S88ca/jRDOmlDXA9gObkPiHNX2Xk/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;400&quot; height=&quot;220&quot; data-filename=&quot;KakaoTalk_Recording_20260313_174026.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;845&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVPTAz/dJMcajamfYD/19Yk93m99Cl6kZP7EBWwjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVPTAz/dJMcajamfYD/19Yk93m99Cl6kZP7EBWwjk/img.png&quot; data-alt=&quot;event graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVPTAz/dJMcajamfYD/19Yk93m99Cl6kZP7EBWwjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVPTAz%2FdJMcajamfYD%2F19Yk93m99Cl6kZP7EBWwjk%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;1347&quot; height=&quot;845&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;845&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;event graph&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;여기서는 이제 Event ActorEndOverlap Event 노드를 추가해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 노드는 해당 오브젝트와 플레이어가 Overlap 겹침이 해제될 때 호출되는 이벤트입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260313_174754.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGk55t/dJMcadOJdzX/7KGa2oimPDU0pNzq855CI0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGk55t/dJMcadOJdzX/7KGa2oimPDU0pNzq855CI0/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGk55t/dJMcadOJdzX/7KGa2oimPDU0pNzq855CI0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bGk55t/dJMcadOJdzX/7KGa2oimPDU0pNzq855CI0/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;400&quot; height=&quot;218&quot; data-filename=&quot;KakaoTalk_Recording_20260313_174754.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9MvIR/dJMcaaR5vj4/cx9vGm2NkStiOt9eOZBXD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9MvIR/dJMcaaR5vj4/cx9vGm2NkStiOt9eOZBXD0/img.png&quot; data-alt=&quot;Obejct Punch Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9MvIR/dJMcaaR5vj4/cx9vGm2NkStiOt9eOZBXD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9MvIR%2FdJMcaaR5vj4%2Fcx9vGm2NkStiOt9eOZBXD0%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;1622&quot; height=&quot;635&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;635&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Obejct Punch Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이전에 만든 박스 오브젝트를 복사하여 새로 추가한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름을 BP_Punch로 바꾸고 Blueprint Event Grpah로 들어가 로직을 변경한다.&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;(Tmi 1: 노드를 끊을 때는 &quot;alt&quot;로 연결을 끊을 수 있다는 것을 알면 편하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Tmi 2: 어떠한 노드의 그룹인지 표시하고 싶으면 해당 노드들을 연속적으로 클릭 후 &quot;C&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;플레이어의 움직임을 제어해야 하므로 Cast 노드를 추가하여 Character로 casting한 후 노드 줄 뽑은 상태에서 Add Impulse를 추가하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1623&quot; data-origin-height=&quot;979&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P7hlA/dJMcach3cjL/XZ71VsgPuIntUrmj213NUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P7hlA/dJMcach3cjL/XZ71VsgPuIntUrmj213NUk/img.png&quot; data-alt=&quot;다음과 같이 노드 이은 상태에서 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P7hlA/dJMcach3cjL/XZ71VsgPuIntUrmj213NUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP7hlA%2FdJMcach3cjL%2FXZ71VsgPuIntUrmj213NUk%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;1623&quot; height=&quot;979&quot; data-origin-width=&quot;1623&quot; data-origin-height=&quot;979&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;/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;그 후 impulse 부분에 어떤 방향으로 플레이어를 날릴 지 sclar 값을 적어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잊지 말아야 할 것이 Vecloity Change를 체크 할 것! ( 질량을 무시안하면 땅에 그대로 있기 때문에 즉시 질량을 무시하고 속도에 영향을 받게 하기 위해서)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260313_181339.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQss5G/dJMb99ZW3TK/TmS1XDSc8cpFVVKCXaIGKk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQss5G/dJMb99ZW3TK/TmS1XDSc8cpFVVKCXaIGKk/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQss5G/dJMb99ZW3TK/TmS1XDSc8cpFVVKCXaIGKk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bQss5G/dJMb99ZW3TK/TmS1XDSc8cpFVVKCXaIGKk/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;400&quot; height=&quot;218&quot; data-filename=&quot;KakaoTalk_Recording_20260313_181339.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;711&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/msVhR/dJMcajamjY5/nofgZwKUWPafi6JzWNZVwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/msVhR/dJMcajamjY5/nofgZwKUWPafi6JzWNZVwk/img.png&quot; data-alt=&quot;Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/msVhR/dJMcajamjY5/nofgZwKUWPafi6JzWNZVwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmsVhR%2FdJMcajamjY5%2FnofgZwKUWPafi6JzWNZVwk%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;1683&quot; height=&quot;711&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;711&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Event Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이펙트가 나오게 하기 위해서 &quot;Spawn Emitter at Location&quot; 노드를 추가하고, 이펙트가 나올 장소를 Get Actor Location 노드를 추가함으로 써 위치를 지정해 줍니다.&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;그 후 Destroy Actor 노드를 통해 해당 오브젝트를 삭제합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Recording_20260313_182345.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dx4iS6/dJMcacCmdNp/b0ezoGPxzNy41OqOGzUK11/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dx4iS6/dJMcacCmdNp/b0ezoGPxzNy41OqOGzUK11/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dx4iS6/dJMcacCmdNp/b0ezoGPxzNy41OqOGzUK11/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dx4iS6/dJMcacCmdNp/b0ezoGPxzNy41OqOGzUK11/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;400&quot; height=&quot;218&quot; data-filename=&quot;KakaoTalk_Recording_20260313_182345.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;다음은 이전에 만들었던 Object에 겹칠 때 해당 박스가 서서히 색을 변경되도록 만들어 보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1jruy/dJMcaakfQFc/co5izomNkaeLI8q9HrhjAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1jruy/dJMcaakfQFc/co5izomNkaeLI8q9HrhjAk/img.png&quot; data-alt=&quot;AlphaToOne Event Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1jruy/dJMcaakfQFc/co5izomNkaeLI8q9HrhjAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1jruy%2FdJMcaakfQFc%2Fco5izomNkaeLI8q9HrhjAk%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;1253&quot; height=&quot;950&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AlphaToOne Event Graph&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;알파값을 서서히 변화시키기 위해서는 AlphaToOne의 노드가 추가되어야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 노드를 살펴보면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCdjel/dJMcacvCWC1/h39kadMjxJ7kcKkNsg6Y3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCdjel/dJMcacvCWC1/h39kadMjxJ7kcKkNsg6Y3k/img.png&quot; data-alt=&quot;AlphaToOne Node&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCdjel/dJMcacvCWC1/h39kadMjxJ7kcKkNsg6Y3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCdjel%2FdJMcacvCWC1%2Fh39kadMjxJ7kcKkNsg6Y3k%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;1722&quot; height=&quot;678&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AlphaToOne Node&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과&amp;nbsp; 같이 해당 값의 변화량을 조절할 수 있는 창이 나오며 &quot;Linear, Constant&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;다음은 teleport를 구현해보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdaWsM/dJMcaf6U1Mk/BqKnxwJx4JhdEk8ccHxktk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdaWsM/dJMcaf6U1Mk/BqKnxwJx4JhdEk8ccHxktk/img.png&quot; data-alt=&quot;Teleport Node&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdaWsM/dJMcaf6U1Mk/BqKnxwJx4JhdEk8ccHxktk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdaWsM%2FdJMcaf6U1Mk%2FBqKnxwJx4JhdEk8ccHxktk%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;1247&quot; height=&quot;752&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Teleport Node&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;다음과 같이 Teleport Node를 설정해주고 해당 텔레포트 할 위치에 플레이어를 어떤 회전량과 위치를 두고 설정할 지 노드를 연결해주면 된다.&lt;/p&gt;</description>
      <category>Unreal Project/Blueprint</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/87</guid>
      <comments>https://seonhwan2547.tistory.com/87#entry87comment</comments>
      <pubDate>Fri, 13 Mar 2026 18:28:27 +0900</pubDate>
    </item>
    <item>
      <title>Data_Asset 및 Quater View, Shoulder View 구현</title>
      <link>https://seonhwan2547.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Data Asset이란?&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data Asset은 게임 로직과 데이터를 분리하기 위해 사용하는 데이터 전용 객체입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Data Asset 생성 방법&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;669&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kSzKW/dJMcacWtuwi/pkkPckgf8csTJ3vo04Fflk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kSzKW/dJMcacWtuwi/pkkPckgf8csTJ3vo04Fflk/img.png&quot; data-alt=&quot;Data Asset 생성 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kSzKW/dJMcacWtuwi/pkkPckgf8csTJ3vo04Fflk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkSzKW%2FdJMcacWtuwi%2FpkkPckgf8csTJ3vo04Fflk%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;954&quot; height=&quot;669&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;669&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Data Asset 생성 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음과 같이 Data Asset을 생성할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Data Asset이 필요한 이유&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1901&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWjhsm/dJMcaaj44hY/kKklk44ciNwXJmiUqS3U90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWjhsm/dJMcaaj44hY/kKklk44ciNwXJmiUqS3U90/img.png&quot; data-alt=&quot;Character BluePrint&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWjhsm/dJMcaaj44hY/kKklk44ciNwXJmiUqS3U90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWjhsm%2FdJMcaaj44hY%2FkKklk44ciNwXJmiUqS3U90%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;1901&quot; height=&quot;581&quot; data-origin-width=&quot;1901&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Character BluePrint&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;Character BluePrint의 오른쪽 Details 패널에서는 다양한 속성 값을 직접 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 모든 값을 블루프린트에 의존하기보다는, C++ 기반 Data Asset을 통해 필요한 데이터만 분리하여 관리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 데이터와 로직을 분리하고 보다 구조적으로 속성 값을 관리할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; data-alt=&quot;c++로 만든 Shoulder View Data Asset&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyq7ti%2FdJMcadOzDCI%2F9QNqWlFNxDBaI75SGFJYyK%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;1051&quot; height=&quot;611&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;c++로 만든 Shoulder View Data Asset&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;Use Controller Rotation Yaw&lt;/b&gt; : 카메라의 좌우 방향에 맞춰 캐릭터도 함께 회전할 지를 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Orient Rotation Movement&lt;/b&gt; : 캐릭터가 입력방향을 바라보도록 자동 회전 시키는 옵션&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Rotation Rate&lt;/b&gt; : 회전 속도&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Target Arm Length&lt;/b&gt; : 카메라 암과 캐릭터 사이의 거리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Releative Rotation&lt;/b&gt; : 카메라가 플레이어를 향해 몇도 기울어져서 바라볼 것인지를 결정&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;Use Pawn Control Rotation&lt;/b&gt;&amp;nbsp; : Pawn 안에 있는 특정 컴포넌트 (SpringArm, Camera 등)가 Pawn의 ControlRotation(= Controller의 회전값)을 사용할 지 정하는 옵션.&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;Do collision Test : &lt;/b&gt;SpringArm이 카메라와 Pawn 사이에 장애물이 있으면 카메라를 앞으로 당겨주는 기능.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772084685897&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include &quot;CoreMinimal.h&quot;
#include &quot;Engine/DataAsset.h&quot;
#include &quot;ABCharacterControlData.generated.h&quot;

/**
 * 
 */
UCLASS()
class RESTUDY_API UABCharacterControlData : public UPrimaryDataAsset
{
	GENERATED_BODY()

public:
	UABCharacterControlData();

	UPROPERTY(EditAnywhere, Category = Pawn)
	bool bUseControllerRotationYaw = false; // Control Rotation의 Yaw값만 체크할지 안할지


	UPROPERTY(EditAnywhere, Category = CharacterMovement)
	bool bOrientRotationMovement = false;

	UPROPERTY(EditAnywhere, Category = CharacterMovement)
	bool bUseControllerDesiredRotation = true;

	UPROPERTY(EditAnywhere, Category = CharacterMovement)
	FRotator RotationRate;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
	TObjectPtr&amp;lt;class UInputMappingContext&amp;gt; InputMappingContext; 

	UPROPERTY(EditAnywhere, Category = SpringArm)
	float TargetArmLength;

	UPROPERTY(EditAnywhere, Category = SpringArm)
	FRotator RelativeRotation; 

	UPROPERTY(EditAnywhere, Category = SpringArm)
	bool bUsePawnControlRotation = false; 

	UPROPERTY(EditAnywhere, Category = SpringArm)
	bool bInheritPitch = false;
	
	UPROPERTY(EditAnywhere, Category = SpringArm)
	bool bInheritYaw = false; 

	UPROPERTY(EditAnywhere, Category = SpringArm)
	bool bInheritRoll = false;

	UPROPERTY(EditAnywhere, Category = SpringArm)
	bool bDoCollisionTest = false; 
	
};&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Quater View란?&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; 캐릭터를 대각선 위쪽에서 내려다보는 시점을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CY3gL/dJMcaaqQyzz/WTi4fqfZxvcFPMVsgDeFmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CY3gL/dJMcaaqQyzz/WTi4fqfZxvcFPMVsgDeFmK/img.png&quot; data-alt=&quot;QuterView의 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CY3gL/dJMcaaqQyzz/WTi4fqfZxvcFPMVsgDeFmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCY3gL%2FdJMcaaqQyzz%2FWTi4fqfZxvcFPMVsgDeFmK%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;1004&quot; height=&quot;467&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;QuterView의 모습&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;Quter View를 만들기 위해서는 다음과 같은 옵션 설정이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; Camera는 플레이어를 45&amp;ordm; ~ 50&amp;ordm; 사이의 각도로 기울여진 각도에서 내려다보도록 배치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; 플레이어와의 거리를 확보하기 위해 Camera Boom(SpringArm)의 길이를 충분히 길게 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; 카메라의 Look(회전)은 플레이어 입력에 따라 조작되지 않도록 하여, 고정된 시점(Fixed View)을 유지합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by8NUT/dJMcahXNMaS/jSW9nhMaXFbkS7rwjTv9t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by8NUT/dJMcahXNMaS/jSW9nhMaXFbkS7rwjTv9t0/img.png&quot; data-alt=&quot;QuaterView Data Asset&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by8NUT/dJMcahXNMaS/jSW9nhMaXFbkS7rwjTv9t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby8NUT%2FdJMcahXNMaS%2FjSW9nhMaXFbkS7rwjTv9t0%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;1046&quot; height=&quot;613&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;QuaterView Data Asset&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Shoulder View란?&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 플레이어의 어깨 뒤쪽에서 캐릭터를 따라가며 바라보는 3인칭 시점 카메라 구조&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xAGux/dJMcac9Ykvt/URRSUd0rPvjWBLHaPMkdn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xAGux/dJMcac9Ykvt/URRSUd0rPvjWBLHaPMkdn1/img.png&quot; data-alt=&quot;Sholuder View 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xAGux/dJMcac9Ykvt/URRSUd0rPvjWBLHaPMkdn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxAGux%2FdJMcac9Ykvt%2FURRSUd0rPvjWBLHaPMkdn1%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;968&quot; height=&quot;420&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Sholuder View 모습&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Shoulder View 를 만들기 위해서는 다음과 같은 옵션 설정이 필요합니다.&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;-&amp;nbsp; 플레이어와의 거리를 확보하기 위해 Camera Boom(SpringArm)의 길이를 충분히 길게 설정합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp; 카메라의 Look(회전)은 플레이어의 전방(Forward) 방향을 결정하는 기준이 되며, 입력에 따라 카메라가 회전하고,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;그 방향을 기준으로 캐릭터가 움직이도록 구성한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; data-alt=&quot;Shoulder View Data Asset&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byq7ti/dJMcadOzDCI/9QNqWlFNxDBaI75SGFJYyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyq7ti%2FdJMcadOzDCI%2F9QNqWlFNxDBaI75SGFJYyK%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;1051&quot; height=&quot;611&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Shoulder View Data Asset&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 데이터셋을 Input Mapping에 연동하여 카메라 시점 변환 구현&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772085985353&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Fill out your copyright notice in the Description page of Project Settings.


#include &quot;Character/ABCharacterPlayer.h&quot;
#include &quot;Camera/CameraComponent.h&quot;
#include &quot;GameFramework/SpringArmComponent.h&quot;
#include &quot;InputMappingContext.h&quot;
#include &quot;EnhancedInputComponent.h&quot;
#include &quot;EnhancedInputSubsystems.h&quot;
#include &quot;Character/ABCharacterControlData.h&quot;




AABCharacterPlayer::AABCharacterPlayer()
{
	//Camera 
	CameraBoom = CreateDefaultSubobject&amp;lt;USpringArmComponent&amp;gt;(TEXT(&quot;CameraBoom&quot;));
	CameraBoom-&amp;gt;SetupAttachment(RootComponent);
	CameraBoom-&amp;gt;TargetArmLength = 400.0f; 
	CameraBoom-&amp;gt;bUsePawnControlRotation = true; 


	FollowCamera = CreateDefaultSubobject&amp;lt;UCameraComponent&amp;gt;(TEXT(&quot;FollowCamera&quot;));
	FollowCamera-&amp;gt;SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
	FollowCamera-&amp;gt;bUsePawnControlRotation = false; 

	//Input
	//static ConstructorHelpers::FObjectFinder&amp;lt;UInputMappingContext&amp;gt; InputMappingContextRef(TEXT(&quot;/Game/Input/IMC_Default.IMC_Default&quot;));
	//
	//if(InputMappingContextRef.Object)
	//{
	//	DefaultMappingContext = InputMappingContextRef.Object;
	//}

	static ConstructorHelpers::FObjectFinder&amp;lt;UInputAction&amp;gt; InputActionJumpRef(TEXT(&quot;/Game/Input/Actions/IA_Jump.IA_Jump&quot;));

	if (InputActionJumpRef.Object)
	{
		JumpAction = InputActionJumpRef.Object;
	}

	
	static ConstructorHelpers::FObjectFinder&amp;lt;UInputAction&amp;gt; InputChnageActionRef(TEXT(&quot;/Game/Input/Actions/IA_ChangeControl.IA_ChangeControl&quot;));
	if(nullptr!= InputChnageActionRef.Object)
	{
		ChangeControlAction = InputChnageActionRef.Object;
	}
	
	
	static ConstructorHelpers::FObjectFinder&amp;lt;UInputAction&amp;gt; InputActionShoulderMoveRef(TEXT(&quot;/Game/Input/Actions/IA_ShoulderMove.IA_ShoulderMove&quot;));
	if (nullptr != InputActionShoulderMoveRef.Object)
	{
		ShoulderMoveAction = InputActionShoulderMoveRef.Object;
	}
	
	
	static ConstructorHelpers::FObjectFinder&amp;lt;UInputAction&amp;gt; InputActionShoulderLookRef(TEXT(&quot;/Game/Input/Actions/IA_ShoulderLook.IA_ShoulderLook&quot;));
	if (nullptr != InputActionShoulderLookRef.Object)
	{
		ShoulderLookAction = InputActionShoulderLookRef.Object;
	}
	
	
	static ConstructorHelpers::FObjectFinder&amp;lt;UInputAction&amp;gt; InputActionQuaterMoveRef(TEXT(&quot;/Game/Input/Actions/IA_QuaterMove.IA_QuaterMove&quot;));
	if (nullptr != InputChnageActionRef.Object)
	{
		QuaterMoveAction = InputActionQuaterMoveRef.Object;
	}

	CurrentCharacterControlType = ECharacterControlType::Quater;


}

void AABCharacterPlayer::BeginPlay()
{
	// 입력 매핑 컨테스트를 할당하는 역할 ( 키보드로 입력받을지,  다른 플랫폼으로 입력받을지등)
	
	Super::BeginPlay();

	SetCharacterControl(CurrentCharacterControlType);

	//APlayerController * PlayerController = CastChecked&amp;lt;APlayerController&amp;gt;(GetController());


	//if (ULocalPlayer* LocalPlayer = PlayerController-&amp;gt;GetLocalPlayer())
	//{
	//	if (UEnhancedInputLocalPlayerSubsystem* SubSystem =
	//		ULocalPlayer::GetSubsystem&amp;lt;UEnhancedInputLocalPlayerSubsystem&amp;gt;(LocalPlayer))
	//	{
	//		SubSystem-&amp;gt;AddMappingContext(DefaultMappingContext, 0);
	//	}
	//}

	





}

void AABCharacterPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	// 언리얼 엔진 입력시스템에서 액션 함수를 매핑시켜주는 곳 

	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputComponent = CastChecked&amp;lt;UEnhancedInputComponent&amp;gt;(PlayerInputComponent);

	EnhancedInputComponent-&amp;gt;BindAction(JumpAction, ETriggerEvent::Triggered, this, &amp;amp;ACharacter::Jump);
	EnhancedInputComponent-&amp;gt;BindAction(JumpAction, ETriggerEvent::Completed, this, &amp;amp;ACharacter::StopJumping);
	EnhancedInputComponent-&amp;gt;BindAction(ChangeControlAction, ETriggerEvent::Triggered, this, &amp;amp;AABCharacterPlayer::ChangeCharacterControl);
	EnhancedInputComponent-&amp;gt;BindAction(ShoulderMoveAction, ETriggerEvent::Triggered, this, &amp;amp;AABCharacterPlayer::ShoulderMove);
	EnhancedInputComponent-&amp;gt;BindAction(ShoulderLookAction, ETriggerEvent::Triggered, this, &amp;amp;AABCharacterPlayer::ShoulderLook);
	EnhancedInputComponent-&amp;gt;BindAction(QuaterMoveAction, ETriggerEvent::Triggered, this, &amp;amp;AABCharacterPlayer::QuaterMove);
	
}

void AABCharacterPlayer::ChangeCharacterControl()
{
	// 누르면 
	if(CurrentCharacterControlType == ECharacterControlType::Quater)
	{
		SetCharacterControl(ECharacterControlType::Shoulder);
	}

	else if (CurrentCharacterControlType == ECharacterControlType::Shoulder)
	{
		SetCharacterControl(ECharacterControlType::Quater);
	}

}

void AABCharacterPlayer::SetCharacterControl(ECharacterControlType NewCharacterControlType)
{
	UABCharacterControlData* NewCharacterControl = CharacterControlManager[NewCharacterControlType];
	check(NewCharacterControl);

	SetCharacterControlData(NewCharacterControl);

	APlayerController* PlayerController = CastChecked&amp;lt;APlayerController&amp;gt;(GetController());

	ULocalPlayer* LocalPlayer = PlayerController-&amp;gt;GetLocalPlayer();


	if(UEnhancedInputLocalPlayerSubsystem* SubSystem = ULocalPlayer::GetSubsystem&amp;lt;UEnhancedInputLocalPlayerSubsystem&amp;gt;(LocalPlayer))
	{
		SubSystem-&amp;gt;ClearAllMappings();
		UInputMappingContext* NewMappingContext = NewCharacterControl-&amp;gt;InputMappingContext; 
		if(NewMappingContext)
		{
			SubSystem-&amp;gt;AddMappingContext(NewMappingContext, 0);
		}
	}

	CurrentCharacterControlType = NewCharacterControlType;

}

void AABCharacterPlayer::SetCharacterControlData(const UABCharacterControlData* CharacterControlData)
{
	Super::SetCharacterControlData(CharacterControlData);

	CameraBoom-&amp;gt;TargetArmLength = CharacterControlData-&amp;gt;TargetArmLength;
	CameraBoom-&amp;gt;SetRelativeRotation(CharacterControlData-&amp;gt;RelativeRotation);
	CameraBoom-&amp;gt;bUsePawnControlRotation = CharacterControlData-&amp;gt;bUsePawnControlRotation;
	CameraBoom-&amp;gt;bInheritPitch = CharacterControlData-&amp;gt;bInheritPitch;
	CameraBoom-&amp;gt;bInheritYaw = CharacterControlData-&amp;gt;bInheritYaw;
	CameraBoom-&amp;gt;bInheritRoll = CharacterControlData-&amp;gt;bInheritRoll;
	CameraBoom-&amp;gt;bDoCollisionTest = CharacterControlData-&amp;gt;bDoCollisionTest;

}

void AABCharacterPlayer::ShoulderMove(const FInputActionValue&amp;amp; Value)
{
	FVector2D MovementVector = Value.Get&amp;lt;FVector2D&amp;gt;(); 
	
	const FRotator Rotation = Controller-&amp;gt;GetControlRotation();
	const FRotator YawRotation(0, Rotation.Yaw, 0);


	const FVector FowardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);	
	const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);	

	

	AddMovementInput(FowardDirection, MovementVector.X);	
	AddMovementInput(RightDirection, MovementVector.Y);	
}

void AABCharacterPlayer::ShoulderLook(const FInputActionValue&amp;amp; Value)
{
	FVector2D LookAxisVector = Value.Get&amp;lt;FVector2D&amp;gt;(); 
	
	AddControllerYawInput(LookAxisVector.X);
	AddControllerPitchInput(LookAxisVector.Y);
	
}


void AABCharacterPlayer::QuaterMove(const FInputActionValue&amp;amp; Value)
{
	FVector2D MovementVector = Value.Get&amp;lt;FVector2D&amp;gt;();

	float InputSizeSquared = MovementVector.SquaredLength();
	float MovementVectorSize = 1.0f; 
	float MovementVectorSizeSquared = MovementVector.SquaredLength();

	if (MovementVectorSizeSquared &amp;gt; 1.0f)
	{
		MovementVector.Normalize();
		MovementVectorSizeSquared = 1.0f; 
	}

	else
	{
		MovementVectorSize = FMath::Sqrt(MovementVectorSizeSquared);
	}


	FVector MoveDirection = FVector(MovementVector.X, MovementVector.Y, 0.0f);
	GetController()-&amp;gt;SetControlRotation(FRotationMatrix::MakeFromX(MoveDirection).Rotator());
	AddMovementInput(MoveDirection, MovementVectorSize);


}&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;h4 data-ke-size=&quot;size20&quot;&gt;해당 작업을 진행 중 몰랐던 부분.&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xikhb/dJMcajacERr/p3RLku3j7a6H3aj8gZUdF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xikhb/dJMcajacERr/p3RLku3j7a6H3aj8gZUdF1/img.png&quot; data-alt=&quot;Sholder View 컨트롤러를 구현하던 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xikhb/dJMcajacERr/p3RLku3j7a6H3aj8gZUdF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxikhb%2FdJMcajacERr%2Fp3RLku3j7a6H3aj8gZUdF1%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;1030&quot; height=&quot;480&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Sholder View 컨트롤러를 구현하던 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UInputAction의 Input Value Type을 Vector2D로 설정하면, 입력 값은 (X,Y) 형태로 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, W,A,S,D와 같은 Digital Input(키보드 입력)은 눌렀을 때 1, 눌리지 않았을 때 0을 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 실제 전달되는 값은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;W 입력&amp;nbsp;&amp;rarr; (1,0)&lt;/li&gt;
&lt;li&gt;입력 없음 &amp;rarr;&amp;nbsp; (0,0)&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 Input Mapping에서 해당 키의 Scalar 값을 (0,1,0)으로 설정하면 입력값에 곱해지는 결과가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1 * 0 , 0 * 1 , 0 * 0 ) 이므로 최종 Vector2D 값이 (0,0)이 되면서 ShoulderMove()함수가 호출되지 않는 상황이 발생했다.&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;해당 문제는 Swizzle Modifier를 활용하여 X축으로 들어오는 입력 값을 Y축으로 재매핑하는 방식으로 해결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 (1,0) 입력값이 들어오면 (0,1)로 해주는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구현 결과&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;QutarViewAndShoulderView.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;209&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drL8Me/dJMcadgNmR7/o8cBKX9VGDYu99MB3mNgdk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drL8Me/dJMcadgNmR7/o8cBKX9VGDYu99MB3mNgdk/img.gif&quot; data-alt=&quot;구현 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drL8Me/dJMcadgNmR7/o8cBKX9VGDYu99MB3mNgdk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/drL8Me/dJMcadgNmR7/o8cBKX9VGDYu99MB3mNgdk/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;400&quot; height=&quot;209&quot; data-filename=&quot;QutarViewAndShoulderView.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;209&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구현 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Unreal Project/Unreal Study</category>
      <category>GameProgramming</category>
      <category>Unreal Engine</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/85</guid>
      <comments>https://seonhwan2547.tistory.com/85#entry85comment</comments>
      <pubDate>Thu, 26 Feb 2026 15:20:10 +0900</pubDate>
    </item>
    <item>
      <title>A-star 알고리즘 구현 및 적용</title>
      <link>https://seonhwan2547.tistory.com/84</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;A-Star 알고리즘이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A*&lt;/b&gt;는 시작점에서 목표까지의 최단 경로를 찾기 위해&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;현재까지의 비용(g(n)) + 목표까지의 예상 비용(h(n))&lt;/b&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;g(n) : 시작점에서 현재 노드까지 가는데 드는 비용&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;h(n) : 현재 노드에서 목표 노드까지 가는데 드는 비용&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;f(n) :&amp;nbsp; 총 예상 비용 ( g(n) + f(n) )&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9WQha/dJMcajgWcFC/GZe30mrOGvrZ6kiykBROQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9WQha/dJMcajgWcFC/GZe30mrOGvrZ6kiykBROQ1/img.png&quot; data-alt=&quot;출처 https://recall.tistory.com/40#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9WQha/dJMcajgWcFC/GZe30mrOGvrZ6kiykBROQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9WQha%2FdJMcajgWcFC%2FGZe30mrOGvrZ6kiykBROQ1%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;1050&quot; height=&quot;773&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 https://recall.tistory.com/40#google_vignette&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;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;A-Star 알고리즘 동작 과정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qjyLF/dJMcagkfFfu/AAsardQlw8vlkuhAoGkUH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qjyLF/dJMcagkfFfu/AAsardQlw8vlkuhAoGkUH1/img.png&quot; data-alt=&quot;출처 https://recall.tistory.com/40#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qjyLF/dJMcagkfFfu/AAsardQlw8vlkuhAoGkUH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqjyLF%2FdJMcagkfFfu%2FAAsardQlw8vlkuhAoGkUH1%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;723&quot; height=&quot;710&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 https://recall.tistory.com/40#google_vignette&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;1&lt;/b&gt;. &lt;b&gt;해당 노드 주변의 열린 노드의&lt;/b&gt; &lt;b&gt;g(n), h(n), f(n)&lt;/b&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;- 열린노드(Open Node)는 현재 위치 노드에 인접한 노드들을 의미합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- g(n)의 비용을 구하는 방식은 바로 유클리디안 거리(점과 점사이의 거리)을 사용하여 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- h(n)의 비용을 구하는 방식은 휴리스틱 거리 측정값을 통해 이동 비용을 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;(격자에서는 가로, 세로 Manhattan 거리 방식을 이용하며, 그 외는 점과 점 사이의 거리 공식을 이용해 표현)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- f(n)의 비용&amp;nbsp; = g(n) + h(n) 이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;2. 경로 탐색&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVOWO1/dJMcahwIT0h/XCAsk5ZeYU6gsfw4qTSJY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVOWO1/dJMcahwIT0h/XCAsk5ZeYU6gsfw4qTSJY0/img.png&quot; data-alt=&quot;출처 https://recall.tistory.com/40#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVOWO1/dJMcahwIT0h/XCAsk5ZeYU6gsfw4qTSJY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVOWO1%2FdJMcahwIT0h%2FXCAsk5ZeYU6gsfw4qTSJY0%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;709&quot; height=&quot;710&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 https://recall.tistory.com/40#google_vignette&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;현재 노드의 오픈 노드를 모아둔 오픈 리스트에서 가장 낮은 f(n)을 우선 방문합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;따라서 현재 그림상에서는 오른쪽 대각선 위 f(n) = 44인 노드를 방문합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;방문한 후에는 ClosedList에 해당 노드를 넣고 재방문을 하지 않도록 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;(하늘색 윤곽선으로 그려진 노드는 ClosedList에 들어간 것입니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;3. 1,2번 반복 하여 Best_Route 구하기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cipRmk/dJMcagxMgV4/J0KoICbCUMVNvVBguUheU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cipRmk/dJMcagxMgV4/J0KoICbCUMVNvVBguUheU0/img.png&quot; data-alt=&quot;출처 https://recall.tistory.com/40#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cipRmk/dJMcagxMgV4/J0KoICbCUMVNvVBguUheU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcipRmk%2FdJMcagxMgV4%2FJ0KoICbCUMVNvVBguUheU0%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;705&quot; height=&quot;706&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 https://recall.tistory.com/40#google_vignette&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;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;A*가 왜 최적의 루트를 제공하는가?&amp;nbsp;&lt;/h3&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;이거 BFS와 마찬가지고 queue를 이용하여 모든 경로를 다 탐색하는거 아니야? 라는 생각을 처음에는 가졌습니다.&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;하지만 A* 알고리즘과 BFS의 탐색범위에 차이가 있습니다.&lt;/p&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/b6tVDt/dJMcaaK7h5M/ackVDZVBMAe48KsF68zd70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6tVDt/dJMcaaK7h5M/ackVDZVBMAe48KsF68zd70/img.png&quot; width=&quot;466&quot; height=&quot;273&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;670&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;49.85&quot; style=&quot;width: 49.2668%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6tVDt/dJMcaaK7h5M/ackVDZVBMAe48KsF68zd70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6tVDt%2FdJMcaaK7h5M%2FackVDZVBMAe48KsF68zd70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1144&quot; height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCbvPE/dJMcabDgJ5C/Wpm0uJ5alhMyKNKcXQUSuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCbvPE/dJMcabDgJ5C/Wpm0uJ5alhMyKNKcXQUSuK/img.png&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;656&quot; data-is-animation=&quot;false&quot; width=&quot;422&quot; height=&quot;246&quot; style=&quot;width: 49.5704%;&quot; data-widthpercent=&quot;50.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCbvPE/dJMcabDgJ5C/Wpm0uJ5alhMyKNKcXQUSuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCbvPE%2FdJMcabDgJ5C%2FWpm0uJ5alhMyKNKcXQUSuK%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;1127&quot; height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;BFS 알고리즘 탐색 범위 vs A* 알고리즘 탐색 범위&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A* 알고리즘은 무작정 모든 방향을 탐색하는 것이 아니라, 목표 지점에 더 가까워 보이는 노드를 우선적으로 확장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탐색 도중 장애물을 만나거나 비효율적인 경로임이 판단되면, Open list에 저장된 다른 후보 노드를 선택해 탐색을 이어갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식 덕분에 BFS보다 불필요한 탐색을 줄이고, 더 빠르게 최적 경로를 찾을 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드 구현&lt;/h3&gt;
&lt;pre id=&quot;code_1771917682041&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bool CNavigation::Make_Route(int iStartIndex, int iGoalIndex)
{
	priority_queue&amp;lt;NodeInfo, vector&amp;lt;NodeInfo&amp;gt;,PQCompare&amp;gt; OpenQueue;

	NodeInfo node;

	node.index = iStartIndex; 
	node.g_Cost.x = 0;
	node.g_Cost.y = 0;
	node.Cost = 0; 

	OpenQueue.push(node);
	
	m_ClosedList.clear();
	
	
	while(!OpenQueue.empty())
	{
		// 여기서 계산하고 맨 위에거 가져온거 
		int CurIndex = OpenQueue.top().index;
		int Cur_gCoost_x = OpenQueue.top().g_Cost.x;
		int Cur_gCoost_y = OpenQueue.top().g_Cost.y;

		OpenQueue.pop();


		if (CheckClose(CurIndex))
			continue;

		if (CurIndex == iGoalIndex)
			return true; 
			

		m_ClosedList.push_back(CurIndex);	

		//여기서 이제 다시 오픈리스트에 넣고 계산하기 
		for (auto&amp;amp; pCell : m_vecCellAbj[CurIndex])
		{
			if (!CheckClose(pCell-&amp;gt;Get_Index()) &amp;amp;&amp;amp; pCell-&amp;gt;Get_Option() != 1) // 장애물 체크 
			{


				//여기서 계산하기 (나중에 함수화하기) 
				int gCost_x = abs(m_vecCell[CurIndex]-&amp;gt;Get_Position().x - pCell-&amp;gt;Get_Position().x) + Cur_gCoost_x;
				int gCost_y = abs(m_vecCell[CurIndex]-&amp;gt;Get_Position().y - pCell-&amp;gt;Get_Position().y) + Cur_gCoost_y;

				int hCost_x = abs(m_vecCell[iGoalIndex]-&amp;gt;Get_Position().x - pCell-&amp;gt;Get_Position().x);
				int hCost_y = abs(m_vecCell[iGoalIndex]-&amp;gt;Get_Position().y - pCell-&amp;gt;Get_Position().y);

				// 여기서도 g_value가 더 낮다면을 가정해야함 
				if ((gCost_x + gCost_y) &amp;lt; pCell-&amp;gt;Get_gValue())
				{
					pCell-&amp;gt;Set_ParentIndex(CurIndex);
					pCell-&amp;gt;Set_gValue(gCost_x + gCost_y);

					int fResult = gCost_x + gCost_y + hCost_x + hCost_y;


					NodeInfo node;
					node.index = pCell-&amp;gt;Get_Index();
					node.Cost = fResult;
					node.g_Cost.x = gCost_x;
					node.g_Cost.y = gCost_y;
					
					OpenQueue.push(node);
				}
			}
		}
	}



	return 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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구현 결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;A_star구현.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eBctsY/dJMb99SX89T/SM180s2r843ayIsA3Q1eWk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eBctsY/dJMb99SX89T/SM180s2r843ayIsA3Q1eWk/img.gif&quot; data-alt=&quot;A-star 구현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eBctsY/dJMb99SX89T/SM180s2r843ayIsA3Q1eWk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/eBctsY/dJMb99SX89T/SM180s2r843ayIsA3Q1eWk/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;400&quot; height=&quot;650&quot; data-filename=&quot;A_star구현.gif&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;A-star 구현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Algorithm/A-star</category>
      <author>seonhwan2547</author>
      <guid isPermaLink="true">https://seonhwan2547.tistory.com/84</guid>
      <comments>https://seonhwan2547.tistory.com/84#entry84comment</comments>
      <pubDate>Tue, 24 Feb 2026 16:28:40 +0900</pubDate>
    </item>
  </channel>
</rss>