<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>긴맨의 블로그</title>
    <link>https://youngchangoon.tistory.com/</link>
    <description>Better than Yesterday</description>
    <language>ko</language>
    <pubDate>Fri, 21 Aug 2026 10:56:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>LongMan</managingEditor>
    <image>
      <title>긴맨의 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/1894246/attach/b139bda08ab6499a936136abaaf43848</url>
      <link>https://youngchangoon.tistory.com</link>
    </image>
    <item>
      <title>Typora + Google Drive + R2 조합으로 최적의 글쓰기 환경 만들기</title>
      <link>https://youngchangoon.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;블로그와 글쓰기를 다시 시작하기로 마음을 먹었다. 가장 먼저 하고 싶었던건 글쓰기에 최적화된 환경을 만들고 싶었다. 마크다운 에디터를 찾아보던 중 Typora라는 에디터가 눈에 들어왔다. 앱 자체가 상당히 미니멀하고, 필요한 기능들만 쏙쏙 들어있어 마음에 들었다. 하지만 클라우드 저장이나 이미지 업로드 및 자동 저장을 하려면 몇 가지 세팅이 더 필요했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typora를 사용하면서 더 편리한 환경을 만들기 위한 목표가 있었다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 저장 시 자동으로 클라우드에 저장하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Google Drive를 이용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이미지 업로드시, 자동으로 링크 변환 및 파일 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CloudFlare R2를 이용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 위의 목표를 달성하는건 어렵지 않았다. 몇가지 세팅만 해준다면 더욱 편한 환경에서 글을 작성할 수 있을 것이다!&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세팅 환경은 Mac OS 기준으로 작성하였습니다.&lt;br /&gt;다만 Windows도 크게 다르진 않을것 같습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Google Drive앱을 이용하여 실시간 업로드&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://support.google.com/a/users/answer/13022292?hl=ko&quot;&gt;데스크톱용 구글 드라이브 앱&lt;/a&gt;을 설치합니다.&lt;/li&gt;
&lt;li&gt;구글 드라이브 폴더 경로에 Typora에서 사용할 폴더를 만듭니다.&lt;/li&gt;
&lt;li&gt;Typora를 실행 후 좌측 하단에 &lt;b&gt;폴더 열기&lt;/b&gt;를 누르고 위에서 만든 폴더로 연결합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 폴더 내에서 자유롭게 파일을 만들고 저장을 한다면 자동으로 구글 드라이브에 업로드됩니다.  &lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;번외 팁&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typora를 재시작하면 폴더를 계속 열어줘야하는데 설정에서 [Files]-[프로그램 시작 시]-[&lt;b&gt;마지막 파일과 폴더 열기&lt;/b&gt;]로 설정해주면 재실행해도 작업중인 파일이 열리게 됩니다!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 3.41.23.png&quot; alt=&quot;스크린샷 2025-11-30 오후 3.41.23&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CloudFlare R2, PicGo를 이용해 Typora에 이미지 자동 업로드 구축&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typora에 이미지를 드래그하면 자동으로 CloudFlare R2에 이미지를 업로드하고 링크를 변환하여 반환하도록 해보겠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;도메인 구입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 구입부터 이미 지갑이 열리는 단계지만 R2에서 제공하는 Public Development URL 보다 나은 몇 가지 장점이 있기 때문에 구매하는 것을 추천한다.&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;나중에 R2대신 다른 버킷 서비스를 사용하기 용이하다.&lt;/li&gt;
&lt;li&gt;r2.dev는 속도제한이 걸려 있기 때문에 트래픽이 올라간다면 이미지 로드가 안될 수도 있지만 그럴 걱정이 없다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Domain Registration] - [Register domains]에 진입하여 원하는 도메인을 검색해보고 적당한 가격의 도메인을 구매한다.&lt;br /&gt;(저는 .com으로 끝나는 도메인을 구매하였습니다. (작성 시점 $10.46달러))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 가격은 1년 단위 가격이며 매년 60일전 자동 갱신되니 구매전 잘 보고 체크!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudFlare에서 도메인을 구매하면 별다른 설정 없이 인증서등 다 세팅이 되니 꽤나 간편하다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 5.35.52.png&quot; alt=&quot;스크린샷 2025-11-30 오후 5.35.52&quot; /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;CloudFlare R2설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudFlare 계정을 생성 후 R2서비스에 들어가 적당한 이름으로 Bucket을 새로 만들어준다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/typora_img_02.png&quot; alt=&quot;typora_img_02&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 도메인을 구매한 경우 Custom Domains를 추가, 구매하지 않은경우 Public Development URL을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 업로드 용이므로 서브도메인 (img.)을 달아주는걸 추천한다. 그리고 각 도메인은 복사해둔다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 5.40.24.png&quot; alt=&quot;스크린샷 2025-11-30 오후 5.40.24&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R2 Overview에 들어가 R2에 접근할 API를 만들어줘야 한다. Account Details에 Manage 버튼을 눌러 Account API Token을 하나를 추가한다. 추가 시 읽기권한과 쓰기권한이 모두 포함된 항목을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 4.12.11.png&quot; alt=&quot;스크린샷 2025-11-30 오후 4.12.11&quot; /&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 4.13.41.png&quot; alt=&quot;스크린샷 2025-11-30 오후 4.13.41&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들어진 Token화면에서 Token Value, Access Key ID, Secret Access Key, S3 Clients 값들을 모두 메모장에 저장한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PicGo 플러그인 설치 및 세팅&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PicGo는 이미지를 업로드하고 바로 링크로 변환해주는 유틸리티 앱이다. 마크다운 형식의 글속 이미지를 삽입할때 사용하기 적합한 앱이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣ Picgo는 Github에서 설치가 가능하므로 바로 설치해준다. &lt;a href=&quot;https://github.com/Molunerfinn/PicGo/releases&quot;&gt;설치 링크&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2️⃣ PicGo 앱은 중국어만 지원하므로 Typora 설정에서 중국어로 변경뒤 이미지 업로드 설정에서 PicGo.app을 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( PicGo.app으로 설정뒤 다시 원래 언어로 변경해도 됨)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 5.53.54.png&quot; alt=&quot;스크린샷 2025-11-30 오후 5.53.54&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3️⃣ PicGo앱을 실행해 S3 플러그인을 받아준다&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.kyc521.com/스크린샷 2025-11-30 오후 6.01.27.png&quot; alt=&quot;스크린샷 2025-11-30 오후 6.01.27&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4️⃣ Picbeds Settings - Amazon S3 설정에 들어가 하나 만들어 준뒤 아래 항목들을 채워준다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Configuration Name - 적당한 이름 입력&lt;/li&gt;
&lt;li&gt;应用密钥 ID: Cloudflare에서 생성한 Access Key ID&lt;/li&gt;
&lt;li&gt;应用密钥: Cloudflare에서 생성한 Secret Access Key&lt;/li&gt;
&lt;li&gt;桶名: Cloudflare R2 버킷 이름&lt;/li&gt;
&lt;li&gt;上传文件路径: 이미지 저장 경로/파일명
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex: {fileName}.{extName}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;自定义节点: Cloudflare R2 엔드포인트 (아까 복사한 S3 Clients 항목)&lt;/li&gt;
&lt;li&gt;自定义输出URL模板: 이미지 업로드 후 생성되는 URL 형식 (R2에서 설정한 커스텀 도메인 or Public Dev Url)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex: &lt;a href=&quot;https://img.kyc521.com/%7BfileName%7D&quot;&gt;https://img.kyc521.com/{fileName}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결과&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 세팅이 완료되었다면 Typora에 이미지를 드래그 앤 드롭할 시 자동으로 이미지가 R2에 저장되며 자동으로 링크가 생성되는걸 확인할 수 있다.&lt;/p&gt;</description>
      <category>프로그래밍</category>
      <category>Typora</category>
      <category>개발</category>
      <category>생산성</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/79</guid>
      <comments>https://youngchangoon.tistory.com/79#entry79comment</comments>
      <pubDate>Sun, 30 Nov 2025 18:31:47 +0900</pubDate>
    </item>
    <item>
      <title>북한산 등산 후기</title>
      <link>https://youngchangoon.tistory.com/78</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6214.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/purCK/btspomjRgJo/uALrJTmaz1oRQnnYTbt0MK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/purCK/btspomjRgJo/uALrJTmaz1oRQnnYTbt0MK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/purCK/btspomjRgJo/uALrJTmaz1oRQnnYTbt0MK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpurCK%2FbtspomjRgJo%2FuALrJTmaz1oRQnnYTbt0MK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;800&quot; data-filename=&quot;IMG_6214.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;새벽 일찍 일어나 지하철을 타고 북한산국립공원으로 출발했다.&lt;br /&gt;여름 산행이라 엄청 더울 줄 알았지만 아침에 출발하니 그리 덥지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6276.PNG&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUM862/btspmgRZNho/VlWoH3Vlxud6B0LdTgKU90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUM862/btspmgRZNho/VlWoH3Vlxud6B0LdTgKU90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUM862/btspmgRZNho/VlWoH3Vlxud6B0LdTgKU90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUM862%2FbtspmgRZNho%2FVlWoH3Vlxud6B0LdTgKU90%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;500&quot; height=&quot;1082&quot; data-filename=&quot;IMG_6276.PNG&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;국립공원 스탬프를 받아야 했기에 북한산성지원센터에서 시작하여 백운대를 찍고 내려오는 루트로 정했다.&lt;br /&gt;내려오는 길을 돌아오는 바람에 올라갈때보다 내려오는 시간이 더 길었던거 같다. ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6227.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTKKok/btspg0o5Md2/MU7CcGkWBH9wMF1qRdDJIK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTKKok/btspg0o5Md2/MU7CcGkWBH9wMF1qRdDJIK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTKKok/btspg0o5Md2/MU7CcGkWBH9wMF1qRdDJIK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTKKok%2Fbtspg0o5Md2%2FMU7CcGkWBH9wMF1qRdDJIK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; data-filename=&quot;IMG_6227.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6229.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTW7MO/btsplRypWx1/qNPAPOrAR8cKik8p4twp71/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTW7MO/btsplRypWx1/qNPAPOrAR8cKik8p4twp71/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTW7MO/btsplRypWx1/qNPAPOrAR8cKik8p4twp71/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTW7MO%2FbtsplRypWx1%2FqNPAPOrAR8cKik8p4twp71%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; data-filename=&quot;IMG_6229.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute; text-align: center;&quot; 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;IMG_6230.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eaZiB6/btspnjAUoqd/jTswL9mWgqb7Kz2u8hDrHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eaZiB6/btspnjAUoqd/jTswL9mWgqb7Kz2u8hDrHK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eaZiB6/btspnjAUoqd/jTswL9mWgqb7Kz2u8hDrHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeaZiB6%2FbtspnjAUoqd%2FjTswL9mWgqb7Kz2u8hDrHK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; data-filename=&quot;IMG_6230.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6239.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2TMwK/btspkJ1WCyA/a7X7dlihgNPxYcJpphzT61/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2TMwK/btspkJ1WCyA/a7X7dlihgNPxYcJpphzT61/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2TMwK/btspkJ1WCyA/a7X7dlihgNPxYcJpphzT61/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2TMwK%2FbtspkJ1WCyA%2Fa7X7dlihgNPxYcJpphzT61%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; data-filename=&quot;IMG_6239.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;백운대 정상가기 직전 무차별 큰 돌들과 계단들 덕분에 숨이&lt;br /&gt;턱 끝까지 차올랐지만 포기하지 않고 올라가니 백운대가 나를 반겼다.&lt;br /&gt;정상에서 바라본 경치는 너무 아름다웠고, 바람도 많이 불어서 너무너무 시원했다.&lt;br /&gt;최근에 러브버그 때문에 시끄러웠던 산인데 7월이 되니 벌레 한마리 보이지 않았다.&lt;br /&gt;사람도 없어서 금방 인증샷도 찍을 수 있었다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6247.JPG&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAt91S/btspmfZOX4I/YeKmZo0JWqWkAlqKBJTzaK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAt91S/btspmfZOX4I/YeKmZo0JWqWkAlqKBJTzaK/img.jpg&quot; data-alt=&quot;정상에서 사진 한장! 뒤돌아야 이쁜 나..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAt91S/btspmfZOX4I/YeKmZo0JWqWkAlqKBJTzaK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAt91S%2FbtspmfZOX4I%2FYeKmZo0JWqWkAlqKBJTzaK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;375&quot; data-filename=&quot;IMG_6247.JPG&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정상에서 사진 한장! 뒤돌아야 이쁜 나..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;IMG_6260.JPG&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx0AID/btspsWd7qnv/HFBOQqCAGG1f9ZwWy1a5mK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx0AID/btspsWd7qnv/HFBOQqCAGG1f9ZwWy1a5mK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx0AID/btspsWd7qnv/HFBOQqCAGG1f9ZwWy1a5mK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx0AID%2FbtspsWd7qnv%2FHFBOQqCAGG1f9ZwWy1a5mK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;375&quot; data-filename=&quot;IMG_6260.JPG&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_6270.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL8Z1s/btspfPahYYq/csc1rSTPOZCOQdleU9dRj1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL8Z1s/btspfPahYYq/csc1rSTPOZCOQdleU9dRj1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL8Z1s/btspfPahYYq/csc1rSTPOZCOQdleU9dRj1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL8Z1s%2FbtspfPahYYq%2Fcsc1rSTPOZCOQdleU9dRj1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;667&quot; data-filename=&quot;IMG_6270.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아침에 왔을땐 탐방센터가 문을 열지 않아서 정상찍고 내려온후 다시 찍었다! 이제 2개 완성!&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>여행/등산</category>
      <category>등산</category>
      <category>북한산</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/78</guid>
      <comments>https://youngchangoon.tistory.com/78#entry78comment</comments>
      <pubDate>Sun, 30 Jul 2023 13:05:16 +0900</pubDate>
    </item>
    <item>
      <title>태백산 등산 후기</title>
      <link>https://youngchangoon.tistory.com/77</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;7월 2일 꼭두새벽에 일어나 태백산을 향해 갔다.&lt;br /&gt;생각보다 엄청 멀었다. 휴게소도 한번 들리고 달리고 달려 10시쯤 도착할 수 있었다.&lt;br /&gt;태백산을 가기 전, 태백산국립공원 사무소에서 무료로! 스탬프 투어 여권을 발급 받았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5778.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pW6ma/btsmtNYNVJK/kPKfSLqrzdAKHnQrauQJH0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pW6ma/btsmtNYNVJK/kPKfSLqrzdAKHnQrauQJH0/img.jpg&quot; data-alt=&quot;국립공원 스탬프 투어 여권&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pW6ma/btsmtNYNVJK/kPKfSLqrzdAKHnQrauQJH0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpW6ma%2FbtsmtNYNVJK%2FkPKfSLqrzdAKHnQrauQJH0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;519&quot; data-filename=&quot;IMG_5778.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;국립공원 스탬프 투어 여권&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 여권들은 산 버전이 있고 섬+바다 버전이 있다.&lt;br /&gt;각 지점마다 사무소에서 받거나 국립공원의 경우 등산로 입구에서 받을 수 있다.&lt;br /&gt;나는 이날 처음 발급 받아서 태백산에 도장을 찍었다 ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_11AD1BCB6A55-1.jpeg&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by8OsJ/btsmmRvgkQx/EMkiydEk1dN91pMmSpS910/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by8OsJ/btsmmRvgkQx/EMkiydEk1dN91pMmSpS910/img.jpg&quot; data-alt=&quot;태백산 등산 루트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by8OsJ/btsmmRvgkQx/EMkiydEk1dN91pMmSpS910/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby8OsJ%2FbtsmmRvgkQx%2FEMkiydEk1dN91pMmSpS910%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;802&quot; data-filename=&quot;IMG_11AD1BCB6A55-1.jpeg&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2373&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;태백산 등산 루트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;태백산 등산루트는 정상까지 오르고 원점회귀하는 것이 아니라 오른편으로 쭉 돌아오는 루트를 선택했다.&lt;br /&gt;천천히 오르기도 했고, 쉬엄쉬엄 올라가는데도 4시간 정도 나왔다. 중간에 계곡도 들러 발도 담군시간도 포함되어있다.&lt;br /&gt;한가지 단점? 이라면 내려오는 길에 계단이 없어서 중간에 몇 번 미끌어질 뻔 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5780.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d0Dl3P/btsmtdcl9Br/Ex27Spo1Msfd5u0qcOE1k0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d0Dl3P/btsmtdcl9Br/Ex27Spo1Msfd5u0qcOE1k0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d0Dl3P/btsmtdcl9Br/Ex27Spo1Msfd5u0qcOE1k0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd0Dl3P%2Fbtsmtdcl9Br%2FEx27Spo1Msfd5u0qcOE1k0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;672&quot; data-filename=&quot;IMG_5780.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;유일사 탐방로에서 출발하여 위에 보이는 언덕으로 쭉 올라갔다.&lt;br /&gt;국립공원답게 길이 잘 되어 있어서 올라가는 내내 너무 편했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5801.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uSZJu/btsmtPCkvKw/NSBJPgUnWU024jtYojgWkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uSZJu/btsmtPCkvKw/NSBJPgUnWU024jtYojgWkK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uSZJu/btsmtPCkvKw/NSBJPgUnWU024jtYojgWkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuSZJu%2FbtsmtPCkvKw%2FNSBJPgUnWU024jtYojgWkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;736&quot; data-filename=&quot;IMG_5801.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;오르다보니 장군봉이 눈앞에 나를 반기고 있었다. 해발은 정말 높지만 사실 시작한 위치가 높아서 수월하게 오를 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5846.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4dAs5/btsmteoOYXr/JWrv5qZTqlgFJESqMO9cE0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4dAs5/btsmteoOYXr/JWrv5qZTqlgFJESqMO9cE0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4dAs5/btsmteoOYXr/JWrv5qZTqlgFJESqMO9cE0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4dAs5%2FbtsmteoOYXr%2FJWrv5qZTqlgFJESqMO9cE0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;808&quot; data-filename=&quot;IMG_5846.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;장군봉을 지나고 오면 천제단 곳이 있는데 그 곳에서 바라본 뷰다.&lt;br /&gt;사진으로는 도저히 담을 수 없는 태백산만의 아름다운 여름 풍경을 가지고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5861.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkN4GH/btsmtOXHmWZ/KFaSJz4i6pk0THl8YJvFbk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkN4GH/btsmtOXHmWZ/KFaSJz4i6pk0THl8YJvFbk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkN4GH/btsmtOXHmWZ/KFaSJz4i6pk0THl8YJvFbk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkN4GH%2FbtsmtOXHmWZ%2FKFaSJz4i6pk0THl8YJvFbk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;572&quot; height=&quot;763&quot; data-filename=&quot;IMG_5861.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;태백산이라는 큰 비석이 있어서 인증샷으로 찍기 너무 좋았다.&amp;nbsp;&lt;br /&gt;심지어 이날은 여름이라 그런가 사람이 없어서 너무 편했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_5917.jpg&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUAYg0/btsmnOLLRgC/Gg2oiZfHeJGUrbcTAmXkJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUAYg0/btsmnOLLRgC/Gg2oiZfHeJGUrbcTAmXkJ0/img.jpg&quot; data-alt=&quot;먼 경치를 바라보는 나?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUAYg0/btsmnOLLRgC/Gg2oiZfHeJGUrbcTAmXkJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUAYg0%2FbtsmnOLLRgC%2FGg2oiZfHeJGUrbcTAmXkJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;700&quot; data-filename=&quot;IMG_5917.jpg&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;먼 경치를 바라보는 나?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;등산에 취미를 가진다는 상상을 해본적도 없었지만 우연치 않게 산을 몇번 와보니&lt;br /&gt;왜 사람들이 산을 찾아 다니는지 조금은 알 것 같다.&lt;br /&gt;보는 맛과 오르는 맛, 또 다리와 종아리에 차오르는 근육통.. 짜릿해..&lt;br /&gt;처음으로 100대 명산 인증도 해보고, 등산 어플도 깔아서 등록 해보았다.&lt;br /&gt;앞으로 더 많은 산들을 안전하고 건강하게 등반 해봐야겠다!&lt;/p&gt;</description>
      <category>여행/등산</category>
      <category>등산</category>
      <category>태백산</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/77</guid>
      <comments>https://youngchangoon.tistory.com/77#entry77comment</comments>
      <pubDate>Tue, 4 Jul 2023 20:46:02 +0900</pubDate>
    </item>
    <item>
      <title>돌이킬 수 있는 - 문목하</title>
      <link>https://youngchangoon.tistory.com/76</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20220828_140352217.jpg&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9MdiF/btrLhtXsMVj/My9PdEtdwvAFpeHKD6CSXk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9MdiF/btrLhtXsMVj/My9PdEtdwvAFpeHKD6CSXk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9MdiF/btrLhtXsMVj/My9PdEtdwvAFpeHKD6CSXk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9MdiF%2FbtrLhtXsMVj%2FMy9PdEtdwvAFpeHKD6CSXk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;657&quot; data-filename=&quot;KakaoTalk_20220828_140352217.jpg&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;책 소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지인의 추천으로 읽은 첫 번째 한국 SF소설이다. 싱크홀 사고 이후 초능력을 얻게 된 사람들과 그 사실이 세상 바깥으로 나오지 않게 하려는 섹션, 그리고 초능력자들을 중심으로 생긴 비원이라는 조직까지 &amp;lsquo;윤서리' 라는 주인공을 통해 이야기가 빠르게 전개되며 놀랄만한 반전까지&amp;hellip; 숨 쉬지 않고 읽은 소설이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;세 가지 능력&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소설에선 세 가지 능력이 존재한다. 모든 것을 부수는 파쇄자, 멈추는 정지자, 제자리에 돌려놓는 복원자.. 작가의 능력의 표현이나 서술 등이 너무나도 생생하게 다가왔다. 참신하고 재밌는 설정들도 많았지만 단순 우연히 일어난 일이 아니라 그럴싸한 원인이 있어서 더 몰입감 있게 보았다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;싱크홀 속 두 그룹&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처참한 상황 속 정여준과 최주상의 그룹은 정반대의 정치를 이룬다. 정여준은 힘으로 지배하는 정치가 아닌 수평적이고 민주적이지만, 최주상은 비원이라는 조직을 만들어 끔찍한 수직구조와 독재 정치를 한다. 두 정치의 대비되는 상황들이 재미있었다. 독재 속에선 항상 반란의 위험과 배신이 도사리고 있지만, 민주적인 경선산성에선 오히려 따뜻하고 서로를 애틋하게 봐주는 장면이 인상 깊었다. 두 그룹 중 선택할 기회가 온다면 나는 어디로 갈까? 안전하지만 공포조직인 비원, 외부의 위협으로 안전하지 않지만 서로를 챙기고 따뜻한 경선산성, 정말 고르기 어려울 것 같다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결국은.. 살아남기 위한 행동일뿐&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서형우라는 형사는 매우 악질스러운 캐릭터로 묘사된다. 또한 섹션의 있는 차세영, 차세욱도 마찬가지.. 자신의 안위가 보장된다면 어떠한 행동도 할 인물들이다. 싱크홀 자체가 국가 기밀 사항인데다 사실이 새 나가는 즉시 죽는 것도 알기에 더 처절하게 묘사되었던거 같다. 살기 위해 누군가를 죽여야 한다면, 눈 하나 깜짝하지 않고 죽일 사람들이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주인공의 반전 능력과 놀랄만한 후반 전개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소설의 중반부로 들어서면 주인공의 정체와 능력을 알게 된다. 주인공은 시간을 복원할 수 있는 능력자고, 모든 능력보다 가장 우위에 있었다. 읽다 보면 소설 첫 부분으로 돌아온 듯한 느낌을 받기도 한다. 결국 윤서리의 수많은 반복 끝에 소설이 여기까지 굴러올 수 있었던 것이었던 부분에서 소름이 돋았다. 또한 냉혈한 같았던 최주상에게도 윤서리는 아킬레스 같은 존재였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정여준과 윤서리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 윤서리는 끝까지 정여준을 살리기 위해 반복되는 일생을 무한히 반복한다. 매 순간 정여준이 죽임을 당할 때마다 윤서리는 계속 시간을 돌린다. 여기서 정여준 또한 시간을 멈출 수 있는 정지자였다. 그는 죽지 않기 위해 시간을 멈췄고, 윤서리는 시간을 되돌리게 되어 정여준이라는 사람은 계속 복제되고 있었다. 그 사실을 알면서도 정여준은 묵묵히 그녀가 성공하기를 기다려준다. 결국 기존의 틀을 깨부수고서야 윤서리는 정여준을 살릴 수 있었다. 최주상은 우리의 입장이 되어 정여준에게 왜 이렇게까지 하는지 물어본다. 정여준은 이런 말을 남기며 이 소설을 마친다. &amp;ldquo;왜겠어요?&amp;rdquo;&lt;/p&gt;</description>
      <category>리뷰/책 독후감</category>
      <category>느낀점</category>
      <category>독후감</category>
      <category>돌이킬수있는</category>
      <category>서평</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/76</guid>
      <comments>https://youngchangoon.tistory.com/76#entry76comment</comments>
      <pubDate>Sat, 3 Sep 2022 11:11:18 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] Android AAB 150mb 이상일 때 추가 코드 없이 Addressable과 함께 처리하기</title>
      <link>https://youngchangoon.tistory.com/75</link>
      <description>&lt;h1&gt;문제&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 개발을 하다보면 Android AAB 빌드 용량이 150mb를 넘기는 순간이 온다. 이 때부터 개발자는 AAB내 base파일과 리소스 파일을 분리하여 base파일을 150mb가 넘어가지 않도록 수정해야 한다.&lt;/p&gt;
&lt;h1&gt;해결&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Play Asset Delivery&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드에서는 이런 문제를 해결 하기 위해 &lt;a href=&quot;https://developer.android.com/guide/playcore/asset-delivery?hl=ko&quot;&gt;PAD(Play Asset Delivery)&lt;/a&gt;를 지원한다. PAD는 구글플레이에서 지원하는 애셋 호스팅 서비스다. 이 서비스를 사용하면 따로 CDN을 쓰지 않아도 쉽고 간편하게 애셋을 올릴 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전송 모드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PAD는 총 3가지의 전송 모드를 지원한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;install-time: 앱이 설치될때 같이 전송된 된다. google play의 앱 크기에 영향을 미친다. ( 최대 1GB )&lt;/li&gt;
&lt;li&gt;fast-follow: 앱이 설치되는 즉시 자동으로 다운로드 된다. ( 최대 512MB )&lt;/li&gt;
&lt;li&gt;on-demand: 애셋팩은 앱이 실행 되는 동안 원하는 시점에 다운로드 된다. ( 최대 512MB )&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Addressable + PAD Plugin 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Unity-Technologies/Addressables-Sample&quot;&gt;https://github.com/Unity-Technologies/Addressables-Sample&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 Github에 들어가서 Addressable-Sample을 다운받는다. Unity공식 가이드를 많이 참고하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 잘 살펴보면 Advanced/Play Asset Delivery라는 폴더가 있는데 이 폴더를 통째로 자신 프로젝트의 최상단인 Assets/ 경로에 복사한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Plugin 설정&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Addressable 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.23.09.png&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xf8K5/btrCAwvLdwP/nvBKCFtVDvhpqwKXblTiv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xf8K5/btrCAwvLdwP/nvBKCFtVDvhpqwKXblTiv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xf8K5/btrCAwvLdwP/nvBKCFtVDvhpqwKXblTiv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxf8K5%2FbtrCAwvLdwP%2FnvBKCFtVDvhpqwKXblTiv0%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;694&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.23.09.png&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Assets/PlayAssetDelivery/Data에 들어있는 Setting값들을 위와같이 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.26.47.png&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HNCT5/btrCCgekYfn/lWV4rwNuLvb68ZbGAXelb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HNCT5/btrCCgekYfn/lWV4rwNuLvb68ZbGAXelb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HNCT5/btrCCgekYfn/lWV4rwNuLvb68ZbGAXelb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHNCT5%2FbtrCCgekYfn%2FlWV4rwNuLvb68ZbGAXelb1%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;416&quot; height=&quot;200&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.26.47.png&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Addressable Group Window에서 [Create] - [Group] - [Asset Pack Content]를 눌러 AssetGroup을 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.29.44.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5mUCl/btrCBOijC53/EK5MpT49IbyjPJkFMkmHK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5mUCl/btrCBOijC53/EK5MpT49IbyjPJkFMkmHK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5mUCl/btrCBOijC53/EK5MpT49IbyjPJkFMkmHK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5mUCl%2FbtrCBOijC53%2FEK5MpT49IbyjPJkFMkmHK0%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;1526&quot; height=&quot;896&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.29.44.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;896&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위와 같이 Build Path와 Load Path는 &lt;b&gt;Local&lt;/b&gt;로 설정한다.&lt;/li&gt;
&lt;li&gt;[Add Schema]를 눌러 Play Asset Delivery를 누른 후 &lt;b&gt;InstallTimeContent&lt;/b&gt;로 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.35.07.png&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2jkmO/btrCCe1RIUJ/hiFdBeoDxLwUg45lTI4Odk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2jkmO/btrCCe1RIUJ/hiFdBeoDxLwUg45lTI4Odk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2jkmO/btrCCe1RIUJ/hiFdBeoDxLwUg45lTI4Odk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2jkmO%2FbtrCCe1RIUJ%2FhiFdBeoDxLwUg45lTI4Odk%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;1492&quot; height=&quot;900&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.35.07.png&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 Asset Inspector창에서 &lt;b&gt;Advanced Options&lt;/b&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;Asset Provider - &lt;b&gt;Assets from Bundles Provider&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Asset Bundle Provider - &lt;b&gt;Play Asset Delivery Provider&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;안드로이드 설정&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[PlayerSettings]를 들어가 &lt;b&gt;Split Application Binary&lt;/b&gt;를 꼭 체크&lt;/li&gt;
&lt;li&gt;Custom Launcher Gradle Template를 체크한 후 launcherTemplate.gradle 파일에 들어가 buildTypes 부분에 &lt;b&gt;PLAY_ASSET_PACKS&lt;/b&gt;를 추가해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.54.36.png&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIevax/btrCDIHWtdw/fBCkaQwnNQxLWYvNiWSqiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIevax/btrCDIHWtdw/fBCkaQwnNQxLWYvNiWSqiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIevax/btrCDIHWtdw/fBCkaQwnNQxLWYvNiWSqiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIevax%2FbtrCDIHWtdw%2FfBCkaQwnNQxLWYvNiWSqiK%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;1396&quot; height=&quot;482&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.54.36.png&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빌드 및 확인&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.39.36.png&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uI4sN/btrCEes3v9u/AkPGmUhJ0FWkYks1MsmTVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uI4sN/btrCEes3v9u/AkPGmUhJ0FWkYks1MsmTVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uI4sN/btrCEes3v9u/AkPGmUhJ0FWkYks1MsmTVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuI4sN%2FbtrCEes3v9u%2FAkPGmUhJ0FWkYks1MsmTVK%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;628&quot; height=&quot;224&quot; data-filename=&quot;스크린샷 2022-05-04 오후 5.39.36.png&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 세팅이 끝나면 Addressable 윈도우 창에서 [New Build] - [Play Asset Delivery]를 눌러준다. 이 빌드가 완료되면 기존처럼 AAB파일을 빌드한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;리소스 분할이 잘 적용되어 있는지 확인하는법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.aab파일을 .zip파일로 변환한후 압축을 해제한다. 해제 후 폴더 안에 &lt;b&gt;UnityDataAssetPack&lt;/b&gt; 파일이 있는지 확인한다.&lt;/p&gt;</description>
      <category>프로그래밍/Unity</category>
      <category>150mb</category>
      <category>AAB</category>
      <category>Android</category>
      <category>build</category>
      <category>C#</category>
      <category>Unity</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/75</guid>
      <comments>https://youngchangoon.tistory.com/75#entry75comment</comments>
      <pubDate>Thu, 19 May 2022 21:35:26 +0900</pubDate>
    </item>
    <item>
      <title>뒤끝 비동기 함수와 C# Promise 사용하기</title>
      <link>https://youngchangoon.tistory.com/74</link>
      <description>&lt;h1&gt;뒤끝에서 서버 API를 사용하는 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤끝에서 서버 API를 사용하는 방법은 총 3가지다.&lt;/p&gt;
&lt;ol 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;SendQueue(비동기) 호출&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도가 가장 쉽고 직관적인건 1번이지만 서버 값을 받아올 때까지 게임이 멈추기에 그렇게 좋은 방법은 아니다. 그렇다면 비동기호출을 해야하는데, 보낸 순서대로 순서를 보장 받을 수 있는 SendQueue방식의 호출을 게임을 개발하며 주로 사용했다.&lt;/p&gt;
&lt;h1&gt;Promise 패턴&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Promise 패턴은 여러 비동기 함수들을 쉽게 관리할 수 있게 하는 패턴이다. Promise 객체는 처리에 대한 결과 상태를 반환하고, 작업의 종료시점을 알 수 있게 된다. Promise객체의 상태는 크게 3가지다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pending - 작업이 완료되지 않은 상태.&lt;/li&gt;
&lt;li&gt;Resolved - 작업이 성공적으로 완료된 상태.&lt;/li&gt;
&lt;li&gt;Rejected - 작업 도중 에러가 나서 실패한 상태.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 상태에 맞춰 작업을 처리하고, Promise끼리 연결을 통해 여러 비동기 작업들의 끝나는 시점들을 제어할 수 있다. 무엇보다 가장 큰 장점은 &lt;a href=&quot;https://librewiki.net/wiki/%EC%BD%9C%EB%B0%B1_%EC%A7%80%EC%98%A5&quot;&gt;callback지옥&lt;/a&gt; 코드에서 벗어날 수 있고, 비동기들의 관리가 쉽다는 점이다.&lt;/p&gt;
&lt;h1&gt;뒤끝 비동기 호출(SendQueue) + Promise 패턴 사용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤끝에서 비동기를 호출하면서 Promise패턴을 사용하면 callback지옥에서 벗어날 수 있다. 비동기 호출이 완료될 때까지 promise상태를 pending으로 두었다가 정상적인 response를 받으면 resolve하게 한다. 뒤끝의 비동기 호출과 Promise를 사용하는 예제를 확인해보자.&lt;/p&gt;
&lt;pre class=&quot;cs&quot; data-ke-language=&quot;cs&quot;&gt;&lt;code&gt;// 로그인 서비스 예제
public class LoginService
{
	public IPromise GuestLogin()
	{
		var promise = new Promise();
		SendQueue.Enqueue(Backend.BMember.GuestLogin, &quot;게스트 로그인&quot;, bro =&amp;gt; 
        {
            if (bro.IsSuccess())
            {
                Debug.Log($&quot;게스트 로그인 성공!&quot;);
                promise.Resolve();
            }
            else
            {
                Debug.Log($&quot;게스트 로그인 실패!&quot;);
                promise.Reject(new Exception(&quot;게스트 로그인 실패&quot;));
        });

		return promise;
	}
}

public class Main
{
    public LoginService loginService;

    public void OnPressedGuestLoginButton()
	{
		// 게스트 로그인을 시도후 완료되면 Then 함수를 호출
		loginService.GuestLogin().Then(() =&amp;gt; 
		{
			// 로그인 완료 후 처리.
			// 이곳에 또 Promise를 만들어 연결 할 수 있다.
		});
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;</description>
      <category>프로그래밍/C#</category>
      <category>C#</category>
      <category>Promise</category>
      <category>뒤끝</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/74</guid>
      <comments>https://youngchangoon.tistory.com/74#entry74comment</comments>
      <pubDate>Wed, 16 Feb 2022 22:49:51 +0900</pubDate>
    </item>
    <item>
      <title>[Android] .AAB 파일에서 .APK 파일로 변환 하는 법</title>
      <link>https://youngchangoon.tistory.com/73</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;변환하는 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티에서 Google Play Store에 올리기 위해서는 .aab 파일로 빌드해야한다. 하지만 .aab파일로는 스토어에 올리지 않는한 로컬 기기에 설치해서 테스트 해볼 수 없다. 따라서 .apk로 변환해주는 작업이 필요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;변환 하는 방법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래 Github주소로 들어가서 알맞는 버전을 다운 받는다.&lt;/li&gt;
&lt;li&gt;터미널이나 명령프롬포트 창(cmd) 을 이용하여 아래 명령어를 넣어준다. &lt;span style=&quot;background-color: #99cefa;&quot;&gt;bundletool-all-1.8.0&lt;/span&gt; 부분과 &lt;span style=&quot;background-color: #99cefa;&quot;&gt;AAB파일이름.aab&lt;/span&gt; 부분을 알맞게 수정해준다.&lt;br /&gt;
&lt;pre id=&quot;code_1634644507185&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -jar &quot;bundletool-all-1.8.0.jar&quot; build-apks &amp;mdash;bundle=&quot;AAB파일이름.aab&quot; &amp;mdash;output=&quot;universal.apks&quot; &amp;mdash;mode=universal&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;나온 universal.apks 확장자 파일을 .zip로 바꿔준다.&lt;/li&gt;
&lt;li&gt;.zip파일을 풀어 .apk파일을 실행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure id=&quot;og_1634639259307&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Releases &amp;middot; google/bundletool&quot; data-og-description=&quot;Bundletool is a command-line tool to manipulate Android App Bundles - google/bundletool&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/google/bundletool/releases&quot; data-og-url=&quot;https://github.com/google/bundletool/releases&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/guWng/hyL2BZpkhA/yIrYFrzSRWUleCQgPSo710/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/google/bundletool/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/google/bundletool/releases&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/guWng/hyL2BZpkhA/yIrYFrzSRWUleCQgPSo710/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Releases &amp;middot; google/bundletool&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Bundletool is a command-line tool to manipulate Android App Bundles - google/bundletool&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍</category>
      <category>Android</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/73</guid>
      <comments>https://youngchangoon.tistory.com/73#entry73comment</comments>
      <pubDate>Tue, 19 Oct 2021 20:56:10 +0900</pubDate>
    </item>
    <item>
      <title>[C#] 소수점 Parsing 할 때, (float.Parse, double.Parse) 언어에 따른 소수점 에러</title>
      <link>https://youngchangoon.tistory.com/72</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;float.Parse() 함수를 사용할 때 러시아, 스페인등 지역에서 파싱 에러가 난다.&lt;/p&gt;
&lt;pre id=&quot;code_1634638483872&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FormatException: Input string was not in a correct format. at System.Number.ParseSingle (System.String value, System.Globalization.NumberStyles options, System.Globalization.NumberFormatInfo numfmt)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#에는 사용자의 문화권에 따라 , 나 . 를 사이에 사용한다. 만약 사용자의 언어 환경이 다른 숫자 표기법을 사용하는 국가라면 string에서 float나 double로 파싱할때 특정 언어 환경에서만 에러가 난다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CultureInfo.InvariantCulture 변수를 사용하면 문화권에 영향을 안받게 처리할 수 있다. Parsing할때 한번만 적용하거나 현재 작동하고 있는 쓰레드안에 있는 전체 메소드의 문화권에 적용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1634638456444&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 메소드 하나에 적용할때
float.Parse(&quot;12312313&quot;, CultureInfo.InvariantCulture);

// 현재 쓰레드에 전체 적용할때
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/C#</category>
      <category>C#</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/72</guid>
      <comments>https://youngchangoon.tistory.com/72#entry72comment</comments>
      <pubDate>Tue, 19 Oct 2021 19:15:00 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 모순을 읽고 느낀 점과 줄거리, 인상 깊었던 구절들</title>
      <link>https://youngchangoon.tistory.com/71</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-filename=&quot;KakaoTalk_20210930_225418478.jpg&quot; width=&quot;345&quot; height=&quot;460&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3tXP8/btrgvS6uK54/HqR0A6nyBktdc8xVlc3qr1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3tXP8/btrgvS6uK54/HqR0A6nyBktdc8xVlc3qr1/img.jpg&quot; data-alt=&quot;모순 - 양귀자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3tXP8/btrgvS6uK54/HqR0A6nyBktdc8xVlc3qr1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3tXP8%2FbtrgvS6uK54%2FHqR0A6nyBktdc8xVlc3qr1%2Fimg.jpg&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-filename=&quot;KakaoTalk_20210930_225418478.jpg&quot; width=&quot;345&quot; height=&quot;460&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모순 - 양귀자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜만에 다시 책을 들고 읽었다. 출퇴근 시간마다 핸드폰 사용을 줄이고 독서를 했는데 정말 시간 가는줄 모르고 읽었다. 독서하는 습관을 다시 잡아준 아주 고마운 책이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;책의 줄거리&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인생은 살아가면서 탐구하는 것이다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 소설의 주인공 안진진, 하루를 가장 열심히 사시는 어머니와 집을 나간 채 돌아오지 않는 아버지 밑에서 매일같이 조폭 흉내만 내는 남동생을 하나 둔 주인공이다. 그냥저냥 살아가던 주인공은 좋아하는 취미 하나 없이 무미건조한 삶을 살아갔다. 올해 25살을 맞으면서 정신이 번쩍 든 주인공은 자신의 현재 삶을 고찰하며 앞으로 자신에게 조금 더 관심을 가지며 전 생애를 걸어서라도 인생을 탐구하며 살아가기로 한다.&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;h3 data-ke-size=&quot;size23&quot;&gt;어릴 적 아버지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아버지는 술을 마시기 전에는 그 누구보다 다정한 사람이었다. 하지만 술만 마시면 모든 물건을 다 집어 던지고, 어머님을 때렸다. 그런 아버지가 미울법한 주인공이지만 주인공은 아버지를 미워하지 않았다. 어릴적 추억을 더 따뜻하게 간직하고 언젠가 맞춰볼 손바닥만을 기다린 채 아버지가 돌아오기를 기다렸다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그녀 앞의 두 남자&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주인공에게는 너무나도 다른 두 남자가 있었다. 한 사람은 김장우, 레스토랑 알바를 하다가 우연히 만나게 되어 연락하게 되었는데 정말 자상하고 좋지만 안정적이지 않은 직장과 가난한 가정을 가지고 있다. 주인공은 멋있는 김장우에게 자신의 안 좋은 모습들을 보여주기 싫어한다. 또 한 남자는 나영규, 안정적인 직장과 모든 일을 계획하고 살아가는 인물이다. 데이트를 할 때도 자신의 계획 속에서 움직이기 때문에 주인공은 그런 나영규를 좋지 않게 본다. 쉽게 생각해서일까, 나영규에겐 자신의 안 좋은 일까지 모두 털어놓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작 중에는 두 남자의 성격이 아버지와 이모부를 연상케 하는 것 같다. 이모와 속마음을 공유하는 사이인 주인공은 다 가졌지만, 불행한 이모를 보면서 계획적인 나영규보다는 순박한 김장우를 더 좋아하게 된다. 하지만 이모가 죽고 난 이후, 주인공은 모순적이게도 나영규에게 시집을 가게 된다. 주인공은 불행할 걸 알지만 어쩌면 살아보지 않은 세상을 함부로 판단하지는 않았는가에 대해 생각하면서 소설은 끝이 난다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;느낀 점&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책을 처음 다 읽고, 정말 치밀하게 짜인 현실감 있는 소설을 읽은 기분이었다. 한 소설에도 주인공 이야기뿐만 아니라 다양한 인물들의 이야기가 자세히 녹아들어 여러 시점에서 생각해볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 이모와 어머니 이야기는 똑 닮은 쌍둥이로 태어나 전혀 다른 길을 걸으면서 서로에 대한 행복과 불행이 교차하는 전개가 인상 깊었다. 누구나 부러울법한 인생을 살고 있지만, 자식들은 유학 가고 철저히 계획적인 남편 때문에 삶의 재미가 없는 이모, 남편은 도망가고 아들은 감방에 가고, 하루하루가 지옥 같지만 그곳에서도 삶의 희망을 놓지 않고 행복을 찾는 어머니. 내가 만약 선택할 수 있다면 사실 그래도 이모의 삶을 선택할 것 같다. 하루하루가 아무리 노력해도 더 나아지지 않는 삶을 살다 보면 포기하고 싶은 순간이 이모의 삶보다 더 많이 찾아올 것 같다. 이모가 마지막에 죽음을 선택한 건 개인적으로 조금 의외의 결말이었다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이야기를 이어서 왜 주인공이 그토록 사랑했던 김장우를 선택하지 않고, 나영규를 선택했는지에 대해 생각도 해보았다. 주인공은 자라면서 물질적인 불행을 많이 보고 느끼고 자라왔을 것이다. 열심히 어머님이 벌어와도 돈만 홀랑 빼가는 아버지, 말썽만 피우고 감방에 들어가서 어머님의 등골을 빼먹는 남동생, 이런 집안에서 어떻게 원하는 거 한번 사고 살 수 있었을까, 심지어 직장도 이모부의 회사로 들어갔다. 물질적인 행복을 얻어보지도 못한 주인공은 김장우를 정말 사랑하지만 아마 이런 이유로 나영규를 선택하는 계기가 되었지 않았을까 조심스레 추측해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 세상을 조금 더 완벽하게 살고 싶지만, 항상 계획대로 되지 않고 인생은 항상 실수의 반복이다. '모순'에서도 우리가 '경험' 해보지 않고 미리 앞서서 예측해보지만, 항상 뜻대로 되지 않는 게 인생이라고 한다. 따라서 우리는 반대로 '경험'을 통해서 인생을 배우고 '탐구'하며 살아가야 하지 않을까?&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;감명 깊은 구절&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P75. 아껴서 좋은 건 돈만이 아니었다. 어쩌면 돈보다 더 아껴야 할 것은 우리가 아무 생각 없이 내뱉는 말들이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P127. 사람들은 작은 상처는 오래 간직하고 큰 은혜는 얼른 망각해버린다. 상처는 꼭 받아야할 빚이라고 생각하고 은혜는 꼭 돌려주지 않아도 될 빚이라고 생각하기 때문이다. 대부분의 사람들은 인생의 장부책 계산을 그렇게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P152. 소소한 불행과 대항하여 싸우는 일보다 거대한 불행 앞에서 무릎을 꿇는 일이 훨씬 견디기 쉽다는 것을 어머니는 이미 체득하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P188. 상처 입은 사람들을 위로하는 것은 말이 아니었다. 상처는 상처로 위로해야 가장 효험이 있는 법이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P209. 사랑이란, 집에서나 회사에서나 거리에서나 비어있는 모든 전화기 앞에서 절대 자유롭지 못한 것이다. 사랑이란, 버스에서나 거리에서 또는 라디오에서 흘러나오는 모든 유행가의 가사에 시도때도 없이 매료당하는 것이다. 사랑이란, 발견할 수 있는 모든 거울 앞에서 자신의 얼굴을 들여다보지 않고 무심히 지나칠 수 없게 만드는 무엇이다. 사랑이란 그러므로 붉은 신호등이다. 켜지기만 하면 무조건 멈춰야하는, 위험을 예고하면서 동시에 안전도 예고하는 붉은 신호등이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P291. 우리는 크고 작은 액자 안에 우리의 지나간 시간들을 걸어놓으며 앞으로 앞으로 걸어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P296. 인생은 탐구하면서 살아가는 것이 아니라, 살아가면서 탐구하는 것이다. 실수는 되풀이된다. 그것이 인생이다.&lt;/p&gt;</description>
      <category>리뷰/책 독후감</category>
      <category>독서</category>
      <category>독후감</category>
      <category>모순</category>
      <category>서평</category>
      <category>양귀자</category>
      <category>책리뷰</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/71</guid>
      <comments>https://youngchangoon.tistory.com/71#entry71comment</comments>
      <pubDate>Thu, 30 Sep 2021 23:08:37 +0900</pubDate>
    </item>
    <item>
      <title>[Unity] 유니티 MVC 패턴 적용하기</title>
      <link>https://youngchangoon.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;Unity로 게임을 만들다 보면 필연적으로 데이터와 로직이 결합된 상태로 개발하게 된다.&lt;br /&gt;프로젝트가 커질수록 점점 코드는 복잡해지고, 데이터와 로직이 뒤섞여 더 이상 유지보수가 힘든 상황이 이르게 된다.&lt;br /&gt;따라서 데이터(Model)와 로직(Controller)을 분리해주는 패턴으로부터 개발을 시작하는 게 좋다.&lt;/p&gt;
&lt;h2&gt;MVC 패턴&lt;/h2&gt;
&lt;p&gt;MVC 패턴은 &lt;b&gt;Model&lt;/b&gt;과 &lt;b&gt;View&lt;/b&gt;, 그리고 둘을 잇는 &lt;b&gt;Controller&lt;/b&gt;라는 요소가 들어있는 패턴이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbWMqL/btq2XjX54F3/wp9xWjbcXW1r29Vckw4OT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbWMqL/btq2XjX54F3/wp9xWjbcXW1r29Vckw4OT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbWMqL/btq2XjX54F3/wp9xWjbcXW1r29Vckw4OT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbWMqL%2Fbtq2XjX54F3%2Fwp9xWjbcXW1r29Vckw4OT1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Model&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;게임의 &lt;span style=&quot;color: #006dd7;&quot;&gt;데이터&lt;/span&gt;가 되는 요소&lt;/li&gt;
&lt;li&gt;로직이 아닌 순수 데이터가 들어가야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Controller&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;게임의 핵심 &lt;span style=&quot;color: #006dd7;&quot;&gt;로직&lt;/span&gt;들을 담당한다.&lt;/li&gt;
&lt;li&gt;Model들을 조작하고 업데이트된 Model들을 View에 통지해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;View&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;게임 내 &lt;span style=&quot;color: #006dd7;&quot;&gt;외적으로 보이는 모든 요소&lt;/span&gt;들이다.&lt;/li&gt;
&lt;li&gt;Controller에서 받은 데이터들을 화면에 출력하는 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 결합도를 줄이기 위해 &lt;span style=&quot;color: #006dd7;&quot;&gt;Model과 View는 Controller의 존재를 몰라야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Unity에 적용하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유니티(C#)에 적용하기 위해선 앞서 구현되어야 할 몇 가지 필요 사항이 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Model의 변화를 View가 감지해야 함&lt;/li&gt;
&lt;li&gt;View에서 발생되는 Event를 Controller에 전달해야 함.&lt;/li&gt;
&lt;li&gt;각각 Controller들끼리 쉬운 통신이 되어야 함.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 조건들을 충족시키는 애셋이 있는데 바로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&quot;Zenject&quot;, &quot;UniRx&quot;&lt;/span&gt;라는 애셋이다.&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://github.com/modesttree/Zenject&quot;&gt;Zenject (Extenject)&lt;/a&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1618737827167&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;modesttree/Zenject&quot; data-og-description=&quot;Dependency Injection Framework for Unity3D . Contribute to modesttree/Zenject development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/modesttree/Zenject&quot; data-og-url=&quot;https://github.com/modesttree/Zenject&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dt8NjK/hyJURdoJhs/sQPE921HpZsL0rRYIgvotK/img.png?width=248&amp;amp;height=248&amp;amp;face=0_0_248_248,https://scrap.kakaocdn.net/dn/dRctcB/hyJU35VzKz/S4Ord4ceijIrOsfrCBz83K/img.png?width=2700&amp;amp;height=702&amp;amp;face=0_0_2700_702&quot;&gt;&lt;a href=&quot;https://github.com/modesttree/Zenject&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/modesttree/Zenject&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dt8NjK/hyJURdoJhs/sQPE921HpZsL0rRYIgvotK/img.png?width=248&amp;amp;height=248&amp;amp;face=0_0_248_248,https://scrap.kakaocdn.net/dn/dRctcB/hyJU35VzKz/S4Ord4ceijIrOsfrCBz83K/img.png?width=2700&amp;amp;height=702&amp;amp;face=0_0_2700_702');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;modesttree/Zenject&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Dependency Injection Framework for Unity3D . Contribute to modesttree/Zenject development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Zenject는 &lt;span style=&quot;color: #006dd7;&quot;&gt;의존성 주입&lt;/span&gt; (Dependency Injection)이 들어있는 프레임워크다. 프로그램의 초기화 부분에서 미리 어떤 클래스 혹은 인터페이스가 어떤 인스턴스를 받을지 정해놓고, 실행 중에는 서로 다른 구성요소 간 종속성과 통신을 쉽고 느슨하게 관리해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대부분 게임을 만들 때 구성요소 별로 Singleton을 사용하여 관리한다. 그러나 어느 시점에 어떻게 초기화 되는지는 보장할 수 없다. 또한 서비스의 로직이 중간에 바뀔 경우, 수정하기도 매우 번거롭다. &lt;br /&gt;Zenject를 사용하면 초기화 시점이 보장되고, Interface의 할당도 가능하여 쉽게 로직들을 수정할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Zenject에선 의존성 주입 외에도 몇 가지 기능을 더 지원하는데, 그중 &lt;span style=&quot;color: #006dd7;&quot;&gt;Signal&lt;/span&gt;이라는 기능을 사용하면 서로의 클래스를 호출하지 않아도 &lt;span style=&quot;color: #006dd7;&quot;&gt;손쉽게 View와 Controller사이의 통신&lt;/span&gt;을 할 수 있다.&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://github.com/neuecc/UniRx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;UniRx ( Unity + Reactivex )&lt;/a&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1618744459377&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;neuecc/UniRx&quot; data-og-description=&quot;Reactive Extensions for Unity. Contribute to neuecc/UniRx development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/neuecc/UniRx&quot; data-og-url=&quot;https://github.com/neuecc/UniRx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OUPKV/hyJUSwIfvl/HpUkGg2GBHEVMhxR88h981/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iOijA/hyJU0uJVDG/cOz4PLrEVIZQifzuEwRlG0/img.png?width=632&amp;amp;height=612&amp;amp;face=0_0_632_612,https://scrap.kakaocdn.net/dn/fwml2/hyJUQ6Iu13/kyYb3XT7O8vuGviHEjKKR1/img.jpg?width=514&amp;amp;height=426&amp;amp;face=0_0_514_426&quot;&gt;&lt;a href=&quot;https://github.com/neuecc/UniRx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/neuecc/UniRx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OUPKV/hyJUSwIfvl/HpUkGg2GBHEVMhxR88h981/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iOijA/hyJU0uJVDG/cOz4PLrEVIZQifzuEwRlG0/img.png?width=632&amp;amp;height=612&amp;amp;face=0_0_632_612,https://scrap.kakaocdn.net/dn/fwml2/hyJUQ6Iu13/kyYb3XT7O8vuGviHEjKKR1/img.jpg?width=514&amp;amp;height=426&amp;amp;face=0_0_514_426');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;neuecc/UniRx&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Reactive Extensions for Unity. Contribute to neuecc/UniRx development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;UniRx는 Unity+Rx의 줄임말로, .NET의 &lt;span style=&quot;color: #006dd7;&quot;&gt;Reactive Extensions&lt;/span&gt;을 Unity버전으로 다시 구현한 것이다. Rx는 옵저빙이 가능한 데이터 스트림을 생성해 데이터를 조작하는 프로그래밍 패러다임이다. 이렇게 만듬으로 다루기 힘든 비동기 작업들을 손쉽게 처리하거나, 데이터의 값 변화를 쉽게 캐치할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;MVC 패턴의 구현중 &lt;span style=&quot;color: #333333;&quot;&gt;Model의 값 변화를 캐치하기 위해 &lt;/span&gt;UniRx에서 사용한 기능은 &lt;span style=&quot;color: #006dd7;&quot;&gt;ReactiveProperty&amp;lt;T&amp;gt;&lt;/span&gt; 클래스다.&lt;br /&gt;데이터 스트림을 만들어 값이 변할 때마다 Controller에서 Subscribe을 해주고, View를 호출해 값을 전달해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이외에도 View단에서 UniRx의 이벤트 스트림을 만들어 더블클릭, 입력 시간 감지등 다양한 처리를 할 수 있다.&lt;/p&gt;
&lt;h2&gt;간단한 예시 - 큐브 움직이기&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로젝트 생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우선 Unity 프로젝트를 3D로 생성해본다.&lt;br /&gt;생성 후, 위에선 언급했던 Zenject와 UniRx를 다운로드하고 Scene에는 Cube를 하나 소환한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Zenject - SceneContext 및 MonoIntaller 추가&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;SceneContext.png&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;622&quot; width=&quot;391&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbIgN1/btq22FMyGrz/u3OUioeSzm5l3UJEPH99AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbIgN1/btq22FMyGrz/u3OUioeSzm5l3UJEPH99AK/img.png&quot; data-alt=&quot;Hierarchy에서 오른쪽 마우스를 누른뒤, Zenject-Scene Context&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbIgN1/btq22FMyGrz/u3OUioeSzm5l3UJEPH99AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbIgN1%2Fbtq22FMyGrz%2Fu3OUioeSzm5l3UJEPH99AK%2Fimg.png&quot; data-filename=&quot;SceneContext.png&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;622&quot; width=&quot;391&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Hierarchy에서 오른쪽 마우스를 누른뒤, Zenject-Scene Context&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 사진과 같이 Scene Context를 생성한다. SceneContext는 이 Scene에 들어올 때 제일 처음 실행되는 진입점이다. 이 부분에 MonoInstaller를 추가해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;MonoInstaller.png&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;382&quot; width=&quot;727&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/26cwP/btq22bx0W5H/Lqdcl71xue8kkAJLhUpqVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/26cwP/btq22bx0W5H/Lqdcl71xue8kkAJLhUpqVK/img.png&quot; data-alt=&quot;Project뷰에서 오른쪽 마우스를 누르고 Create-Zenject-Mono Installer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/26cwP/btq22bx0W5H/Lqdcl71xue8kkAJLhUpqVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F26cwP%2Fbtq22bx0W5H%2FLqdcl71xue8kkAJLhUpqVK%2Fimg.png&quot; data-filename=&quot;MonoInstaller.png&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;382&quot; width=&quot;727&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Project뷰에서 오른쪽 마우스를 누르고 Create-Zenject-Mono Installer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Zenject에서 제공하는 Create 메뉴를 이용하여 코드를 생성한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;넣고 저장.png&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;633&quot; width=&quot;230&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPzaiX/btq2RkDuXyT/mfUtYNDVt9geRkZWFcEb10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPzaiX/btq2RkDuXyT/mfUtYNDVt9geRkZWFcEb10/img.png&quot; data-alt=&quot;Mono Installers에 추가!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPzaiX/btq2RkDuXyT/mfUtYNDVt9geRkZWFcEb10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPzaiX%2Fbtq2RkDuXyT%2FmfUtYNDVt9geRkZWFcEb10%2Fimg.png&quot; data-filename=&quot;넣고 저장.png&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;633&quot; width=&quot;230&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Mono Installers에 추가!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코드를 생성한 뒤, Add Component로 Installer를 추가해주고, Mono Installers에 추가해준다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Scripting&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Model 부분에선 데이터만 들고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1618837971322&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UniRx;
using UnityEngine;

public class CubeModel
{
    public ReactiveProperty&amp;lt;Vector3&amp;gt; position;

    public CubeModel()
    {
        position = new ReactiveProperty&amp;lt;Vector3&amp;gt;(Vector2.zero);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-------&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Controller 부분에선 핵심 로직과 Model과 View의 연결을 담당한다.&lt;/p&gt;
&lt;pre id=&quot;code_1618838155218&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UniRx;
using UnityEngine;
using Zenject;

 // Cube Moving 로직 코드
public class CubeMoveController : IInitializable, ITickable
{
    [Inject] private CubeModel _cubeModel;
    [Inject] private CubeView _cubeView;
    [Inject] private SignalBus _signalBus;

    private float _speed = 5f;

    // 초기화 부분
    public void Initialize()
    {
        // Cube Position 데이터 스트림을 View에서 구독한다.
        _cubeModel.position.Subscribe(_cubeView.UpdateMove);
        
        // View에서 넘어오는 Event를 받아서 처리한다.
        _signalBus.Subscribe&amp;lt;CubeResetSignal&amp;gt;(ResetCubePosition);
    }

    // Update Logic
    public void Tick()
    {
        var horizontal = Input.GetAxisRaw(&quot;Horizontal&quot;);
        var vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
        var cubePosition = _cubeModel.position.Value;
        
        if (horizontal != 0)
            cubePosition.x += horizontal * _speed * Time.deltaTime;

        if (vertical != 0)
            cubePosition.z += vertical * _speed * Time.deltaTime;

        _cubeModel.position.Value = cubePosition;
    }

    public void ResetCubePosition()
    {
        _cubeModel.position.Value = Vector3.zero;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;-------&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;View 부분에선 Controller에서 넘어온 데이터를 받아 처리한다.&lt;/p&gt;
&lt;pre id=&quot;code_1618838165371&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using UnityEngine;
using Zenject;

public class CubeView : MonoBehaviour
{
    [Inject] private SignalBus _signalBus;
    
    public void UpdateMove(Vector3 position)
    {
        transform.position = position;
    }

    // View단에서 넘어가는 Event의 예시를 들기위해 Reset기능을 만들어보았다.
    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space))
            _signalBus.Fire(new CubeResetSignal());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;------&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;View에서 Controller로 넘어가는 Event의 데이터를 담는 Signal이다.&lt;/p&gt;
&lt;pre id=&quot;code_1618838720177&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CubeResetSignal
{
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;------&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로, 이 모든 클래스의 진입점인 Installer의 코드를 작성한다.&lt;br /&gt;( cubeView는 Scene에서 큐브를 만들고 연결해줘야 한다. )&lt;/p&gt;
&lt;pre id=&quot;code_1618838791341&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using UnityEngine;
using Zenject;

public class GameInstaller : MonoInstaller
{
    [SerializeField] private CubeView cubeView;
    
    public override void InstallBindings()
    {
        // Cube모델을 컨테이너에 Single(1개)로 담는다.
        // 기본적으로 다른곳에서 불릴때까지 생성되지 않는다. ( lazy )
        Container.Bind&amp;lt;CubeModel&amp;gt;().AsSingle();

        // CubeMoveController에 구현된 Interface들을 CubeMoveController에 담는다.
        // ---
        // Container.Bind(typeof(IInitializable), typeof(ITickable)).To&amp;lt;CubeMoveController&amp;gt;().AsSingle();
        // 위의 문구를 줄인것이다.
        Container.BindInterfacesAndSelfTo&amp;lt;CubeMoveController&amp;gt;().AsSingle();

        // View
        Container.Bind&amp;lt;CubeView&amp;gt;().FromInstance(cubeView);
        
        // Signals
        Container.DeclareSignal&amp;lt;CubeResetSignal&amp;gt;();
        
        SignalBusInstaller.Install(Container);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 모든 작업이 끝나면 큐브를 자유롭게 이동할 수 있게 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 패턴의 장점은 &lt;span style=&quot;color: #006dd7;&quot;&gt;데이터와 로직, 그리고 뷰를 나눠서 개발&lt;/span&gt;할 수 있다는 장점이 있다.&lt;br /&gt;그러나 단점으로는 패턴에 대한 숙지가 먼저 되어있어야 하고, 고작 큐브 움직이는 코드를 만드는데도 꽤 많은 스크립트 파일이 만들어진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러나 단점은 유지보수 성적인 측면으로 보았을 때 충분이 보완이 가능하다고 생각한다. 기존 개발 방식에 문제점을 느끼고, 새로운 방식의 개발 방법을 찾는다면 한번 시도해봐도 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;---&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;중간중간 Zenject의 사용방법이나 UniRx의 사용방법은 적지 않았는데, 이 글의 주제와 맞지않고, 너무 길어져서 적지 않았다.&lt;/p&gt;</description>
      <category>프로그래밍/Unity</category>
      <category>Architecture</category>
      <category>C#</category>
      <category>designpattern</category>
      <category>MVC</category>
      <category>MVC Pattern</category>
      <category>MVC패턴</category>
      <category>unirx</category>
      <category>Unity</category>
      <category>Zenject</category>
      <category>패턴</category>
      <author>LongMan</author>
      <guid isPermaLink="true">https://youngchangoon.tistory.com/70</guid>
      <comments>https://youngchangoon.tistory.com/70#entry70comment</comments>
      <pubDate>Mon, 19 Apr 2021 22:38:24 +0900</pubDate>
    </item>
  </channel>
</rss>