<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>z.log</title>
        <link>https://velog.io/</link>
        <description>trying to make the world a better place with a cool head and warm heart</description>
        <lastBuildDate>Thu, 07 Mar 2024 17:47:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>z.log</title>
            <url>https://velog.velcdn.com/images/a_zz/profile/8ec949e8-4d86-4b1e-8801-e7364318c979/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. z.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/a_zz" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[TIL_240307]]></title>
            <link>https://velog.io/@a_zz/TIL240307</link>
            <guid>https://velog.io/@a_zz/TIL240307</guid>
            <pubDate>Thu, 07 Mar 2024 17:47:00 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>최종발표 ppt 마무리</li>
</ul>
<hr>
<p><a href="https://www.canva.com/design/DAF-iAK6gdk/i_OWDE2e-DacNMrnwSHjNw/view?utm_content=DAF-iAK6gdk&amp;utm_campaign=designshare&amp;utm_medium=link&amp;utm_source=editor">최종발표 ppt</a> 마무리 작업에 집중한 날 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240306]]></title>
            <link>https://velog.io/@a_zz/TIL240306</link>
            <guid>https://velog.io/@a_zz/TIL240306</guid>
            <pubDate>Wed, 06 Mar 2024 11:48:14 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 관련 UI 효율적으로 관리하기</li>
</ul>
<hr>
<p><span style="color:#6C6C6C">(정리 후 작성 예정)</span></p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/52808ae0-5084-4616-b846-99079c764218/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240305]]></title>
            <link>https://velog.io/@a_zz/TIL240305</link>
            <guid>https://velog.io/@a_zz/TIL240305</guid>
            <pubDate>Tue, 05 Mar 2024 14:47:53 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>브로셔 작업 마무리</li>
</ul>
<hr>
<p><span style="color:#6C6C6C">(정리 후 작성 예정)</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240304]]></title>
            <link>https://velog.io/@a_zz/TIL240304</link>
            <guid>https://velog.io/@a_zz/TIL240304</guid>
            <pubDate>Mon, 04 Mar 2024 19:46:55 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>브로셔 및 최종발표 ppt 제작</li>
</ul>
<hr>
<p>브로셔와 최종발표 ppt 제작에 집중한 날 !
<span style="color:#6C6C6C">(완성되는대로 링크 공유하자 !)
+ Raycast Target 에 대해서도 적어둘 것 !</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240229]]></title>
            <link>https://velog.io/@a_zz/TIL240229</link>
            <guid>https://velog.io/@a_zz/TIL240229</guid>
            <pubDate>Thu, 29 Feb 2024 02:55:03 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 코드 체계적으로 관리</li>
</ul>
<hr>
<h3 id="span-stylecoloryellowgreen🛠-튜토리얼-내용-csv-데이터로-불러오기span"><span style="color:yellowgreen">🛠 튜토리얼 내용 csv 데이터로 불러오기</span></h3>
<p>기존에는 아래처럼 하드코딩으로
코드 안에 다이렉트로 string 값을 입력해서
튜토리얼 내용을 띄워주고 있었는데,</p>
<pre><code class="language-cs">// 기존 방식
TutorialMsg_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;TutorialMsg_PopupUI&gt;();
ui.curTutorialText =
    &quot;&lt;b&gt;[튜토리얼]&lt;/b&gt;\n\n적의 침입으로부터 메인 거점인 Home 을 지켜내야 해요!\n지키기 위해서는 침입을 막아줄 Unit 과 Room 이 필요해요.\n\n그럼, &lt;color=#E9D038&gt;&lt;b&gt;상점&lt;/b&gt;&lt;/color&gt;에서 제공해드린 재화로\nUnit 과 Room 을 구매해봅시다!&quot;;</code></pre>
<br>

<p>csv 파일로 TutorialData 를 만들고 Dictionary 를 활용해
상황에 맞는 데이터(string) 를 불러 오는 방식으로 진행하기로 했다.</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/534967b3-9068-4736-88dc-62ce022ae51a/image.png" alt=""></p>
<p>⚠
<em>csv 파일 작업할 때 쉼표 없는지 체크 잘 해야하고
개행은 \n 대신 &lt;br&gt; 로 작성해야 한다 !</em>
⚠</p>
<pre><code class="language-cs">// 수정 후
TutorialMsg_PopupUI ui = _ui.OpenPopup&lt;TutorialMsg_PopupUI&gt;();
ui.curTutorialText = Main.Get&lt;DataManager&gt;().Tutorial[&quot;T0&quot;].Description;</code></pre>
<br>

<p>기존 방식으로 진행하다보니
문구를 하나 찾아서 수정하는 데 걸리는 시간이 너무 오래걸리기도 하고
csv 로 관리하면 한 눈에 데이터를 볼 수 있어서 시간도 세이브하고 수정 자체도 편하고 용이할 것이라고 예상 !</p>
<hr>
<h3 id="span-stylecoloryellowgreen🛠-tutorialmanager-생성span"><span style="color:yellowgreen">🛠 TutorialManager 생성</span></h3>
<p>튜토리얼매니저 클래스를 만들어서
지금은 스크립트에 조잡하고 반복적으로 코드들이 들어가있다면
매니저에서 해당 내용을 함수로 만들어
그 함수를 불러 사용하는 느낌으로 진행하기로 결정 !</p>
<br>

<p>TutorialManager.cs</p>
<pre><code class="language-cs">// 튜토리얼 팝업 만드는 함수 + 튜토리얼 내용 연결
public void CreateTutorialPopup(string tutorialTextKey, bool isCloseBtnActive = false, bool isBackgroundActive = false) 
{
    TutorialMsg_PopupUI ui = _uiManager.OpenPopup&lt;TutorialMsg_PopupUI&gt;();
    ui.curTutorialText = _dataManager.Tutorial[tutorialTextKey].Description;
    ui.isCloseBtnActive = isCloseBtnActive;
    ui.isBackgroundActive = isBackgroundActive;
}

// 화살표 이미지 SetActive 해주는 함수
public void SetArrowActive(Image image, bool activeState) 
{
    image.gameObject.SetActive(activeState);
}

// arrow.achoredPosition 값 받아서 화살표 위치 설정해주는 함수
public void SetArrowPosition(RectTransform arrowTransform, float x, float y)
{
    arrowTransform.anchoredPosition = new Vector3(x, y, 0f);
}

// DOTween x 값 받아서 화살표 움직임 설정해주는 함수
public Tweener SetDOTweenX(RectTransform arrowTransform, float x)
{
    return arrowTransform.DOAnchorPosY(x, animationDuration).SetLoops(-1, LoopType.Yoyo);
}

// DOTween y 값 받아서 화살표 움직임 설정해주는 함수
public Tweener SetDOTweenY(RectTransform arrowTransform, float y) 
{
    return arrowTransform.DOAnchorPosY(y, animationDuration).SetLoops(-1, LoopType.Yoyo);
}    

// DOTween Kill 해주는 함수
public void KillDOTween(Tweener tweener) 
{
    if (tweener.IsActive())
    {
        tweener.Kill();
    }
}</code></pre>
<br>

<p>코드 수정
before</p>
<pre><code class="language-cs">if (gameManager.isTutorial) // 튜토리얼 중이라면
{

        tweener.Kill();
        _dayArrowImg.gameObject.SetActive(false);

        TutorialMsg_PopupUI tutorialUI = _ui.OpenPopup&lt;TutorialMsg_PopupUI&gt;();
        tutorialUI.curTutorialText = Main.Get&lt;DataManager&gt;().Tutorial[&quot;T1&quot;].Description;
        tutorialUI.isCloseBtnActive = true;
        tutorialUI.isBackgroundActive = true;

        shopButton.gameObject.SetActive(false);
        _inventoryButton.gameObject.SetActive(true);

        _dayArrowImg.gameObject.SetActive(true);
        dayArrowTransform.anchoredPosition = new Vector3(-241f, -276f, 0f);
        tweener = dayArrowTransform.DOAnchorPosY(-306f, animationDuration).SetLoops(-1, LoopType.Yoyo);
}</code></pre>
<br>

<p>after</p>
<pre><code class="language-cs">if (gameManager.isTutorial) // 튜토리얼 중이라면
{
    _tutorialManager.KillDOTween(tweener);
    _tutorialManager.SetArrowActive(_dayArrowImg, false);

    _tutorialManager.CreateTutorialPopup(&quot;T1&quot;, true, true);

    shopButton.gameObject.SetActive(false);
    _inventoryButton.gameObject.SetActive(true);

    _tutorialManager.SetArrowActive(_dayArrowImg, true);
    _tutorialManager.SetArrowPosition(dayArrowTransform, -241f, -276f);
    tweener = _tutorialManager.SetDOTweenY(dayArrowTransform, -306f);
}</code></pre>
<br>

<p>확실히 깔끔해졌다 ~ :)</p>
<hr>
<p>🤔<em>추가 고민 중 :
지금은 튜토리얼에서 특정 버튼을 강조하는 화살표를 
필요한 PopupUI 들마다 만들어 준 상태인데
다 지우고 TutorialPopupUI 에서 화살표 만들어 이걸로 사용할까 고민중 !</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240228]]></title>
            <link>https://velog.io/@a_zz/TIL240228</link>
            <guid>https://velog.io/@a_zz/TIL240228</guid>
            <pubDate>Wed, 28 Feb 2024 15:46:09 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>✅ 상점에 판매물건 정보 볼 수 있는 버튼 및 UI 추가</li>
<li>✅ 배치모드 Pocket 사이즈 조절</li>
</ul>
<hr>
<h3 id="상점에-판매물건-정보-볼-수-있는-버튼-추가">상점에 판매물건 정보 볼 수 있는 버튼 추가</h3>
<p>상점에서 판매하는
유닛, 룸, 그라운드, 아이템 항목들 설명 이미지를 제작해
info 팝업에서 버튼을 누르면 해당 이미지가 SetActive(true) 되도록 구현 !</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/60c6e5ad-efcb-48aa-a58f-e2e4a7eb3cb5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/583fd94d-13bf-45f0-97ab-b6a8f4b43d92/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/087ae79d-6db3-4d8b-8664-f011e1e701c3/image.png" alt=""></p>
<hr>
<h3 id="배치모드-pocket-사이즈-조절">배치모드 Pocket 사이즈 조절</h3>
<p>피드백 중에
기존 Pocket 사이즈가 너무 작아서 보유한 룸이나 유닛이 많다면 그 목록을 보기 힘들다는 의견이 있어서 사이즈 수정 진행 !</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/20320240-572f-4d6f-919f-feaac18cbf81/image.png" alt=""></p>
<p><span style="color:#6C6C6C">나중에 UI 최종 수정 완료되는대로 튜토리얼 화살표도 수정해야지...^.^..껄껄...</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240227]]></title>
            <link>https://velog.io/@a_zz/TIL240227</link>
            <guid>https://velog.io/@a_zz/TIL240227</guid>
            <pubDate>Tue, 27 Feb 2024 13:47:43 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 수정<ul>
<li>아이템 장착 관련 설명 추가</li>
</ul>
</li>
</ul>
<hr>
<p>피드백 중에 아이템을 어떻게 사용(장착)해야하는지 몰라 헤맨 분들이 계셔서
튜토리얼에 아이템 장착 설명 파트도 추가했다.</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/875f028d-6e75-48ca-b7cc-555207d6aec9/image.png" alt=""></p>
<p>튜토리얼에서 
특정 버튼만 작동하게끔 하고,
그 외에 다른 버튼들은 작동하지 않도록 처리를 하고,
상황에 맞게 가이드 역할을 해주는 화살표 위치를 수정해가면서
DOTween 으로 강조 포인트 해주는 부분이
참.. 매번 작업할 때마다 두통유발 포인트이지만
어찌저찌 해냈다....!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240226]]></title>
            <link>https://velog.io/@a_zz/TIL240226</link>
            <guid>https://velog.io/@a_zz/TIL240226</guid>
            <pubDate>Mon, 26 Feb 2024 12:57:44 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>UT 피드백 정리</li>
</ul>
<hr>
<p>오늘까지 들어왔던 피드백 정리 후
이번 주 작업 내용 세팅.</p>
<p>나는 일단 튜토리얼에서 아이템 장착 관련 설명 추가하는 걸 진행하기로 했다 !</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/5bdce6d7-d00b-49e8-a010-8caa294852b3/image.png" alt=""></p>
<br>

<p><span style="color:#6C6C6C"><em>(240223 결석 이슈.)</em></span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240222]]></title>
            <link>https://velog.io/@a_zz/TIL240222</link>
            <guid>https://velog.io/@a_zz/TIL240222</guid>
            <pubDate>Thu, 22 Feb 2024 17:40:39 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>UT 준비 ing</li>
</ul>
<p>내일 오후 1시 UT 시작 예정 !
🔥</p>
<hr>
<p>에러 발견과 에러 해결의 시간....</p>
<p>해결해야 할 에러들이 자꾸 생기는 이슈와
밸런스 작업이 시간이 꽤 걸려
원래 오늘 저녁에 UT 를 진행하려 했지만 내일로 딜레이 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_230221]]></title>
            <link>https://velog.io/@a_zz/TIL230221</link>
            <guid>https://velog.io/@a_zz/TIL230221</guid>
            <pubDate>Thu, 22 Feb 2024 00:51:20 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 작업 DONE.<ul>
<li>✅배치모드, ✅배틀</li>
</ul>
</li>
</ul>
<p>드디어 튜토리얼 작업 끝이 났다...!!</p>
<p>튜토리얼도 정말 손이 많이 가고
신경도 많이 써야하는 작업이라는 걸 아주 제대로 깨달았다..
<span style="color:#6C6C6C">(유저의 입장에서 생각하기.. 유저의 안정적인 온보딩을 위해..
  이탈을 최대한 막기 위해..)</span></p>
<p>특히 배치모드 쪽 튜토리얼을 작업하면서
다른 분들이 작업하셨던 코드를 읽고 이해하는
공부의 시간도 가질 수 있어서
겸사겸사 오히려 좋았다 ~
그리고 DOTween 도 사용해보면서
개인적으로 상당히 의미있는, 도전의 시간이었다.</p>
<p>확실히 와이어프레임을 만들어서 미리 설계를 하고 코드 작성을 진행하니
당연히 코드 작성 부분에서는 어려움을 느끼긴 했지만
방향성을 미리 세팅하고 작업에 들어갔기에 작업의 흐름과 관련해서는 물흐르듯이 순탄하게 잘 흘러갔다고 생각한다.
무사히 작업 완료를 외칠 수 있어 너무나도 기쁘고 감사하다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/a_zz/post/24002184-744f-4564-a778-b44b17664896/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/05063769-5b44-4e90-bb07-bbfd8b54dfd3/image.png" alt=""></p>
<p>배치모드</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/e2a462ee-2c15-4ece-88b6-c36f53128aad/image.png" alt=""></p>
<p>배틀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_230220]]></title>
            <link>https://velog.io/@a_zz/TIL230220</link>
            <guid>https://velog.io/@a_zz/TIL230220</guid>
            <pubDate>Tue, 20 Feb 2024 22:40:35 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 작업 ing<ul>
<li>🛠배치모드, 🛠배틀</li>
</ul>
</li>
</ul>
<p>하루종일 튜토리얼 작업하다가 해가 떴다...하하하</p>
<hr>
<p>튜토리얼 피드백 : </p>
<ul>
<li>말투에 컨셉이 있으면 좋겠다.</li>
<li>하나의 step 이 여러 step 으로 합쳐져 있는 것들을 최대한 분리하자.</li>
<li>캐릭터가 말하는 방식으로<ul>
<li>지금은 너무 띡 네모네모한 느낌.</li>
</ul>
</li>
</ul>
<hr>
<p>ing..</p>
<p>배치모드 해내고 만다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240219]]></title>
            <link>https://velog.io/@a_zz/TIL240219</link>
            <guid>https://velog.io/@a_zz/TIL240219</guid>
            <pubDate>Mon, 19 Feb 2024 10:22:06 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 작업 ing<ul>
<li>✅<del>상점</del>, ✅<del>인벤토리</del>, 🛠배치모드, 🛠배틀</li>
</ul>
</li>
</ul>
<p>주말과 함께
상점, 인벤토리 튜토리얼은 일단 완료 !
(but 언제 어디서 에러가 와랄ㄹ라라랄 나올지는 모르겠음..껄껄)
<br>
튜토리얼과 관련해서
코드를 체계적으로 작성하고 싶은 마음은 정말 굴뚝같지만
어떻게 해야할지 감이 전혀 오지 않아서
일단은 GameManager 에서 bool 변수 isTutorial 을 추가한 다음,
버튼 클릭이나 팝업 동작 시에 &quot;튜토리얼 중이라면(isTutorial == true)&quot; 조건을 만들어 튜토리얼이 진행되게끔 작업하고 있다.</p>
<br>
배치모드, 배틀 파이팅 !

<hr>
<p><img src="https://velog.velcdn.com/images/a_zz/post/0ed9b29d-f546-4114-9785-2d9bc225faf1/image.png" alt=""></p>
<p>상점</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/34fe363a-de8e-463f-8494-0da7e26dedeb/image.png" alt=""></p>
<p>인벤토리</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240216]]></title>
            <link>https://velog.io/@a_zz/TIL240216</link>
            <guid>https://velog.io/@a_zz/TIL240216</guid>
            <pubDate>Fri, 16 Feb 2024 10:47:53 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>튜토리얼 작업 start !</li>
</ul>
<p>유저테스트 날짜가 다가오고 있다. (계획 : 2/21)
그래서 급한 우선순위에 포함되어 있는 튜토리얼 작업을 시작해보려 한다 !
튜터님의 조언과 함께 이것저것 레퍼런스를 참고해가지고 설계부터 하나씩 작업해보자 !</p>
<hr>
<p>참고 레퍼런스s :</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/f43ea35f-8bda-4ee9-b1f9-51326650d245/image.png" alt=""></p>
<hr>
<h3 id="튜토리얼-와이어프레임">튜토리얼 와이어프레임</h3>
<p><img src="https://velog.velcdn.com/images/a_zz/post/18991140-46db-4da3-9e4c-8e4cf752a1fb/image.png" alt=""></p>
<p><span style="color:#6C6C6C">와이어프레임뚝딱뚝딱.jpg</span></p>
<br>



]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240215]]></title>
            <link>https://velog.io/@a_zz/TIL240215</link>
            <guid>https://velog.io/@a_zz/TIL240215</guid>
            <pubDate>Thu, 15 Feb 2024 17:17:01 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>유닛, 룸, 아이템 업그레이드 UI 및 시스템 추가 ing<ul>
<li>유닛은 어느정도 마무리 단계. 룸 업그레이드 작업 gogo !</li>
</ul>
</li>
</ul>
<hr>
<h3 id="룸-업그레이드-구현">룸 업그레이드 구현</h3>
<p><strong>GameManager.cs</strong></p>
<p>원래는 Upgrade 버튼 누를 때나 인벤토리에서 삭제버튼 누를 때 GameManager 에 있는 PlayerRooms 을 직접적으로 불러서 수정을 해왔는데,
이제는 GameManager 에 RemoveRoom() 메서드를 만들어서 </p>
<p>RemoveRoom() 하게 되면
(룸이 배치되어 있다면)배치되어 있는 룸 해제, - unit 도 자연스럽게 빠짐. (BatRoom의 DeleteAllUnit()이 OnDestroy() 에서 발동된다.)
인벤토리에서도 삭제가 진행된다.</p>
<pre><code class="language-cs">private TileManager _tile;

public void RemoveRoom(Room room) // room
{
    if (room.IsEquiped) // 배치되어있다면 room 해제
    {
        room.IsEquiped = false;
        _tile.DeleteRoom(room);
    }
    PlayerRooms.Remove(room); // 인벤토리에서 지우고
}</code></pre>
<p><strong>TileManager.cs</strong></p>
<pre><code class="language-cs">public void DeleteRoom(Room room)
{
    RoomBehavior newRoom = CreateDefaultRoom(room.IndexX, room.IndexY, _roomObjList[room.IndexX][room.IndexY].transform.position);
    resource.Destroy(_roomObjList[room.IndexX][room.IndexY].gameObject);
    _roomObjList[room.IndexX][room.IndexY] = newRoom;
}</code></pre>
<br>

<p><strong>InventUpgrade_PopupUI.cs</strong></p>
<p>Unit 과 동일하게 먼저, UpgradeRoomSlots 배열로 slot 을 관리한다.</p>
<pre><code class="language-cs">private Room[] UpgradeRoomSlots = new Room[3];</code></pre>
<br>

<p>ClickUpgradeBtn()에서
Unit slot 에 데이터 들어왔을 때와 Room slot 에 데이터가 들어왔을 때의 구분을 위해 다음의 조건을 추가해주었다.</p>
<p><code>if (UpgradeUnitSlots[0] != null &amp;&amp; UpgradeUnitSlots[1] != null &amp;&amp; UpgradeUnitSlots[2] != null)</code> // Unit slot 구분
<code>if (UpgradeRoomSlots[0] != null &amp;&amp; UpgradeRoomSlots[1] != null &amp;&amp; UpgradeRoomSlots[2] != null)</code> // Room slot 구분</p>
<p><span style="color:#6C6C6C">작동은 잘 되는데, 과연 올바르게 조건을 걸어준건지는 확실하진 않다 하핫.</span></p>
<pre><code class="language-cs">private void ClickUpgradeBtn(PointerEventData data)
{
    // slot 이 null 인 경우 예외처리할 것
    if (_upgradeSlotsImgs[0].sprite == null || _upgradeSlotsImgs[1].sprite == null || _upgradeSlotsImgs[2].sprite == null)
    {
        Error_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
        ui.curErrorText = &quot;슬롯이 비어있습니다!&quot;;
        Debug.Log(&quot;슬롯이 비어있습니다!&quot;);
        return;
    }

    if (UpgradeUnitSlots[0] != null &amp;&amp; UpgradeUnitSlots[1] != null &amp;&amp; UpgradeUnitSlots[2] != null) // Unit slot 구분
    {
        // slot 3개에 모두 동일한 데이터가 들어왔다면.
        if (UpgradeUnitSlots[0].Data.Key == UpgradeUnitSlots[1].Data.Key &amp;&amp; UpgradeUnitSlots[1].Data.Key == UpgradeUnitSlots[2].Data.Key)
        {
            for (int i = 0; i &lt; UpgradeUnitSlots.Length; i++)
            {
                _upgradeSlotsImgs[i].sprite = null; // slot image 빼기.
                _upgradeSlotsImgs[i].enabled = false; // image 컴포넌트 체크 해제.

                Main.Get&lt;GameManager&gt;().RemoveUnit(UpgradeUnitSlots[i]);
                Owner.SetUnitInventory();
            }

            // 합성 후 새롭게 능력 부여된 아이템 제공 - NextKey 통해.
            Main.Get&lt;GameManager&gt;().playerUnits.Add(new Character(Main.Get&lt;DataManager&gt;().Character[UpgradeUnitSlots[0].Data.NextKey]));
            Owner.SetUnitInventory();

            Array.Clear(UpgradeUnitSlots, 0, UpgradeUnitSlots.Length);
            Count = 0;
        }
        else
        {
            Error_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
            ui.curErrorText = &quot;동일한 종류,\n레벨의 유닛을 넣어주세요!&quot;;
            Debug.Log(&quot;동일한 유닛을 넣어주세요!&quot;);
        }
    }

    if (UpgradeRoomSlots[0] != null &amp;&amp; UpgradeRoomSlots[1] != null &amp;&amp; UpgradeRoomSlots[2] != null) // Room slot 구분
    {
        // slot 3개에 모두 동일한 데이터가 들어왔다면.
        if (UpgradeRoomSlots[0].Data.Key == UpgradeRoomSlots[1].Data.Key &amp;&amp; UpgradeRoomSlots[1].Data.Key == UpgradeRoomSlots[2].Data.Key)
        {
            for (int i = 0; i &lt; UpgradeRoomSlots.Length; i++)
            {
                _upgradeSlotsImgs[i].sprite = null; // slot image 빼기.
                _upgradeSlotsImgs[i].enabled = false; // image 컴포넌트 체크 해제.

                Main.Get&lt;GameManager&gt;().RemoveRoom(UpgradeRoomSlots[i]);
                Owner.SetRoomInventory();
            }

            // 합성 후 새롭게 능력 부여된 아이템 제공 - NextKey 통해.
            Main.Get&lt;GameManager&gt;().PlayerRooms.Add(new Room(Main.Get&lt;DataManager&gt;().Room[UpgradeRoomSlots[0].Data.NextKey]));
            Owner.SetRoomInventory();

            Array.Clear(UpgradeRoomSlots, 0, UpgradeRoomSlots.Length);
            Count = 0;
        }
        else
        {
            Error_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
            ui.curErrorText = &quot;동일한 종류,\n레벨의 룸을 넣어주세요!&quot;;
            Debug.Log(&quot;동일한 룸을 넣어주세요!&quot;);
        }
    }
}</code></pre>
<br>

<p>ClickSlot() 에서도
Unit slot 과 Room slot 을 구분지어줘야하기 때문에
조건을</p>
<pre><code class="language-cs">if (UpgradeUnitSlots[i] != null)
{
    UpgradeUnitSlots[i] = null;
}
else if (UpgradeRoomSlots[i] != null)
{
    UpgradeRoomSlots[i] = null;
}</code></pre>
<p>이런식으로 추가해주었다.</p>
<pre><code class="language-cs">private void ClickSlot(int i)
{
    if (UpgradeUnitSlots == null || UpgradeRoomSlots == null) return;

    Count--;

    if (UpgradeUnitSlots[i] != null)
    {
        UpgradeUnitSlots[i] = null;
    }
    else if (UpgradeRoomSlots[i] != null)
    {
        UpgradeRoomSlots[i] = null;
    }

    _upgradeSlotsImgs[i].sprite = null; // slot image 빼기
    _upgradeSlotsImgs[i].enabled = false; // image 컴포넌트 체크 해제.
}</code></pre>
<br>

<p>AddUpgradeRoomSlot() 메서드
(유닛의 AddUpgradeUnitSlot 과 동일한 구조)</p>
<p>index 는 비어있는 배열 요소의 index 찾았는지 아닌지 판별을 위한 친구. (못찾았다면 -1 유지하겠죠.)</p>
<p>fore 문에서
배열 요소에 아무것도 없으면서 -1 이면 index 를 i 로 변경.
배열 요소에 똑같은 unit 이 들어있다면 return</p>
<p>index 가 -1 이라면, 배열이 꽉 찼다는 의미이기에 return;</p>
<p>for 문에서 두번째 if 문에 안 걸리고 첫번째 if 문만 거쳤다면
index 가 i 가 되어있으니까
UpgradeRoomSlot[index] = unit;
SetRoomInfo(index);
Count++; (슬롯에 더해지는 상황이니까 !)
진행.</p>
<pre><code class="language-cs">public void AddUpgradeRoomSlot(Room room)
{
    int index = -1;

    for (int i = 0; i &lt; UpgradeRoomSlots.Length; i++)
    {
        if (UpgradeRoomSlots[i] == null &amp;&amp; index == -1)
        {
            index = i;
        }
        if (UpgradeRoomSlots[i] == room)
        {
            return;
        }
    }

    if (index == -1)
    {
        return;
    }
    UpgradeRoomSlots[index] = room;
    SetRoomInfo(index);
    Count++;
}</code></pre>
<br>

<p><em>이 외에
InventRoom_ContentsBtnUI.cs 에서는 UI 관련 처리 진행. 
(e.g. 언제 Upgrade 창이 꺼지고, 켜지고 하는지, Upgrade 창이 켜져있으면 인벤토리 아이템 눌렀을 때 Upgrade slot 에 추가되도록, etc.)</em></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240214]]></title>
            <link>https://velog.io/@a_zz/TIL240214</link>
            <guid>https://velog.io/@a_zz/TIL240214</guid>
            <pubDate>Wed, 14 Feb 2024 11:49:49 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>유닛, 룸, 아이템 업그레이드 UI 및 시스템 추가 ing<ul>
<li>still 유닛 작업 중..</li>
</ul>
</li>
</ul>
<hr>
<h3 id="유닛-업그레이드-구현">유닛 업그레이드 구현</h3>
<p><strong>GameManager.cs</strong></p>
<p>원래는 Upgrade 버튼 누를 때나 인벤토리에서 삭제버튼 누를 때 GameManager 에 있는 playerUnits 을 직접적으로 불러서 수정을 해왔는데,
이제는 GameManager 에 RemoveUnit() 메서드를 만들어서 </p>
<p>RemoveUnit() 하게 되면
(유닛이 배치되어 있다면)배치되어 있는 유닛 해제, 
인벤토리에서도 삭제, 
그리고 유닛에 아이템 장착되어있다면 아이템 장착해제 진행한다.</p>
<pre><code class="language-cs">public void RemoveUnit(Character unit) // unit
{
    if (unit.CurRoom != null) // 유닛이 배치되어있는 경우에
    {
        ((BatRoom)unit.CurRoom).DeleteUnit(unit); // 배치되어있는 유닛 빼면서
    }
    playerUnits.Remove(unit); // 인벤토리에서도 지우고 
    Item[] items = unit.Item; // 아이템 장착되어있는 것도 빼주고
    for (int i = 0; i &lt; items.Length; i++)
    {
        if (items[i] != null)
        {
            items[i].IsEquiped = false;
            items[i].Owner = null;
        }
    }
}</code></pre>
<br>

<p><strong>InventUpgrade_PopupUI.cs</strong></p>
<p>먼저, UpgradeUnitSlots 배열로 slot 을 관리한다.
slot 이 얼마나 찼는지 체크해주는 역할의 Count 는 Init() 에서 0 으로 초기화 진행.</p>
<pre><code class="language-cs">private Character[] UpgradeUnitSlots = new Character[3];
public int Count { get; private set; } // slot 얼마나 찼는지 체크해주는 역할.</code></pre>
<br>

<p>ClickUpgradeBtn() 메서드에서는
업그레이드 버튼을 눌렀을 때
slot 이 null 인 경우 예외처리 진행하고,
slot 3칸에 모두 동일한 데이터가 들어왔다면 업그레이드 진행.
-&gt; 이 때 업그레이드 후 새롭게 능력 부여된 유닛 제공을 위해 Data 의 NextKey 활용. (e.g. 1레벨의 Gun 이 NextKey 로 다음 레벨 Gun 인 Guner 를 string 으로 들고 있게 한다 !)</p>
<p><img src="https://velog.velcdn.com/images/a_zz/post/22b0d130-52f2-4488-826a-f255baf1974a/image.png" alt=""></p>
<pre><code class="language-cs">private void ClickUpgradeBtn(PointerEventData data)
{
    // slot 이 null 인 경우 예외처리할 것
    if (_upgradeSlotsImgs[0].sprite == null || _upgradeSlotsImgs[1].sprite == null || _upgradeSlotsImgs[2].sprite == null)
    {
        Debug.Log(&quot;슬롯이 비어있습니다!&quot;);
        return;
    }

    // slot 3개에 모두 동일한 데이터가 들어왔다면.
    if (UpgradeUnitSlots[0].Data.Key == UpgradeUnitSlots[1].Data.Key &amp;&amp; UpgradeUnitSlots[1].Data.Key == UpgradeUnitSlots[2].Data.Key)
    {
        for (int i = 0; i &lt; UpgradeUnitSlots.Length; i++)
        {
            _upgradeSlotsImgs[i].sprite = null; // slot image 빼기.
            _upgradeSlotsImgs[i].enabled = false; // image 컴포넌트 체크 해제.

            Main.Get&lt;GameManager&gt;().RemoveUnit(UpgradeUnitSlots[i]);
            Owner.SetUnitInventory();
        }

        // 업그레이드 후 새롭게 능력 부여된 아이템 제공 - Nextkey 통해.
        Main.Get&lt;GameManager&gt;().playerUnits.Add(new Character(Main.Get&lt;DataManager&gt;().Character[UpgradeUnitSlots[0].Data.NextKey]));
        Owner.SetUnitInventory();

        Array.Clear(UpgradeUnitSlots, 0, UpgradeUnitSlots.Length);
        Count = 0;
    }
    else
    {
        Debug.Log(&quot;동일한 아이템을 넣어주세요!&quot;);
    }
}</code></pre>
<br>

<p>slot 클릭하면 작동하는 ClickSlot() 메서드.
슬롯 클릭하면 데이터가 빠지기 때문에, Count-- 도 진행.</p>
<pre><code class="language-cs">private void ClickSlot(int i)
{
    if (UpgradeUnitSlots == null) return;
    Count--;
    UpgradeUnitSlots[i] = null;

    _upgradeSlotsImgs[i].sprite = null; // slot image 빼기
    _upgradeSlotsImgs[i].enabled = false; // image 컴포넌트 체크 해제.
}</code></pre>
<br>

<p>AddUpgradeUnitSlot() 메서드.
index 는 비어있는 배열 요소의 index 찾았는지 아닌지 판별을 위한 친구. (못찾았다면 -1 유지하겠죠.)</p>
<p>fore 문에서
배열 요소에 아무것도 없으면서 -1 이면 index 를 i 로 변경.
배열 요소에 똑같은 unit 이 들어있다면 return;</p>
<p>index 가 -1 이라면, 배열이 꽉 찼다는 의미이기에 return;</p>
<p>for 문에서 두번째 if 문에 안 걸리고 첫번째 if 문만 거쳤다면
index 가 i 가 되어있으니까
UpgradeUnitSlot[index] = unit;
SetUnitInfo(index);
Count++; (슬롯에 더해지는 상황이니까 !)
진행.</p>
<pre><code class="language-cs">public void AddUpgradeUnitSlot(Character unit)
{
    int index = -1; // 비어있는 배열 요소의 index 찾았는지 아닌지 판별을 위한 친구. (못찾았다면 -1)

    for (int i = 0; i &lt; UpgradeUnitSlots.Length; i++)
    {
        if (UpgradeUnitSlots[i] == null &amp;&amp; index == -1)
        {
            index = i;

        }

        if (UpgradeUnitSlots[i] == unit) // 똑같은 친구가 있으면 return.
        {
            return;
        }
    }

    if (index == -1) // UpgradeUnitSlots 배열이 꽉 차있다면 return.
    {
        return;
    }

    UpgradeUnitSlots[index] = unit;
    SetUnitInfo(index);
    Count++;
}</code></pre>
<br>

<p><em>이 외에
Inventory_PopupUI.cs 나 InventUnit_ContentsBtnUI.cs 에서는 UI 관련 처리 진행. 
(e.g. 언제 Upgrade 창이 꺼지고, 켜지고 하는지, 특정 버튼을 누르는데 Upgrade 창이 켜져있다면 꺼지도록, Upgrade 창이 켜져있으면 인벤토리 아이템 눌렀을 때 Upgrade slot 에 추가되도록, etc.)</em></p>
<p>--
그리고
업그레이드 시 Key 값과 매칭되는 prefab 이 없어서 에러가 뜨는 이슈가 있었는데
csv 파일에 PrefabName 키값을 새로 추가해서 prefab 만들 때 더이상 Key 가 아닌 PrefabName 을 바라보게 설정했다.
(이렇게 하면 굳이 똑같이 생긴 prefab 을 각 레벨별로 만들어 줄 필요도 없고, csv 파일에서는 Key 값으로 데이터 구분도 할 수 있음 !)</p>
<p>before
<code>Units[index] = Main.Get&lt;SceneManager&gt;().Scene.CreateCharacter(data.Data.Key);</code>
after
<code>Units[index] = Main.Get&lt;SceneManager&gt;().Scene.CreateCharacter(data.Data.PrefabName);</code></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240213]]></title>
            <link>https://velog.io/@a_zz/TIL240213</link>
            <guid>https://velog.io/@a_zz/TIL240213</guid>
            <pubDate>Tue, 13 Feb 2024 11:28:59 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>유닛, 룸, 아이템 업그레이드 UI 및 시스템 추가</li>
</ul>
<p><span style="color:#6C6C6C">연휴의 후유증..
짜릿하다 !</span></p>
<hr>
<p><strong>업그레이드 UI</strong>
<img src="https://velog.velcdn.com/images/a_zz/post/6c61a78f-130b-4c38-8e3d-3dc0fbc009ff/image.png" alt=""></p>
<p>업그레이드 방식은
우선, unit, room, item 모두 같은 레벨이 3개 있으면, 다음 레벨로 업그레이드 가능하게끔 구현해보려고 한다.
그리고 drag 방식이 아닌 click 방식으로 업그레이드를 진행해볼 예정이다.</p>
<p>새로운 도전의 작업이 찾아왔는데
일단 츄라이🔥 실패해도 못해도 일단 츄라이🔥
파이탱 !</p>
<p>차근차근
unit 업그레이드부터 하나씩 시작해보자 !</p>
<p>InventUpgrade_PopupUI.cs (~ing)</p>
<pre><code class="language-cs">using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class InventUpgrade_PopupUI : BaseUI
{
    private Button _closeButton;
    private Button[] _upgradeSlots = new Button[3];
    private Button _upgradeButton;

    private Image _itemImg;
    private Image[] _upgradeSlotsImgs = new Image[3];
    private Image[] _upgradeCancelImgs = new Image[3];

    protected override void Init()
    {
        SetUI&lt;Button&gt;();
        SetUI&lt;Image&gt;();

        _closeButton = GetUI&lt;Button&gt;(&quot;InventUpgradeCloseBtn&quot;);

        for (int i = 0; i &lt; _upgradeSlots.Length; i++)
        {
            _upgradeSlots[i] = GetUI&lt;Button&gt;($&quot;UpgradeSlotBtn{i + 1}&quot;);
            _upgradeSlotsImgs[i] = GetUI&lt;Image&gt;($&quot;UpgradeSlotBtn{i + 1}&quot;);
            _upgradeCancelImgs[i] = GetUI&lt;Image&gt;($&quot;UpgradeCancelImg{i + 1}&quot;);
        }

        _upgradeButton = GetUI&lt;Button&gt;(&quot;UpgradeBtn&quot;);

        SetUICallback(_closeButton.gameObject, EUIEventState.Click, ClickCloseBtn);
        SetUICallback(_upgradeButton.gameObject, EUIEventState.Click, ClickUpgradeBtn);
        SetUICallback(_upgradeSlots[0].gameObject, EUIEventState.Click, ClickFirstSlot);
        SetUICallback(_upgradeSlots[1].gameObject, EUIEventState.Click, ClickSecondSlot);
        SetUICallback(_upgradeSlots[2].gameObject, EUIEventState.Click, ClickThirdSlot);
        SetUICallback(_upgradeSlots[0].gameObject, EUIEventState.Hovered, HoveredFirstSlot);
        SetUICallback(_upgradeSlots[0].gameObject, EUIEventState.Exit, ExitFirstSlot);
        SetUICallback(_upgradeSlots[1].gameObject, EUIEventState.Hovered, HoveredSecondSlot);
        SetUICallback(_upgradeSlots[1].gameObject, EUIEventState.Exit, ExitSecondSlot);
        SetUICallback(_upgradeSlots[2].gameObject, EUIEventState.Hovered, HoveredThirdSlot);
        SetUICallback(_upgradeSlots[2].gameObject, EUIEventState.Exit, ExitThirdSlot);
    }

    private void ClickCloseBtn(PointerEventData data)
    {
        Main.Get&lt;UIManager&gt;().ClosePopup();
    }

    private void ClickUpgradeBtn(PointerEventData data)
    {

    }

    private void ClickFirstSlot(PointerEventData data)
    {

    }

    private void ClickSecondSlot(PointerEventData data)
    {

    }

    private void ClickThirdSlot(PointerEventData data)
    {

    }

    private void HoveredFirstSlot(PointerEventData data)
    {
        _upgradeCancelImgs[0].gameObject.SetActive(true);
    }

    private void ExitFirstSlot(PointerEventData data)
    {
        _upgradeCancelImgs[0].gameObject.SetActive(false);
    }

    private void HoveredSecondSlot(PointerEventData data)
    {
        _upgradeCancelImgs[1].gameObject.SetActive(true);
    }

    private void ExitSecondSlot(PointerEventData data)
    {
        _upgradeCancelImgs[1].gameObject.SetActive(false);
    }

    private void HoveredThirdSlot(PointerEventData data)
    {
        _upgradeCancelImgs[2].gameObject.SetActive(true);
    }

    private void ExitThirdSlot(PointerEventData data)
    {
        _upgradeCancelImgs[2].gameObject.SetActive(false);
    }
}
</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240208]]></title>
            <link>https://velog.io/@a_zz/TIL240208</link>
            <guid>https://velog.io/@a_zz/TIL240208</guid>
            <pubDate>Thu, 08 Feb 2024 12:24:13 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>상점 구매 방식 리뉴얼<ul>
<li>Unit, Room, Item 랜덤 뽑기 시스템 도입</li>
<li>Ground 는 돈으로 구매 가능</li>
</ul>
</li>
</ul>
<hr>
<p>중복되는 코드 개선</p>
<p>e.g. 유닛 1회뽑기 &amp; 3회뽑기 진행할 때 코드적으로 중복되는 부분이 많아 매개변수를 활용해 다음과 같이 변경했다.
그래서 1회뽑기 버튼 눌렀을 땐 <code>ClickGachaUnit(1);</code> 
3회뽑기는 <code>ClickGachaUnit(3);</code> 해주면 된다.</p>
<p>Shop_PopupUI.cs</p>
<pre><code class="language-cs">private void ClickGachaUnit(int count)
{
    if (_myGachaUnits != null)
    {
        _myGachaUnits.Clear();
    }

    if (Main.Get&lt;GameManager&gt;()._playerMoney &gt;= count * 1000) // 금액 계산 로직
    {
        Main.Get&lt;GameManager&gt;().ChangeMoney(-count * 1000);
        Debug.Log(&quot;구매완료했습니다.&quot;);
        Debug.Log($&quot;잔액 : {Main.Get&lt;GameManager&gt;()._playerMoney}&quot;);

        for (int i = 0; i &lt; count; i++)
        {
            _myGachaUnits.Add(RandomPickUnit());
            Debug.Log($&quot;{_myGachaUnits[i].Key}&quot;);
        }

        GachaResult_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;GachaResult_PopupUI&gt;(&quot;GachaResult_PopupUI&quot;);
        ui.GachaUnitData = _myGachaUnits;
    }
    else // 보유 금액 부족 시
    {
        Error_PopupUI errorUI = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
        errorUI.curErrorText = &quot;돈이 부족해서 구매할 수 없습니다.&quot;;
    }
}</code></pre>
<br>

<p>작성하면서
ClickGachaUnit 과 ClickGachaRoom, ClickGachaItem
이 친구들끼리도 중복되는 내용이 꽤 많은데
얘네들은 어떻게 개선을 할 수 있을지 아직 고민중이다.</p>
<pre><code class="language-cs">private void ClickGachaRoom(int count)
{
    if (_myGachaRooms != null) 
    {
        _myGachaRooms.Clear();
    }

    if (Main.Get&lt;GameManager&gt;()._playerMoney &gt;= count * 1000)
    {
        Main.Get&lt;GameManager&gt;().ChangeMoney(-count * 1000);
        Debug.Log(&quot;구매완료했습니다.&quot;);
        Debug.Log($&quot;잔액 : {Main.Get&lt;GameManager&gt;()._playerMoney}&quot;);

        for (int i = 0; i &lt; count; i++)
        {
            _myGachaRooms.Add(RandomPickRoom());
            Debug.Log($&quot;{_myGachaRooms[i].Key}&quot;);
        }

        GachaResult_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;GachaResult_PopupUI&gt;(&quot;GachaResult_PopupUI&quot;);
        ui.GachaRoomData = _myGachaRooms;
    }
    else
    {
        Error_PopupUI errorUI = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
        errorUI.curErrorText = &quot;돈이 부족해서 구매할 수 없습니다.&quot;;
    }
}</code></pre>
<pre><code class="language-cs">private void ClickGachaItem(int count)
{
    if (_myGachaItems != null)
    {
        _myGachaItems.Clear();
    }

    if (Main.Get&lt;GameManager&gt;()._playerMoney &gt;= count * 1000)
    {
        Main.Get&lt;GameManager&gt;().ChangeMoney(-count * 1000);
        Debug.Log(&quot;구매완료했습니다.&quot;);
        Debug.Log($&quot;잔액 : {Main.Get&lt;GameManager&gt;()._playerMoney}&quot;);

        for (int i = 0; i &lt; count; i++)
        {
            _myGachaItems.Add(RandomPickItem());
            Debug.Log($&quot;{_myGachaItems[i].Key}&quot;);
        }

        GachaResult_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;GachaResult_PopupUI&gt;(&quot;GachaResult_PopupUI&quot;);
        ui.GachaItemData = _myGachaItems;
    }
    else
    {
        Error_PopupUI errorUI = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
        errorUI.curErrorText = &quot;돈이 부족해서 구매할 수 없습니다.&quot;;
    }
}</code></pre>
<br>

<p>또한 Unit, Room, Item 모두 랜덤으로 픽하는 로직도 비슷 !
(이 부분도 어떻게 개선을 할 수 있을지 고민중 !)</p>
<pre><code class="language-cs">private CharacterData RandomPickUnit()
{
    return GachaUnitItems[Random.Range(0, GachaUnitItems.Count)];
}

private RoomData RandomPickRoom()
{
    return GachaRoomItems[Random.Range(0, GachaRoomItems.Count)];
}

private ItemData RandomPickItem()
{
    return GachaItemItems[Random.Range(0, GachaItemItems.Count)];
}</code></pre>
<hr>
<p><img src="https://velog.velcdn.com/images/a_zz/post/8a31053e-1579-4e8e-81c0-c928a61e85be/image.png" alt=""></p>
<p><span style="color:#6C6C6C">북적북적그잡채.jpg</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240207]]></title>
            <link>https://velog.io/@a_zz/TIL240207</link>
            <guid>https://velog.io/@a_zz/TIL240207</guid>
            <pubDate>Wed, 07 Feb 2024 16:01:27 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>랜덤 뽑기 시스템 구현 ing</li>
</ul>
<p>오늘은 일단 기본 상점 prefab 을 변경해 EditingShop_PopupUI prefab 을 새로 만들어 Unit 랜덤뽑기(1회, 3회) 로직 작성을 시작해보았다.</p>
<p>EditingShop_PopupUI 에서 가챠 판매 아이템 GachaUnitItems 를 List.Add() 한 다음, RandomPickUnit() 을 통해 랜덤 가챠 진행 후 나온 결과를 주머니_myGachaUnit 에 넣어서 그 데이터를 GachaResult_PopupUI 로 넘겨준다.</p>
<p>GachaResult_PopupUI 에서는 SaveInInventory() 를 통해 받은 데이터(CharacterData)를 Character 로 새로 인스턴스화하여(얕은 복사 이슈) 인벤토리로 옮겨준다.</p>
<p>EditingShop_PopupUI.cs</p>
<pre><code class="language-cs">private void ClickUnit1Btn(PointerEventData eventData) //유닛 1회 뽑기
{
    if (_myGachaUnit != null) // 이거 안 해주면 버튼 누를때마다 리스트에 계속 쌓여서 1개가 2개가 되고 .. 계속 증가 이슈.
    {
        _myGachaUnit.Clear();
    }

    if (Main.Get&lt;GameManager&gt;()._playerMoney &gt;= 1000) // 금액 계산 로직
    {
        Main.Get&lt;GameManager&gt;().ChangeMoney(-1000);
        Debug.Log(&quot;구매완료했습니다.&quot;);
        Debug.Log($&quot;잔액 : {Main.Get&lt;GameManager&gt;()._playerMoney}&quot;);

        _myGachaUnit.Add(RandomPickUnit());
        Debug.Log($&quot;{_myGachaUnit[0].Key}&quot;);

        GachaResult_PopupUI ui = Main.Get&lt;UIManager&gt;().OpenPopup&lt;GachaResult_PopupUI&gt;(&quot;GachaResult_PopupUI&quot;);
        ui.GachaUnitData = _myGachaUnit;
    }
    else // 보유 금액 부족 시
    {
        Error_PopupUI errorUI = Main.Get&lt;UIManager&gt;().OpenPopup&lt;Error_PopupUI&gt;(&quot;Error_PopupUI&quot;);
        errorUI.curErrorText = &quot;돈이 부족해서 구매할 수 없습니다.&quot;;
    }
}

private CharacterData RandomPickUnit()
{
    return GachaUnitItems[Random.Range(0, GachaUnitItems.Count)];
}</code></pre>
<br>

<p>GachaResult_PopupUI.cs</p>
<pre><code class="language-cs">private void ClickCloseBtn(PointerEventData eventData)
{
    if (GachaUnitData != null) // 구분 - 인벤토리로 옮기려는 데이터가 유닛 일 때
    {
        for (int i = 0; i &lt; GachaUnitData.Count; i++)
        {
            SaveInInventory(GachaUnitData[i]);
        }
    }

    Main.Get&lt;UIManager&gt;().ClosePopup();
}

private void SaveInInventory(CharacterData data)
{
    Character newChar = new Character(data);
    Main.Get&lt;GameManager&gt;().playerUnits.Add(newChar);
}</code></pre>
<hr>
<p><img src="https://velog.velcdn.com/images/a_zz/post/b9e4f649-1cb5-4f66-9c9b-8969de97f7cc/image.png" alt=""></p>
<p>내일은 오늘 유닛 뽑기 만든 것처럼
Room 과 Item 에도 뽑기 시스템을 적용해 상점 관련 UI 를 변경할 예정 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240206]]></title>
            <link>https://velog.io/@a_zz/TIL240206</link>
            <guid>https://velog.io/@a_zz/TIL240206</guid>
            <pubDate>Tue, 06 Feb 2024 12:27:40 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 ing<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
</li>
</ul>
<blockquote>
<p>최종프로젝트 진행상황</p>
</blockquote>
<p>오늘의 작업 :</p>
<ul>
<li>랜덤 뽑기 시스템 기획 및 설계 ing</li>
</ul>
<p><img src="https://velog.velcdn.com/images/a_zz/post/0b58bf5c-1533-436d-8859-e3dd178d6513/image.png" alt=""></p>
<p>바로 코드 작성 전에 어떤식으로 진행하고 싶은지
이것저것 의식의 흐름대로 적어보며 진행해봤다.
뭔가 글로만 코드 설계를 하려고 하니 감이 잘 안 와서
UI적인 작업도 간단하게 병행하며 진행해야겠다는 생각이 들었다.</p>
<p>튜터님께 피드백도 받으며 기획과 재미 요소에 대해 더욱 깊게 생각해봐야할 것 같기도 하고 !
일단 내일의 나 파이팅 :-)</p>
<hr>
<hr>
<p><strong><em>튜터님의 피드백 - 유저테스트 및 앞으로의 방향성에 관하여.</em></strong></p>
<ul>
<li><p>유저테스트는 MVP 보다 발전한 ! 아주 조금의 버그만 있는 상태여야 한다 !</p>
</li>
<li><p>(1차)유저테스트 19일부터 하는 것 추천</p>
</li>
<li><p>유저테스트 오래 올려놓는다고 사람들이 적극적으로 참여하는것은 아님 ~</p>
</li>
<li><p>유저테스트 하면서 구글플레이스토어 심사 받자</p>
</li>
<li><p>구글플레이 스토어 올리고 2차 유저테스트 받는거죠</p>
<ul>
<li>이 때 저번에 말씀하신 지표 봐도 되고 !</li>
</ul>
</li>
<li><p>유저테스트를 안드로이드 자체 베타 테스트 ? 그걸로 해도 된다</p>
</li>
<li><p>상품거는방식</p>
<ul>
<li><p>e.g. 상품 건다면 5000원 두 장을 준다</p>
<p>  당첨된 사람 하나 주고, 당첨된 사람 또 주고(?)</p>
</li>
<li><p>e.g. 스테이지 끝까지 완료하고 인증한 후에 그들에게 상품을 주는 방식</p>
</li>
<li><p>e.g. 유저테스트를 특정 인원 참여 달성하면 상품 돌린다 !</p>
</li>
<li><p>e.g. 특정 스테이지 이상 깬 사람들한테 어떤어떤 상품 제공, 스테이지 수 올라갈수록 상품의 품질(?)도 ↑</p>
</li>
</ul>
</li>
<li><p>유저테스트로 캠프 내부에서 테스트 돌리는 것도 괜찮게 생각하심.</p>
</li>
</ul>
<hr>
<p>튜터님이 생각하시는 <strong>재미 요소 TODOs</strong> :</p>
<ul>
<li><p>유닛 -&gt; 다양화 please ~</p>
<ul>
<li>그래야 전략 요소 ↑</li>
<li>앞라인, 뒷라인 - 라인제</li>
</ul>
</li>
<li><p>다양한 적 -&gt; 근거리 및 원거리</p>
</li>
<li><p>스테이지도 10~15개 !</p>
</li>
<li><p>함정타일을 따로 빼는 것보다 유닛을 다양하게 하는 법(e.g. 속성 도입하는 방법 ?)</p>
</li>
<li><p>전략 !!!!!!!!!!!!!</p>
<ul>
<li>유저들이 좋아할 만한 요소들을 넣어줘야해요 :)</li>
</ul>
</li>
<li><p>적어도 30분 플레이 할 수 있게끔 !</p>
</li>
</ul>
<hr>
<hr>
<p>2/19 에 -&gt; <strong>1차 테스트</strong> (2/19~21)</p>
<p>오류 체크하고</p>
<p>2/22 또는 23 ~ 26 -&gt; <strong>2차 테스트</strong> (목,금 ~ 월요일까지)</p>
<p>2차 유저테스트 할 때에는 앱스토어에서 다운받게끔 하는 것이 목표</p>
<p>그 후에 이벤트 받고 데이터 기반으로 업데이트 하는 방식 !</p>
<p>이걸 바탕으로 1주일동안 개선작업</p>
<hr>
<ul>
<li><p>유니티 게이밍 서비스</p>
<ul>
<li>애널릭틱스<ul>
<li>유저들의 플레이 시간, 이벤트 트레킹 etc</li>
</ul>
</li>
</ul>
</li>
<li><p>80% 느낌이 50%라는 것.</p>
</li>
<li><p>게임이 계산기게임이 되면 안 된다.</p>
</li>
<li><p>죽고나서 게임 처음부터 시작한다는 요소</p>
<ul>
<li>매우 위험한 요소<ul>
<li>유저들은 게임을 껐다가 다시 킬 확률 높다.</li>
</ul>
</li>
</ul>
</li>
<li><p>배속을 캐시로 파는 아이디어</p>
</li>
<li><p>CDO 와 쿠키런킹덤 레퍼런스로 삼아보자 !</p>
<p>  설날에 츄라이 ~ :)</p>
</li>
<li><p>경영 ! 도 설계를 잘 할 것 !</p>
</li>
</ul>
<hr>
<p>추가로,
<a href="https://docs.unity3d.com/kr/530/ScriptReference/Random.Range.html">Random.Range</a> 에 대해서
Range 의 범위가
float 값이면 min <span style="color:yellowgreen">[inclusive]</span> and max <span style="color:yellowgreen">[inclusive]</span> 
int 값이면 min <span style="color:yellowgreen">[inclusive]</span> and max <span style="color:#FF92F9">[exclusive]</span> 
이라는 사실을 새롭게 알게 되었다 !
다 max 값은 exclusive 인줄 알았는데 float 는 max 가 inclusive 였다니 !
메모-!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_240205]]></title>
            <link>https://velog.io/@a_zz/TIL240205</link>
            <guid>https://velog.io/@a_zz/TIL240205</guid>
            <pubDate>Mon, 05 Feb 2024 13:03:01 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do_오늘-할-일">to do_오늘 할 일</h2>
<ul>
<li>최종프로젝트 - 중간발표 Dday</li>
</ul>
<h2 id="retro_오늘-한-일회고">retro_오늘 한 일(회고)</h2>
<p>오늘은 내 생일 &amp;&amp; 최종프로젝트 중간발표 Dday !</p>
<p>주말에 ppt 정리 작업을 하면서 이것저것 또 새롭게 공부해야 할 것들을 마주하게 되었다.
e.g. 디자인 패턴 중 싱글톤 패턴, 상태 패턴, MVP 패턴, 팩토리 패턴 etc..</p>
<p>그래도 우리 프로젝트에서 디자인 패턴이 언제 쓰였는지 깔끔하게 정리해주신 굿동님 덕분에 프로젝트의 기술 스택을 (아직 100% 이해는 아니지만) 정리할 수 있었다. 그.. 정말 대단해..</p>
<p>오늘 발표하면서 우리 프로젝트가 받았던 기술질문과 피드백으로는 :</p>
<ul>
<li><p>기술질문
4주 작업시간에 비해 퀄리티 굿 !
간단한 게임이지만, 처리해야 할 것들이 많다고 느껴짐.
질문1 : 이와 관련해서 프레임 드랍도 일어날 것 같은데, 최적화 부분 신경쓰고 있거나 개선으로 고려하고 있는 방안이 있는지 ? 
(앞으로 최적화 부분에 신경 많이 써주세요 ~~!)
질문2 &amp; 3 : 타일 배치관련 어떻게 진행했는지
질문3 : 적의 AI 알고리즘 어떤 방식으로 구현했는지</p>
</li>
<li><p>피드백</p>
<ul>
<li>발표 내용 중 기술적인 부분에서 궁금증 많이 해소 됨. good !</li>
<li>손이 가는 게임 만드는게 좋아요. 이 점에서는 잘 하고 있다.</li>
<li>후킹요소(?), isometric</li>
<li>MVP 잘 만듦.</li>
<li>(유저테스트 전까지는) 플레이 시간을 오래 끌고갈 수 있는 점을 생각해보자 !</li>
<li>5분이 데드타임 기준이라고 하심. !!!!</li>
<li>과연 유저가 5분동안 재미를 충분히 느낄 수 있을까 에 대해 고민해볼 것.</li>
</ul>
</li>
</ul>
<p>중간발표 전 상반기(?) 나의 작업 목록은
MainSceneUI, 상점, 인벤토리 로 정리할 수 있다.</p>
<p>후반기의 임무로는 우선 다음과 같다.</p>
<ul>
<li>랜덤 뽑기 시스템 구현</li>
<li>클리어 &amp; 클리어 실패 ui 수정(스토리와 연관지을 수 있는 방법 think !)</li>
</ul>
<p>그리고 계속해서 개념 공부를 시간날 때마다 진행해나갈 예정 !</p>
<p>🔥</p>
]]></description>
        </item>
    </channel>
</rss>