<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Russell Developer</title>
    <link>https://russellstudio.tistory.com/</link>
    <description>russellstudio 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 20 Jun 2026 09:22:42 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Russell Developer</managingEditor>
    <image>
      <title>Russell Developer</title>
      <url>https://tistory1.daumcdn.net/tistory/7282202/attach/fc33e488a2944b66a55128529d0b4c01</url>
      <link>https://russellstudio.tistory.com</link>
    </image>
    <item>
      <title>Unity 간단한 쉐이더 구현 (물, 불, 빛 효과 등)</title>
      <link>https://russellstudio.tistory.com/153</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 간단한 쉐이더 구현: 물, 불, 빛 효과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉐이더는 게임의 시각적 효과를 크게 향상시킬 수 있는 중요한 요소입니다. Unity에서는 쉐이더를 통해 물의 움직임, 불의 생동감, 빛의 반사를 표현할 수 있습니다. 이번 포스팅에서는 간단한 물, 불, 빛 효과를 구현하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Unity에서 쉐 이더란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉐 이더(Shader)는 그래픽 처리 장치(GPU)에서 실행되는 작은 프로그램으로, 게임 오브젝트의 시각적 표현을 담당합니다.&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;물 효과&lt;/b&gt;: 움직이는 물결, 반사, 굴절.&lt;/li&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;p data-ke-size=&quot;size16&quot;&gt;Unity에서는 &lt;b&gt;Shader Graph&lt;/b&gt;를 사용하거나 HLSL 코드를 직접 작성하여 쉐 이더를 구현할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 물(Water) 효과 쉐이더&lt;/h4&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;물결 애니메이션.&lt;/li&gt;
&lt;li&gt;반사 또는 굴절 효과.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단계별 구현&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;UV 좌표 조작&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;Time 노드&lt;/b&gt;와 &lt;b&gt;Sine 노드&lt;/b&gt;를 사용해 텍스처의 UV 좌표를 움직입니다.&lt;/li&gt;
&lt;li&gt;물결 효과를 위해 UV 좌표를 변경하는 값을 생성합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;Fresnel Effect&lt;/b&gt;를 추가합니다.&lt;/li&gt;
&lt;li&gt;Base Color에 블루 계열의 색상과 Fresnel 값을 곱합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;Reflection Probe&lt;/b&gt;를 사용하거나 텍스처 샘플링을 통해 반사 효과를 추가합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 불(Fire) 효과 쉐이더&lt;/h4&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;화염의 움직임.&lt;/li&gt;
&lt;li&gt;불의 생동감 표현.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단계별 구현&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&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;Noise 노드&lt;/b&gt;를 활용해 화염의 불규칙한 패턴을 만듭니다.&lt;/li&gt;
&lt;li&gt;Time 노드를 활용해 노이즈 텍스처를 애니메이션화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Gradient 색상 적용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불의 색상을 표현하기 위해 Gradient 노드를 사용합니다.&lt;/li&gt;
&lt;li&gt;노란색에서 빨간색으로 점진적으로 변화하도록 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Alpha 조정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불의 가장자리를 부드럽게 표현하기 위해 Alpha 값을 점진적으로 낮춥니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 빛(Light) 효과 쉐이더&lt;/h4&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;빛의 확산 효과.&lt;/li&gt;
&lt;li&gt;표면 반사 표현.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단계별 구현&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Emission 추가&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;Emission Property&lt;/b&gt;를 사용해 빛나는 효과를 만듭니다.&lt;/li&gt;
&lt;li&gt;색상과 Intensity 값을 조정하여 원하는 빛의 강도를 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Bloom 효과 적용&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;Post Processing&lt;/b&gt;에서 Bloom 효과를 활성화해 빛의 확산을 강화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Normal Map 활용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Normal Map을 사용해 빛의 반사와 굴곡을 표현합니다.&lt;/li&gt;
&lt;li&gt;표면의 세부적인 질감을 강조합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. Shader Graph 예제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 1: 움직이는 물결 효과&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Time 노드&lt;/b&gt; &amp;rarr; &lt;b&gt;Sine 노드&lt;/b&gt; &amp;rarr; &lt;b&gt;UV 좌표&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fresnel Effect&lt;/b&gt;를 사용해 반사 표현 추가.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 2: 생동감 있는 불 표현&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;Noise 노드&lt;/b&gt;를 애니메이션화하고, &lt;b&gt;Gradient 색상&lt;/b&gt;으로 불의 색상 변화 표현.&lt;/li&gt;
&lt;li&gt;Alpha 값으로 불의 투명도를 조정.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 3: 빛나는 표면&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;Emission Property&lt;/b&gt;로 빛나는 효과.&lt;/li&gt;
&lt;li&gt;Normal Map과 Bloom 효과를 조합해 자연스러운 빛 반사 구현.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 최적화 팁&lt;/h4&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;Shader Complexity&lt;/b&gt;: 복잡한 쉐이더는 성능에 영향을 줄 수 있으므로 단순화.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Batching 활용&lt;/b&gt;: 쉐이더를 적용한 오브젝트가 많을 경우 Static/Dynamic Batching을 사용하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서 간단한 쉐이더를 구현하는 방법은 생각보다 어렵지 않습니다.&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;Shader Graph&lt;/b&gt;로 쉽게 제작 가능.&lt;/li&gt;
&lt;li&gt;기본 노드 조합만으로도 실감 나는 효과를 구현할 수 있습니다.&lt;/li&gt;
&lt;li&gt;성능을 고려해 최적화를 병행하세요.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>Unity Shader</category>
      <category>unity shader graph</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 쉐이더</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/153</guid>
      <comments>https://russellstudio.tistory.com/153#entry153comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:38:39 +0900</pubDate>
    </item>
    <item>
      <title>Unity Shader Graph 기본 사용법</title>
      <link>https://russellstudio.tistory.com/152</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity Shader Graph 기본 사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Shader Graph&lt;/b&gt;는 Unity에서 &lt;b&gt;비주얼 스크립팅&lt;/b&gt; 방식으로 셰이더를 제작할 수 있는 강력한 도구입니다. 코드 없이도 직관적인 인터페이스를 통해 다양한 셰이더를 제작할 수 있어, 디자이너와 개발자 모두에게 유용합니다. 이번 포스팅에서는 Shader Graph의 기본 사용법과 간단한 셰이더를 만드는 과정을 다룹니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Shader Graph란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Shader Graph&lt;/b&gt;는 Unity에서 제공하는 시각적 셰이더 제작 툴로, 노드 기반 인터페이스를 통해 복잡한 셰이더를 쉽게 제작할 수 있습니다.&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;직관적&lt;/b&gt;: 코드를 작성할 필요 없이 드래그 앤 드롭으로 셰이더 구성 가능.&lt;/li&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Shader Graph 프로젝트 설정&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;SRP 설정&lt;/b&gt;&lt;br /&gt;Shader Graph는 &lt;b&gt;Scriptable Render Pipeline(SRP)&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;URP(Universal Render Pipeline)&lt;/b&gt; 또는 &lt;b&gt;HDRP(High Definition Render Pipeline)&lt;/b&gt;를 사용해야 합니다.&lt;/li&gt;
&lt;li&gt;Unity &lt;b&gt;Package Manager&lt;/b&gt;에서 URP 또는 HDRP 설치.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Shader Graph 설치&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;Window &amp;gt; Package Manager&lt;/b&gt;로 이동.&lt;/li&gt;
&lt;li&gt;Shader Graph 패키지를 검색하고 설치.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 새로운 Shader Graph 만들기&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Shader Graph 생성&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;Project 창&lt;/b&gt;에서 우클릭 &amp;rarr; &lt;b&gt;Create &amp;gt; Shader Graph &amp;gt; PBR Graph&lt;/b&gt; 선택.&lt;/li&gt;
&lt;li&gt;생성된 셰이더 파일의 이름을 지정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Material에 Shader 적용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 Material을 생성하고, Shader Graph에서 생성한 셰이더를 할당합니다.&lt;/li&gt;
&lt;li&gt;Material을 원하는 GameObject에 적용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Shader Graph 열기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Shader 파일을 더블 클릭하면 Shader Graph 에디터가 열립니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. Shader Graph 기본 구성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shader Graph는 크게 세 가지 영역으로 나뉩니다.&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;Main Preview&lt;/b&gt;: 결과를 실시간으로 확인할 수 있는 미리보기 창.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Node Graph&lt;/b&gt;: 셰이더를 구성하는 노드가 배치되는 작업 공간.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Blackboard&lt;/b&gt;: &lt;b&gt;Property&lt;/b&gt;(속성)와 &lt;b&gt;Keyword&lt;/b&gt;를 관리하는 패널.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 간단한 Shader 제작 예제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제: 움직이는 물결 효과&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Property 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Blackboard에서 &lt;b&gt;Vector1 Property&lt;/b&gt;를 추가하고 이름을 Speed로 설정.&lt;/li&gt;
&lt;li&gt;Speed 값을 통해 물결의 움직임 속도를 조절할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;Time 노드&lt;/b&gt;: 시간 값을 가져옵니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Sine 노드&lt;/b&gt;: 시간에 따라 파형을 생성합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UV 노드&lt;/b&gt;: 텍스처의 UV 좌표를 가져옵니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Add 노드&lt;/b&gt;: UV 좌표에 Sine 값을 더합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Color 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Base Color 노드에 텍스처와 함께 곱하여 색상을 조정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;PBR Master&lt;/b&gt; 노드에 연결해 셰이더 완성.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. Shader Graph 활용 팁&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&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;/li&gt;
&lt;li&gt;그룹 노드를 사용해 특정 작업을 묶어 관리하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Property 활용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 Property를 추가해 Material Inspector에서 값을 실시간으로 조정 가능.&lt;/li&gt;
&lt;li&gt;예: 색상, 속도, 강도 등을 Property로 설정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Custom Function 활용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Shader Graph만으로 구현하기 어려운 부분은 &lt;b&gt;HLSL 코드&lt;/b&gt;를 추가할 수 있습니다.&lt;/li&gt;
&lt;li&gt;Custom Function 노드를 통해 고유한 기능을 셰이더에 통합하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. Shader Graph로 제작 가능한 셰이더&lt;/h4&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;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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;8. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shader Graph는 Unity에서 비주얼 방식으로 셰이더를 제작할 수 있는 강력한 도구입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 UI로 다양한 셰이더 효과 구현 가능.&lt;/li&gt;
&lt;li&gt;Property와 노드의 활용으로 유연한 작업 가능.&lt;/li&gt;
&lt;li&gt;최적화된 환경에서 실시간 성능 확인 가능.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>unity shader graph</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 쉐이더 그래프</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/152</guid>
      <comments>https://russellstudio.tistory.com/152#entry152comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:35:49 +0900</pubDate>
    </item>
    <item>
      <title>Unity 프로파일러를 이용한 성능 분석 및 최적화</title>
      <link>https://russellstudio.tistory.com/151</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 프로파일러를 이용한 성능 분석 및 최적화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서의 성능 최적화는 부드러운 게임 플레이를 제공하는 데 필수적입니다. &lt;b&gt;Unity Profiler&lt;/b&gt;는 게임 실행 중 성능 데이터를 시각적으로 보여주는 도구로, 문제를 진단하고 최적화하는 데 유용합니다. 이번 포스팅에서는 Unity Profiler의 사용법과 주요 기능, 최적화 팁을 소개합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Unity Profiler란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Unity Profiler&lt;/b&gt;는 게임의 CPU, GPU, 메모리, 렌더링, 오디오 등 다양한 성능 지표를 실시간으로 측정하고 분석하는 도구입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제를 시각적으로 확인 가능.&lt;/li&gt;
&lt;li&gt;게임의 특정 영역이나 스크립트에서 성능 병목 현상을 찾아냄.&lt;/li&gt;
&lt;li&gt;모바일, PC, 콘솔 등 다양한 플랫폼에서 동작.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Unity Profiler 활성화 방법&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Unity 에디터 상단 메뉴&lt;/b&gt;에서 &lt;b&gt;Window &amp;gt; Analysis &amp;gt; Profiler&lt;/b&gt;를 선택합니다.&lt;/li&gt;
&lt;li&gt;Profiler 창이 열리면 &lt;b&gt;플레이 모드&lt;/b&gt;로 전환해 실시간 데이터를 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;특정 디바이스(예: Android, iOS)에서 테스트하려면 장치를 연결하고 &lt;b&gt;Attach to Player&lt;/b&gt;를 사용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. Profiler의 주요 섹션&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) CPU Usage&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;게임의 CPU 사용량을 보여줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Main Thread&lt;/b&gt;: 주요 게임 로직이 실행되는 부분.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scripts&lt;/b&gt;: 스크립트 실행 시간.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&lt;b&gt;FixedUpdate()&lt;/b&gt;나 &lt;b&gt;Update()&lt;/b&gt;에서 과도한 계산이 발생하는 경우.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Garbage Collection(GC)&lt;/b&gt; 호출 빈도가 높은 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) GPU Usage&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GPU에서 수행되는 작업 시간과 렌더링 상태를 확인.&lt;/li&gt;
&lt;li&gt;Draw Call 수와 쉐이더 실행 시간을 분석.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;복잡한 쉐이더 사용으로 인해 GPU 부하가 높은 경우.&lt;/li&gt;
&lt;li&gt;불필요한 오브젝트가 렌더링에 포함된 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) Memory&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 사용량을 확인하고, 메모리 누수 및 GC를 추적.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Texture&lt;/b&gt;, &lt;b&gt;Mesh&lt;/b&gt;, &lt;b&gt;Audio Clip&lt;/b&gt;의 메모리 사용량 확인.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;너무 큰 텍스처나 오디오 파일이 메모리를 과도하게 차지하는 경우.&lt;/li&gt;
&lt;li&gt;메모리 해제가 이루어지지 않아 누수가 발생하는 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) Rendering&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오브젝트 렌더링 과정과 Draw Call 수를 보여줍니다.&lt;/li&gt;
&lt;li&gt;배칭 효과를 확인할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) Audio&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;게임 오디오와 관련된 데이터.&lt;/li&gt;
&lt;li&gt;오디오 클립 재생 빈도 및 DSP(디지털 신호 처리) 시간 분석.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 성능 분석 및 최적화 단계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 병목 현상 확인&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Profiler Timeline&lt;/b&gt;에서 가장 긴 프레임 시간(Spike)을 확인합니다.&lt;/li&gt;
&lt;li&gt;해당 프레임의 CPU, GPU 사용률 및 특정 함수의 실행 시간을 분석합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 문제 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU 병목 현상 해결&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;Update()&lt;/b&gt;와 &lt;b&gt;FixedUpdate()&lt;/b&gt; 내 작업을 간소화.&lt;/li&gt;
&lt;li&gt;반복 호출되는 메서드에 캐싱 기법 활용.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GPU 병목 현상 해결&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;텍스처 크기 줄이기.&lt;/li&gt;
&lt;li&gt;Static/Dynamic Batching과 GPU Instancing 적용.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;메모리 사용량이 높은 리소스를 압축 또는 최적화.&lt;/li&gt;
&lt;li&gt;사용하지 않는 오브젝트를 Destroy()로 제거하고 Resources.UnloadUnusedAssets() 호출.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 최적화 후 재분석&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최적화 후 다시 Profiler를 사용해 문제 개선 여부를 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. Profiler와 함께 사용할 추가 도구&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Frame Debugger&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;렌더링 단계를 한 프레임 단위로 분석.&lt;/li&gt;
&lt;li&gt;Draw Call 병목 현상 해결에 유용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory Profiler 패키지&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;세부적인 메모리 스냅샷 제공.&lt;/li&gt;
&lt;li&gt;메모리 누수를 발견하고 관리할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Deep Profile&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;Profiler&lt;/b&gt;의 세부 모드로, 함수 호출 체인을 깊이 있게 분석.&lt;/li&gt;
&lt;li&gt;단, 성능에 영향을 줄 수 있으므로 필요 시에만 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 최적화 팁&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Update 호출 줄이기&lt;/b&gt;: 자주 호출되는 메서드의 최적화는 성능 향상에 큰 영향을 줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오브젝트 풀링(Object Pooling)&lt;/b&gt;: 오브젝트 생성과 파괴를 최소화.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;배칭 활용&lt;/b&gt;: Static/Dynamic Batching, GPU Instancing을 적극적으로 사용.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;텍스처 압축&lt;/b&gt;: 모바일 환경에서는 텍스처 압축을 활용해 메모리 사용량 감소.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity Profiler는 성능 문제를 시각적으로 분석하고 최적화 가능성을 파악하는 데 매우 유용합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CPU, GPU, 메모리, 렌더링 등 다양한 섹션에서 병목 현상을 발견.&lt;/li&gt;
&lt;li&gt;문제를 분석한 후, 최적화 기법을 적용.&lt;/li&gt;
&lt;li&gt;Frame Debugger와 Memory Profiler 같은 추가 도구로 최적화 결과를 확인.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Unity</category>
      <category>unity profiler</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 프로파일러</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/151</guid>
      <comments>https://russellstudio.tistory.com/151#entry151comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:34:15 +0900</pubDate>
    </item>
    <item>
      <title>Unity 메모리 관리 및 배칭(Batching)</title>
      <link>https://russellstudio.tistory.com/150</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 메모리 관리 및 배칭(Batching) 이해&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서의 성능 최적화는 게임 개발의 핵심 과제 중 하나입니다. 특히, 메모리 관리와 배칭(Batching)은 부드러운 게임 플레이 경험을 제공하는 데 필수적인 요소입니다. 이번 포스팅에서는 Unity의 메모리 관리 기법과 배칭의 개념 및 활용 방법을 살펴보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Unity 메모리 관리의 중요성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메모리 관리&lt;/b&gt;는 게임이 적절한 메모리를 사용하도록 조정하여 성능 문제를 방지하는 작업입니다.&lt;br /&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;메모리 누수&lt;/b&gt;: 더 이상 사용하지 않는 데이터가 메모리에 남아 있는 경우.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GC(Garbage Collection) 과부하&lt;/b&gt;: 불필요한 메모리 해제가 많아 프레임 드롭 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 메모리 관리 기법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 메모리 사용 추적&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity의 &lt;b&gt;Profiler&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;Unity Profiler&lt;/b&gt;에서 Memory 탭을 열어 오브젝트, 텍스처, 메쉬, 오디오 클립의 메모리 사용량을 확인.&lt;/li&gt;
&lt;li&gt;스크립트 메모리는 Mono Behaviour와 관련된 데이터를 보여줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 텍스처 및 오브젝트 관리&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;텍스처 압축&lt;/b&gt;: 텍스처의 해상도를 낮추거나 압축 형식을 사용하세요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오브젝트 풀링(Object Pooling)&lt;/b&gt;: 자주 생성 및 파괴되는 오브젝트를 재사용해 메모리 할당을 줄입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불필요한 리소스 해제&lt;/b&gt;: Resources.UnloadUnusedAssets()를 호출해 사용하지 않는 리소스를 메모리에서 해제.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 스크립트 최적화&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;할당 최소화&lt;/b&gt;: new 키워드를 과도하게 사용하지 말고, 기존 객체를 재사용하세요.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GC 호출 줄이기&lt;/b&gt;: 큰 데이터 배열은 미리 할당하고, 매 프레임 재할당을 피하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 배칭(Batching)이란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배칭(Batching)은 &lt;b&gt;여러 오브젝트의 렌더링 작업을 묶어 처리&lt;/b&gt;하여 CPU와 GPU의 부하를 줄이는 기술입니다.&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;Draw Call&lt;/b&gt;: GPU가 화면에 오브젝트를 렌더링하는 요청.&lt;/li&gt;
&lt;li&gt;배칭을 사용하면 Draw Call 수를 줄여 성능을 최적화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. Unity에서의 배칭 종류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity는 &lt;b&gt;Static Batching&lt;/b&gt;과 &lt;b&gt;Dynamic Batching&lt;/b&gt;, &lt;b&gt;GPU Instancing&lt;/b&gt;을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Static Batching&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;특징&lt;/b&gt;: 움직이지 않는 정적 오브젝트를 하나의 메쉬로 결합해 배칭.&lt;/li&gt;
&lt;li&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;Inspector에서 &lt;b&gt;Static&lt;/b&gt; 체크박스 활성화.&lt;/li&gt;
&lt;li&gt;정적 환경 오브젝트에 적합 (예: 건물, 나무).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: CPU 사용량 감소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: 메모리 사용량 증가.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Dynamic Batching&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;특징&lt;/b&gt;: 소형, 동일한 쉐이더를 사용하는 오브젝트를 한 번에 처리.&lt;/li&gt;
&lt;li&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;오브젝트 크기와 Vertex 수가 작아야 함 (300개 이하).&lt;/li&gt;
&lt;li&gt;동적으로 움직이는 오브젝트에 적합.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: Draw Call 감소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: CPU 부하 증가 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) GPU Instancing&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;특징&lt;/b&gt;: 동일한 메쉬를 공유하는 오브젝트를 GPU에서 한 번에 처리.&lt;/li&gt;
&lt;li&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;Material&lt;/b&gt;에서 &lt;b&gt;Enable GPU Instancing&lt;/b&gt; 체크 활성화.&lt;/li&gt;
&lt;li&gt;적합 예: 동일한 나무 모델을 대량으로 배치.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 메모리 절약 및 GPU 부하 감소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: 복잡한 쉐이더는 효과 감소.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 배칭 최적화 사례&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 1: Static Batching 적용&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734957137398&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GameObject building = GameObject.Find(&quot;Building&quot;);
building.isStatic = true; // 정적 오브젝트로 설정&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 2: GPU Instancing 활용&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734957142735&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Material treeMaterial = Resources.Load&amp;lt;Material&amp;gt;(&quot;TreeMaterial&quot;);
treeMaterial.enableInstancing = true; // GPU Instancing 활성화&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 3: Draw Call 확인&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;Stats 패널&lt;/b&gt;을 통해 현재 Draw Call 수를 확인하고 최적화 목표를 설정하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 메모리 관리와 배칭의 통합 활용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;효율적인 메모리 관리와 배칭은 게임의 성능을 극대화합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;메모리 사용량을 줄여 GC 호출을 최소화.&lt;/li&gt;
&lt;li&gt;배칭을 통해 Draw Call 수를 줄여 렌더링 성능 향상.&lt;/li&gt;
&lt;li&gt;Profiler와 Frame Debugger를 사용해 최적화 상태를 지속적으로 점검.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 요약&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 관리는 게임이 부드럽게 실행되도록 보장하며, Profiler를 사용해 문제를 추적하세요.&lt;/li&gt;
&lt;li&gt;배칭 기법(Static, Dynamic, GPU Instancing)을 사용해 Draw Call을 줄이세요.&lt;/li&gt;
&lt;li&gt;두 기술을 통합적으로 활용해 높은 퍼포먼스와 낮은 메모리 소비를 동시에 달성하세요.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>unity batching</category>
      <category>unity memory</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 메모리</category>
      <category>unity 배칭</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/150</guid>
      <comments>https://russellstudio.tistory.com/150#entry150comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:32:30 +0900</pubDate>
    </item>
    <item>
      <title>Unity 오브젝트 풀링(Object Pooling) 기법</title>
      <link>https://russellstudio.tistory.com/149</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 오브젝트 풀링(Object Pooling) 기법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 개발에서 성능 최적화는 매우 중요합니다. &lt;b&gt;오브젝트 풀링(Object Pooling)&lt;/b&gt;은 자주 생성하고 파괴되는 오브젝트를 효율적으로 관리해 게임 성능을 향상시키는 기술입니다. 이번 포스팅에서는 Unity에서 오브젝트 풀링의 개념, 장점, 구현 방법을 다룹니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 오브젝트 풀링(Object Pooling)이란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;오브젝트 생성 비용을 줄여 성능 향상.&lt;/li&gt;
&lt;li&gt;메모리 단편화를 방지.&lt;/li&gt;
&lt;li&gt;Garbage Collection 호출을 최소화.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;적 생성&lt;/li&gt;
&lt;li&gt;총알 발사&lt;/li&gt;
&lt;li&gt;파티클 효과&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 오브젝트 풀링의 동작 원리&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;게임 시작 시 필요한 만큼의 오브젝트를 미리 생성해 &lt;b&gt;풀(Pool)&lt;/b&gt;에 저장.&lt;/li&gt;
&lt;li&gt;필요할 때 풀에서 오브젝트를 가져와 사용.&lt;/li&gt;
&lt;li&gt;사용이 끝난 오브젝트를 비활성화하고 풀에 반환.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. Unity에서 오브젝트 풀링 구현하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 기본 스크립트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 Unity에서 간단한 오브젝트 풀링 시스템을 구현하는 코드입니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956450746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour
{
    public GameObject prefab; // 생성할 오브젝트 프리팹
    public int poolSize = 10; // 초기 풀 크기

    private Queue&amp;lt;GameObject&amp;gt; pool = new Queue&amp;lt;GameObject&amp;gt;();

    void Start()
    {
        // 풀 초기화
        for (int i = 0; i &amp;lt; poolSize; i++)
        {
            GameObject obj = Instantiate(prefab);
            obj.SetActive(false); // 비활성화
            pool.Enqueue(obj); // 풀에 추가
        }
    }

    public GameObject GetObject()
    {
        if (pool.Count &amp;gt; 0)
        {
            GameObject obj = pool.Dequeue();
            obj.SetActive(true); // 활성화
            return obj;
        }
        else
        {
            GameObject obj = Instantiate(prefab);
            return obj;
        }
    }

    public void ReturnObject(GameObject obj)
    {
        obj.SetActive(false); // 비활성화
        pool.Enqueue(obj); // 풀에 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 사용 예제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;총알 발사 시스템에 오브젝트 풀링 적용하기&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ObjectPool 스크립트를 빈 GameObject에 추가하고, Prefab과 Pool Size를 설정합니다.&lt;/li&gt;
&lt;li&gt;총알을 발사하는 스크립트를 작성합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956461974&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class BulletSpawner : MonoBehaviour
{
    public ObjectPool bulletPool; // ObjectPool 참조
    public Transform firePoint;

    void Update()
    {
        if (Input.GetButtonDown(&quot;Fire1&quot;))
        {
            GameObject bullet = bulletPool.GetObject(); // 풀에서 총알 가져오기
            bullet.transform.position = firePoint.position;
            bullet.transform.rotation = firePoint.rotation;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;총알이 화면을 벗어나면 풀에 반환합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956468887&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class Bullet : MonoBehaviour
{
    private float lifetime = 5f; // 총알의 생명 시간
    private float timer = 0f;

    void OnEnable()
    {
        timer = 0f; // 타이머 초기화
    }

    void Update()
    {
        timer += Time.deltaTime;
        if (timer &amp;gt;= lifetime)
        {
            FindObjectOfType&amp;lt;ObjectPool&amp;gt;().ReturnObject(gameObject); // 풀에 반환
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 오브젝트 풀링의 장단점&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;성능 최적화: 메모리 할당 및 해제 비용 감소&lt;/td&gt;
&lt;td&gt;초기 생성 비용이 큼&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;부드러운 게임 플레이: GC 호출 빈도 감소&lt;/td&gt;
&lt;td&gt;비활성화된 오브젝트가 메모리를 차지함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;반복적인 오브젝트 생성/삭제 시 적합&lt;/td&gt;
&lt;td&gt;복잡한 시나리오에서는 구현 난이도가 높아질 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 오브젝트 풀링 최적화 팁&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오브젝트 풀링(Object Pooling)&lt;/b&gt;은 자주 생성되고 파괴되는 오브젝트를 효율적으로 관리하여 게임 성능을 향상시키는 데 매우 유용한 기법입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;총알, 적, 파티클 등 반복적으로 생성되는 오브젝트에 적용.&lt;/li&gt;
&lt;li&gt;성능 최적화와 부드러운 게임 플레이를 보장.&lt;/li&gt;
&lt;li&gt;Unity에서 간단한 스크립트로 구현 가능.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>unity object pool</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 오프젝트 풀링</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/149</guid>
      <comments>https://russellstudio.tistory.com/149#entry149comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:21:45 +0900</pubDate>
    </item>
    <item>
      <title>Unity 네트워크 기초 이론 (클라이언트-서버 구조)</title>
      <link>https://russellstudio.tistory.com/148</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 네트워크 기초 이론: 클라이언트-서버 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온라인 멀티플레이어 게임 개발에서 네트워크는 핵심적인 역할을 합니다. 특히, 클라이언트-서버 구조는 대부분의 네트워크 게임에서 사용되는 기본적인 아키텍처입니다. 이번 포스팅에서는 Unity에서의 네트워크 기초와 클라이언트-서버 구조에 대해 설명하겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 클라이언트-서버 구조란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&lt;b&gt;클라이언트(Client)&lt;/b&gt;: 사용자 인터페이스를 제공하며 서버와 데이터를 주고받습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버(Server)&lt;/b&gt;: 데이터를 중앙에서 처리하고 클라이언트에 정보를 전달합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;중앙 집중화된 데이터 처리로 클라이언트 간 동기화가 용이.&lt;/li&gt;
&lt;li&gt;데이터 보안이 상대적으로 강함.&lt;/li&gt;
&lt;li&gt;서버 과부하가 발생할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 클라이언트-서버 구조의 장단점&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;중앙 서버로 데이터 관리가 용이&lt;/td&gt;
&lt;td&gt;서버 과부하 시 성능 저하 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;클라이언트 간의 실시간 동기화 가능&lt;/td&gt;
&lt;td&gt;네트워크 지연(Latency) 문제 발생 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;클라이언트의 데이터 조작 가능성 감소&lt;/td&gt;
&lt;td&gt;서버 유지비 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. Unity에서 네트워크 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서는 &lt;b&gt;Netcode for GameObjects (NGO)&lt;/b&gt;, &lt;b&gt;Photon&lt;/b&gt;, 또는 &lt;b&gt;Mirror&lt;/b&gt;와 같은 네트워크 프레임워크를 사용하여 클라이언트-서버 구조를 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 네트워크 솔루션&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Netcode for GameObjects (NGO)&lt;/b&gt;: Unity의 공식 네트워크 라이브러리.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Photon&lt;/b&gt;: 간단한 설정과 클라우드 서버를 지원.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mirror&lt;/b&gt;: 오픈 소스이며 커뮤니티 지원이 활발.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 클라이언트-서버 통신의 기본 원리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 서버 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버는 클라이언트의 요청을 처리하고, 게임 상태를 유지하며, 클라이언트 간 데이터를 동기화합니다.&lt;br /&gt;서버는 일반적으로 고성능 머신이나 클라우드 서비스에서 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 클라이언트 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트는 사용자의 입력을 서버에 전달하고, 서버로부터 게임 상태를 수신하여 화면에 렌더링합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 데이터 흐름&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트가 서버에 연결 요청을 보냅니다.&lt;/li&gt;
&lt;li&gt;서버는 클라이언트를 승인하고 연결을 설정합니다.&lt;/li&gt;
&lt;li&gt;클라이언트는 사용자 입력 데이터를 서버에 전송합니다.&lt;/li&gt;
&lt;li&gt;서버는 데이터를 처리한 후 결과를 모든 클라이언트에 브로드캐스트합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. Unity에서의 클라이언트-서버 구현 기본 코드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 서버 역할 설정&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956319146&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using Unity.Netcode;

public class ServerManager : MonoBehaviour
{
    void Start()
    {
        NetworkManager.Singleton.StartServer(); // 서버 시작
        Debug.Log(&quot;서버가 시작되었습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 클라이언트 역할 설정&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956325187&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using Unity.Netcode;

public class ClientManager : MonoBehaviour
{
    void Start()
    {
        NetworkManager.Singleton.StartClient(); // 클라이언트 시작
        Debug.Log(&quot;클라이언트가 서버에 연결되었습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 호스트 역할 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버와 클라이언트를 동시에 실행하는 호스트 모드는 소규모 멀티플레이어 게임에서 유용합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956332514&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using Unity.Netcode;

public class HostManager : MonoBehaviour
{
    void Start()
    {
        NetworkManager.Singleton.StartHost(); // 호스트 시작
        Debug.Log(&quot;호스트가 시작되었습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 클라이언트-서버 동기화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) RPC(Remote Procedure Call)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트와 서버 간 특정 동작을 실행하기 위해 사용됩니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956342022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ServerRpc]
void ServerRpcExample()
{
    Debug.Log(&quot;서버에서 실행됨&quot;);
}

[ClientRpc]
void ClientRpcExample()
{
    Debug.Log(&quot;클라이언트에서 실행됨&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 변수 동기화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Netcode에서는 &lt;b&gt;NetworkVariable&lt;/b&gt;을 사용하여 데이터를 동기화할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734956348449&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Unity.Netcode;

public class SyncData : NetworkBehaviour
{
    public NetworkVariable&amp;lt;int&amp;gt; playerScore = new NetworkVariable&amp;lt;int&amp;gt;();

    void Update()
    {
        if (IsServer)
        {
            playerScore.Value += 1; // 서버에서 점수 증가
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 네트워크 개발 시 고려사항&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;지연 시간(Latency)&lt;/b&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;/li&gt;
&lt;li&gt;&lt;b&gt;패킷 손실(Packet Loss)&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;(TCP)을 사용하고, 반복 가능한 데이터는 &lt;b&gt;비신뢰성 전송&lt;/b&gt;(UDP)을 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;8. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서의 클라이언트-서버 구조는 멀티플레이어 게임 구현의 핵심입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트-서버 구조를 통해 데이터를 효율적으로 관리하고 동기화할 수 있습니다.&lt;/li&gt;
&lt;li&gt;Unity Netcode for GameObjects 또는 Photon 같은 네트워크 솔루션을 사용해 네트워크 게임을 쉽게 개발할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>unity network</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 네트워크</category>
      <category>네트워크 이론</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/148</guid>
      <comments>https://russellstudio.tistory.com/148#entry148comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:19:19 +0900</pubDate>
    </item>
    <item>
      <title>Unity 간단한 적 AI 제작</title>
      <link>https://russellstudio.tistory.com/147</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 간단한 적 AI 제작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 개발에서 &lt;b&gt;적 AI&lt;/b&gt;는 플레이어의 도전 의식을 자극하고 몰입감을 더하는 중요한 요소입니다. 이번 포스팅에서는 Unity를 활용해 간단한 적 AI를 제작하는 방법을 소개합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 적 AI의 기본 개념&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적 AI는 게임 내에서 &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;&lt;b&gt;추적(Chase)&lt;/b&gt;: 플레이어를 따라감.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;공격(Attack)&lt;/b&gt;: 일정 거리 내에서 공격 행동.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;순찰(Patrol)&lt;/b&gt;: 특정 경로를 따라 이동.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 기본 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 프로젝트 환경 준비&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;새 &lt;b&gt;3D Unity 프로젝트&lt;/b&gt;를 생성합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Plane&lt;/b&gt;을 생성하고 게임 씬의 바닥 역할을 하도록 설정합니다.&lt;/li&gt;
&lt;li&gt;적 역할을 할 &lt;b&gt;Cube&lt;/b&gt; 또는 &lt;b&gt;3D 모델&lt;/b&gt;을 추가합니다.&lt;/li&gt;
&lt;li&gt;플레이어 역할의 &lt;b&gt;Capsule&lt;/b&gt; 또는 다른 오브젝트를 추가합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) NavMesh 활성화&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Window &amp;gt; AI &amp;gt; Navigation&lt;/b&gt;을 클릭하여 Navigation 창을 엽니다.&lt;/li&gt;
&lt;li&gt;Plane을 선택하고 Navigation 창에서 &lt;b&gt;Bake&lt;/b&gt;를 클릭하여 NavMesh를 생성합니다.&lt;/li&gt;
&lt;li&gt;적 오브젝트에 &lt;b&gt;NavMesh Agent&lt;/b&gt; 컴포넌트를 추가합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 스크립트로 적 AI 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 적 추적 기능 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어를 따라가는 기본 추적 AI를 작성합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892850376&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.AI;

public class EnemyAI : MonoBehaviour
{
    public Transform player; // 플레이어 위치
    private NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent&amp;lt;NavMeshAgent&amp;gt;();
    }

    void Update()
    {
        if (player != null)
        {
            agent.SetDestination(player.position); // 플레이어를 목표로 설정
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NavMeshAgent&lt;/b&gt;가 플레이어의 위치를 따라 경로를 계산합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 공격 기능 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어와 적 사이의 거리를 계산하여 공격을 수행합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892864373&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public float attackRange = 2f; // 공격 범위
public float attackCooldown = 1f; // 공격 간격
private float lastAttackTime = 0;

void Update()
{
    float distance = Vector3.Distance(transform.position, player.position);

    if (distance &amp;lt;= attackRange &amp;amp;&amp;amp; Time.time &amp;gt;= lastAttackTime + attackCooldown)
    {
        AttackPlayer();
        lastAttackTime = Time.time;
    }
    else
    {
        agent.SetDestination(player.position);
    }
}

void AttackPlayer()
{
    Debug.Log(&quot;공격!&quot;);
    // 여기에서 플레이어에게 데미지를 줄 수 있습니다.
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 순찰(Patrol) 기능 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 순찰 지점 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 순찰 지점을 순서대로 이동하는 기능을 추가합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892876093&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public Transform[] patrolPoints; // 순찰 지점 배열
private int currentPatrolIndex = 0;

void Patrol()
{
    if (patrolPoints.Length == 0) return;

    agent.SetDestination(patrolPoints[currentPatrolIndex].position);

    if (!agent.pathPending &amp;amp;&amp;amp; agent.remainingDistance &amp;lt; 0.5f)
    {
        currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Length;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 순찰과 추적의 전환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어가 감지되면 추적, 그렇지 않으면 순찰하도록 구현합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892884618&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public float detectionRange = 10f; // 플레이어 감지 범위

void Update()
{
    float distance = Vector3.Distance(transform.position, player.position);

    if (distance &amp;lt;= detectionRange)
    {
        agent.SetDestination(player.position); // 추적
    }
    else
    {
        Patrol(); // 순찰
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 적 AI의 시각적 표현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 적 행동 상태에 따른 색상 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적 AI의 상태를 시각적으로 표시할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892894053&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private Renderer enemyRenderer;

void Start()
{
    enemyRenderer = GetComponent&amp;lt;Renderer&amp;gt;();
}

void Update()
{
    float distance = Vector3.Distance(transform.position, player.position);

    if (distance &amp;lt;= detectionRange)
    {
        enemyRenderer.material.color = Color.red; // 추적 중
    }
    else
    {
        enemyRenderer.material.color = Color.green; // 순찰 중
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 최적화 팁&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Trigger 활용&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;Collider&lt;/b&gt;와 &lt;b&gt;Trigger&lt;/b&gt;로 처리해 경로 계산을 최소화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NavMesh Agent 설정&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;Stopping Distance&lt;/b&gt;와 &lt;b&gt;Speed&lt;/b&gt;를 상황에 맞게 조정해 부드러운 이동을 구현합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 간단한 적 AI를 구현해 보았습니다.&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;NavMesh&lt;/b&gt;를 활용한 경로 찾기.&lt;/li&gt;
&lt;li&gt;추적, 공격, 순찰 기능 구현.&lt;/li&gt;
&lt;li&gt;플레이어 감지 및 상태 전환.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>Unity AI</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/147</guid>
      <comments>https://russellstudio.tistory.com/147#entry147comment</comments>
      <pubDate>Mon, 23 Dec 2024 03:41:42 +0900</pubDate>
    </item>
    <item>
      <title>Unity NavMesh를 활용한 AI 경로 찾기</title>
      <link>https://russellstudio.tistory.com/146</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity NavMesh를 활용한 AI 경로 찾기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;NavMesh&lt;/b&gt;는 Unity에서 제공하는 내장 경로 찾기 시스템으로, AI 캐릭터가 지형을 탐색하고 목표 지점까지 효율적으로 이동할 수 있도록 돕습니다. 이번 포스팅에서는 NavMesh의 기본 개념, 설정 방법, 그리고 AI 경로 찾기 구현 방법을 알아보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. NavMesh란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavMesh(Navigation Mesh)는 3D 공간에서 AI가 이동할 수 있는 영역을 나타내는 데이터 구조입니다.&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;NavMesh Agent&lt;/b&gt;: NavMesh 위에서 이동하는 AI 캐릭터.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NavMesh Obstacles&lt;/b&gt;: 장애물을 정의하여 AI의 이동 경로를 제어.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;AI 캐릭터의 경로 탐색.&lt;/li&gt;
&lt;li&gt;장애물을 우회하는 동적 경로 계산.&lt;/li&gt;
&lt;li&gt;지형에 따라 자동으로 길을 생성.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. NavMesh 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) NavMesh 생성&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Window &amp;gt; AI &amp;gt; Navigation&lt;/b&gt;을 클릭하여 Navigation 창을 엽니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scene&lt;/b&gt; 창에서 AI가 이동할 수 있는 지형을 선택합니다.&lt;/li&gt;
&lt;li&gt;Navigation 창에서 &lt;b&gt;Bake&lt;/b&gt; 탭으로 이동하여 &lt;b&gt;Bake&lt;/b&gt; 버튼을 클릭합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;선택한 지형이 NavMesh로 변환됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Agent Radius, Height&lt;/b&gt; 등을 조정해 세부 설정을 변경할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) NavMesh Agent 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AI 캐릭터가 될 GameObject를 선택합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Inspector &amp;gt; Add Component &amp;gt; NavMesh Agent&lt;/b&gt;를 추가합니다.&lt;/li&gt;
&lt;li&gt;NavMesh Agent의 속성을 조정합니다:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Speed&lt;/b&gt;: 이동 속도.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Angular Speed&lt;/b&gt;: 회전 속도.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Stopping Distance&lt;/b&gt;: 목표 지점에 도달 후 멈추는 거리.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) NavMesh Obstacles 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AI 경로를 차단할 GameObject를 선택합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Inspector &amp;gt; Add Component &amp;gt; NavMesh Obstacle&lt;/b&gt;을 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Carve&lt;/b&gt; 옵션을 활성화하여 장애물이 NavMesh에 영향을 미치도록 설정합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 스크립트를 통한 경로 찾기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 목표 지점 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI가 이동할 목표 지점을 지정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1734892721918&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.AI;

public class AIController : MonoBehaviour
{
    public Transform target; // 목표 지점
    private NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent&amp;lt;NavMeshAgent&amp;gt;();
        agent.SetDestination(target.position); // 목표 지점으로 이동
    }

    void Update()
    {
        if (agent.remainingDistance &amp;lt;= agent.stoppingDistance)
        {
            // 목표 지점에 도달했을 때의 행동
            Debug.Log(&quot;목표 지점에 도달&quot;);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 동적 목표 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이어의 위치 등 동적으로 변경되는 목표 지점에 AI를 이동시킬 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892736229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void Update()
{
    if (target != null)
    {
        agent.SetDestination(target.position); // 목표 위치를 실시간으로 업데이트
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 장애물 우회 및 동적 경로 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) NavMesh Obstacle 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장애물로 지정된 GameObject는 AI의 경로에 영향을 주어, AI가 이를 우회하도록 만듭니다.&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;Carve&lt;/b&gt;를 활성화하면 NavMesh가 장애물을 중심으로 동적으로 재계산됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) NavMesh Link 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;높은 곳이나 단차를 넘어서 이동해야 하는 경우 &lt;b&gt;NavMesh Link&lt;/b&gt;를 추가합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;GameObject &amp;gt; AI &amp;gt; NavMesh Link&lt;/b&gt;를 선택하여 링크를 생성합니다.&lt;/li&gt;
&lt;li&gt;링크의 시작(Start)과 끝(End) 위치를 설정합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. NavMesh의 확장 기능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 동적 NavMesh 업데이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavMesh가 실시간으로 변경되어야 하는 경우 &lt;b&gt;NavMesh Surface&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;NavMesh Components&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;Package Manager&lt;/b&gt;에서 &quot;NavMesh Components&quot;를 검색하여 설치.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이동할 지형에 &lt;b&gt;NavMesh Surface&lt;/b&gt;를 추가하고 설정합니다.&lt;/li&gt;
&lt;li&gt;스크립트를 통해 동적으로 NavMesh를 갱신할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734892750622&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine.AI;

public class DynamicNavMesh : MonoBehaviour
{
    public NavMeshSurface surface;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            surface.BuildNavMesh(); // NavMesh 재생성
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) AI 행동 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경로 탐색 외에도 AI 행동을 추가하여 더욱 생동감 있는 게임플레이를 구현할 수 있습니다.&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;추적(Chase)&lt;/b&gt;: 플레이어를 따라가도록 설정.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;도망(Flee)&lt;/b&gt;: 특정 조건에서 목표로부터 멀어지도록 설정.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Unity NavMesh&lt;/b&gt;를 활용하면 AI 경로 탐색과 장애물 회피를 손쉽게 구현할 수 있습니다.&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;NavMesh Bake&lt;/b&gt;로 AI가 이동 가능한 영역 생성.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NavMesh Agent&lt;/b&gt;와 &lt;b&gt;Obstacle&lt;/b&gt;을 활용해 동적 경로 계산.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스크립트&lt;/b&gt;를 통해 목표 지점을 제어하고 동적 환경에 대응.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>Unity AI</category>
      <category>unity navmesh</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/146</guid>
      <comments>https://russellstudio.tistory.com/146#entry146comment</comments>
      <pubDate>Mon, 23 Dec 2024 03:39:16 +0900</pubDate>
    </item>
    <item>
      <title>Unity 오디오 믹서 사용법</title>
      <link>https://russellstudio.tistory.com/145</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 오디오 믹서(Audio Mixer) 사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity의 &lt;b&gt;Audio Mixer&lt;/b&gt;는 게임의 사운드를 체계적으로 관리하고, 다양한 음향 효과를 적용할 수 있도록 돕는 강력한 도구입니다. 이번 포스팅에서는 Audio Mixer의 개념, 사용 방법, 그리고 실제 적용 사례를 다루어 보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Audio Mixer란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Audio Mixer&lt;/b&gt;는 Unity에서 제공하는 오디오 관리 도구로, 다음과 같은 작업에 유용합니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;볼륨 조정 및 그룹화.&lt;/li&gt;
&lt;li&gt;사운드 이펙트(EQ, 리버브 등) 적용.&lt;/li&gt;
&lt;li&gt;BGM과 SFX를 구분하여 관리.&lt;/li&gt;
&lt;li&gt;사운드 간의 우선순위 설정 및 블렌딩.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Audio Mixer 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Audio Mixer 생성&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Assets &amp;gt; Create &amp;gt; Audio Mixer&lt;/b&gt;를 클릭하여 Audio Mixer를 생성합니다.&lt;/li&gt;
&lt;li&gt;생성된 Audio Mixer의 이름을 지정합니다 (예: GameAudioMixer).&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Audio Mixer 창 열기&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Audio Mixer를 더블 클릭하면 &lt;b&gt;Audio Mixer 창&lt;/b&gt;이 열립니다.&lt;/li&gt;
&lt;li&gt;창에서 그룹(Group)을 확인하고 추가로 설정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 그룹 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 그룹 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Audio Mixer 창&lt;/b&gt;에서 &lt;b&gt;+&lt;/b&gt; 버튼을 클릭하여 새로운 그룹을 추가합니다.&lt;/li&gt;
&lt;li&gt;예를 들어, BGM과 SFX 그룹을 생성하여 사운드를 분리 관리합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 그룹 연결&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AudioSource의 &lt;b&gt;Output&lt;/b&gt; 속성을 Audio Mixer의 특정 그룹으로 설정합니다.&lt;/li&gt;
&lt;li&gt;사운드 파일이 지정된 그룹을 통해 재생되며, 그룹 설정이 적용됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 기본 Audio Mixer 기능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 볼륨 및 피치 조정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 그룹의 &lt;b&gt;Volume&lt;/b&gt; 슬라이더를 사용해 볼륨을 조정합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pitch&lt;/b&gt; 슬라이더로 재생 속도를 변경할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 이펙트 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Audio Mixer 창&lt;/b&gt;에서 그룹을 선택합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Inspector&lt;/b&gt; 창에서 &lt;b&gt;Add Effect&lt;/b&gt;를 클릭하여 효과(EQ, Reverb 등)를 추가합니다.&lt;/li&gt;
&lt;li&gt;각 효과의 매개변수를 조정해 원하는 사운드를 만듭니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 스냅샷(Snapshots)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스냅샷을 사용하면 특정 오디오 설정 상태를 저장하고 필요 시 전환할 수 있습니다.&lt;/li&gt;
&lt;li&gt;예를 들어, 전투 시에는 효과음을 강조하고, 탐험 시에는 배경 음악을 강조하도록 설정 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. Audio Mixer와 스크립트 연동&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Audio Mixer의 파라미터 설정&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Audio Mixer에서 그룹의 속성(Volume, Pitch 등)에 &lt;b&gt;Expose to Script&lt;/b&gt;를 클릭하여 파라미터를 노출합니다.&lt;/li&gt;
&lt;li&gt;노출된 파라미터는 스크립트에서 제어 가능합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 스크립트 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Audio Mixer를 활용한 볼륨 조정 스크립트를 작성합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734705295577&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.Audio;

public class AudioManager : MonoBehaviour
{
    public AudioMixer audioMixer;

    public void SetVolume(string parameterName, float value)
    {
        audioMixer.SetFloat(parameterName, Mathf.Log10(value) * 20); // dB 단위로 설정
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;SetVolume()&lt;/b&gt; 함수는 슬라이더 값(0~1)을 받아 dB 값으로 변환합니다.&lt;/li&gt;
&lt;li&gt;Audio Mixer의 노출된 파라미터 이름을 &lt;b&gt;parameterName&lt;/b&gt;으로 전달합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 슬라이더와 연동&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UI 슬라이더의 &lt;b&gt;OnValueChanged()&lt;/b&gt; 이벤트에 SetVolume 함수를 연결합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 실제 사례: BGM과 SFX의 분리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 그룹 설정&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Audio Mixer에서 &lt;b&gt;BGM&lt;/b&gt;과 &lt;b&gt;SFX&lt;/b&gt; 그룹을 생성합니다.&lt;/li&gt;
&lt;li&gt;각각의 AudioSource를 해당 그룹으로 연결합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 스크립트를 활용한 볼륨 제어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734705311549&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void AdjustBGMVolume(float value)
{
    SetVolume(&quot;BGMVolume&quot;, value);
}

public void AdjustSFXVolume(float value)
{
    SetVolume(&quot;SFXVolume&quot;, value);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BGM과 SFX의 볼륨을 개별적으로 제어할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 오디오 믹서 최적화 팁&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;8. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity의 Audio Mixer를 사용하면 사운드를 더욱 세밀하게 관리하고, 플레이어 경험을 강화할 수 있습니다.&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;그룹과 이펙트&lt;/b&gt;를 사용하여 사운드 구성.&lt;/li&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;</description>
      <category>Unity</category>
      <category>unity audio mixer</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 오디오 믹서</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/145</guid>
      <comments>https://russellstudio.tistory.com/145#entry145comment</comments>
      <pubDate>Fri, 20 Dec 2024 23:35:19 +0900</pubDate>
    </item>
    <item>
      <title>Unity 사운드 이펙트와 배경 음악 설정</title>
      <link>https://russellstudio.tistory.com/144</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Unity 사운드 이펙트와 배경 음악 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임에서 사운드 이펙트(SFX)와 배경 음악(BGM)은 플레이어의 몰입감을 높이는 중요한 요소입니다. 사운드 이펙트는 액션과 이벤트를 강조하며, 배경 음악은 분위기를 형성하고 감정을 전달합니다. Unity에서 SFX와 BGM을 설정하고 제어하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 프로젝트에 사운드 파일 추가&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 사운드 파일 가져오기&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 탐색기에서 사운드 파일을 Unity &lt;b&gt;Assets&lt;/b&gt; 폴더로 드래그합니다.&lt;/li&gt;
&lt;li&gt;파일이 Unity에 임포트되면, &lt;b&gt;Inspector&lt;/b&gt; 창에서 속성을 확인하고 필요한 설정을 적용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 파일 포맷 선택&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;WAV&lt;/b&gt;: 고품질 효과음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MP3&lt;/b&gt;: 압축된 배경 음악.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 배경 음악(BGM) 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) AudioSource 컴포넌트 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Hierarchy&lt;/b&gt; 창에서 빈 GameObject를 생성하고 이름을 BGMManager로 설정합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Inspector &amp;gt; Add Component &amp;gt; AudioSource&lt;/b&gt;를 추가합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) BGM 설정&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;Audio Clip&lt;/b&gt;: 배경 음악 파일을 할당합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Loop&lt;/b&gt;: 활성화하여 음악이 반복 재생되도록 설정합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Play On Awake&lt;/b&gt;: 활성화하여 게임 시작 시 음악이 재생되도록 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 스크립트를 통한 제어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;BGMManager&lt;/b&gt; 스크립트를 작성합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734705176414&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class BGMManager : MonoBehaviour
{
    public AudioSource audioSource;

    void Start()
    {
        audioSource.Play(); // 게임 시작 시 BGM 재생
    }

    public void StopBGM()
    {
        audioSource.Stop(); // BGM 중지
    }

    public void SetVolume(float volume)
    {
        audioSource.volume = volume; // 볼륨 조정
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 사운드 이펙트(SFX) 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) AudioSource를 사용한 SFX 설정&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이펙트 사운드를 재생할 GameObject를 생성하거나 기존 객체에 &lt;b&gt;AudioSource&lt;/b&gt;를 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Play On Awake&lt;/b&gt;는 비활성화하여 특정 이벤트 시에만 재생되도록 설정합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) SFX 스크립트 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SFXManager&lt;/b&gt;를 작성하여 사운드를 효율적으로 재생합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734705186374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;

public class SFXManager : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip[] soundEffects; // 다양한 효과음을 배열로 저장

    public void PlayEffect(int index)
    {
        if (index &amp;lt; soundEffects.Length)
        {
            audioSource.PlayOneShot(soundEffects[index]); // 지정된 효과음 재생
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;PlayOneShot()&lt;/b&gt;: 기존 사운드를 중단하지 않고 재생.&lt;/li&gt;
&lt;li&gt;효과음을 배열로 관리하여 다양한 사운드를 쉽게 호출 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. Audio Mixer를 사용한 사운드 관리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Audio Mixer 생성&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Assets &amp;gt; Create &amp;gt; Audio Mixer&lt;/b&gt;를 선택하여 믹서를 생성합니다.&lt;/li&gt;
&lt;li&gt;Mixer 내에 그룹을 생성하여 BGM과 SFX를 분리 관리합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) AudioSource와 Audio Mixer 연결&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AudioSource의 &lt;b&gt;Output&lt;/b&gt; 필드를 Audio Mixer의 그룹으로 설정합니다.&lt;/li&gt;
&lt;li&gt;Audio Mixer 창에서 볼륨 및 이펙트를 조정합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 볼륨 조정 UI 구현&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;UI &amp;gt; Slider&lt;/b&gt;를 추가하여 볼륨 조정을 위한 슬라이더를 만듭니다.&lt;/li&gt;
&lt;li&gt;슬라이더의 값 변경 이벤트에 아래 스크립트를 연결합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1734705196949&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.Audio;

public class AudioControl : MonoBehaviour
{
    public AudioMixer audioMixer;

    public void SetVolume(string parameterName, float value)
    {
        audioMixer.SetFloat(parameterName, Mathf.Log10(value) * 20); // dB로 변환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;audioMixer.SetFloat()&lt;/b&gt;를 통해 그룹 볼륨 제어.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 사운드 시스템 최적화 팁&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사운드 풀링(Pooling)&lt;/b&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;/li&gt;
&lt;li&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;AudioSource의 &lt;b&gt;volume&lt;/b&gt;과 &lt;b&gt;pitch&lt;/b&gt;를 활용해 동적이고 자연스러운 사운드 연출.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6. 최종 구조 예시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Hierarchy&lt;/b&gt; 구조:&lt;/p&gt;
&lt;pre id=&quot;code_1734705219717&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BGMManager (GameObject)
├── AudioSource (BGM)

SFXManager (GameObject)
├── AudioSource (SFX)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 요약&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity에서 사운드 이펙트와 배경 음악을 설정하는 과정은 단순하지만, 게임의 감각적인 경험에 큰 영향을 미칩니다.&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;BGM&lt;/b&gt;은 AudioSource의 반복 재생 기능으로 설정.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SFX&lt;/b&gt;는 PlayOneShot을 사용해 중복 없이 효과적으로 재생.&lt;/li&gt;
&lt;li&gt;Audio Mixer로 볼륨과 사운드 효과를 체계적으로 관리.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Unity</category>
      <category>unity sound</category>
      <category>Unity 강의</category>
      <category>unity 기초</category>
      <category>unity 배경 음악</category>
      <category>unity 사운드</category>
      <author>Russell Developer</author>
      <guid isPermaLink="true">https://russellstudio.tistory.com/144</guid>
      <comments>https://russellstudio.tistory.com/144#entry144comment</comments>
      <pubDate>Fri, 20 Dec 2024 23:33:44 +0900</pubDate>
    </item>
  </channel>
</rss>