[개발일지] 24. 월드 판넬 제작

2025. 1. 23. 21:38·유니티 프로젝트/점토게임

0. 들어가기 전에

이번에는 월드 판넬을 제작했다. 본격적으로 야생 콘텐츠를 만들기 전에 야생 씬으로 넘어갈 수 있도록 하는 판넬을 만들어야 하기 때문이다.

 

 


 

 

1. 게임 오브젝트

이번에 새로 만든 게임 오브젝트는 World Panel 이다.

 

1.1 World Panel

기존 Canvas1 게임 오브젝트에 자식 오브젝트로 World Panel 을 만들었다.

더보기

1. 하이어라키 창

 

 

2. 게임 화면 속 모습

 

 

3. 인스펙터 창 모습

World Panel 게임 오브젝트는 컴포넌트로 Animator 와 World Panel 을 갖는다.

 

1.2 World Button

기존 만들어 놓았던 게임 오브젝트이다. 수정한 내역은 다음과 같다.

더보기

1. 하이어라키 창 모습

 

 

2. 인스펙터 창 모습

기존에 부착해놨던 Button Move 스크립트의 Panel 변수로 새로 만든 World Panel 게임 오브젝트를 할당했다.

 

1.3 Close Button

기존 만들어 놓았던 게임 오브젝트이다. 수정한 내역은 다음과 같다.

더보기

1. 하이어라키 창 모습

 

 

2. 인스펙터 창 모습

OnClick() 에 직접 추가했다. 새로 추가한 내역은 사진 속 빨간색 네모 칸에 있는 것이다. Close Button 을 누르면 World Button 의 ButtonMove 컴포넌트의 CloseButton 메서드를 호출할 수 있도록 했다.

 

즉, 야생 버튼의 스프라이트 상태를 원상태로 돌려놓도록 했다.

 

 


 

 

2. 스크립트

이번에 새로 만든 스크립트는 WorldPanelClayAnim, WorldPanel 이고 ButtonMove 스크립트를 수정했다.

 

2.1 WorldPanel 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;

public class WorldPanel : MonoBehaviour
{
    [Header("World Panel UI")]
    public Button[] worldButtons;
    public Text[] worldTexts;

    [Header("Prices")]
    public int[] worldPrices;

    private void Start()
    {
        SetWorldPanel(); // 버튼 설정
    }

    public void SetWorldPanel()
    {
        for (int i=0; i<worldButtons.Length; i++)
        {
            int price = worldPrices[i];

            // 버튼 난이도에 맞는 가격 소모 메서드 할당
            worldButtons[i].onClick.AddListener(() => GameManager.instance.GetGold(-price));

            // 텍스트에 가격 표시..
            worldTexts[i].text = worldPrices[i] + "";
        }
    }

    public void ClosePanel()
    {
        gameObject.SetActive(false); // 활성화 끄기..
    }
}

 

2.2 WorldPanel 스크립트 설명

더보기

1. 변수

선언한 변수는 다음과 같다.

 

worldButtons 는 월드 판넬의 세 버튼을 넣어놓기 위해 선언한 변수이다. worldTexts 도 같은 맥락이다. worldPrices 는 worldButton 에 GameManager 의 GetGold 메서드를 연결할 때 사용하기 위해 선언했다.

[Header("World Panel UI")]
public Button[] worldButtons;
public Text[] worldTexts;

[Header("Prices")]
public int[] worldPrices;

 

 

2. Start()

버튼에 GetGold 메서드를 연결하는 메서드를 Start 에서 호출했다.

private void Start()
{
    SetWorldPanel(); // 버튼 설정
}

 

 

3. SetWorldPanel()

버튼에 GetGold 메서드를 연결하는 메서드이다. 동시에 텍스트에도 가격을 표시하도록 했다.

 

일단 야생 씬으로 넘어가는 로직은 추가하지 않았다. 이번엔 정말 버튼을 클릭했을 때 골드가 차감되는 기본적인 동작만 하도록 만들었다.

public void SetWorldPanel()
{
    for (int i=0; i<worldButtons.Length; i++)
    {
        int price = worldPrices[i];

        // 버튼 난이도에 맞는 가격 소모 메서드 할당
        worldButtons[i].onClick.AddListener(() => GameManager.instance.GetGold(-price));

        // 텍스트에 가격 표시..
        worldTexts[i].text = worldPrices[i] + "";
    }
}

 

 

4. ClosePanel()

게임 오브젝트 활성화를 끄도록 하는 메서드이다.

public void ClosePanel()
{
    gameObject.SetActive(false); // 활성화 끄기..
}

 

2.3 WorldPanelClayAnim 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.EventSystems;

public class WorldPanelClayAnim : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    [Header("Animation")]
    public Animator anim; // 점토 이미지에 마우스 가져다 대면 애니메이션 실행될 수 있도록..

    private void Awake()
    {
        anim = GetComponent<Animator>();
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        // 마우스 포인터가 이미지에 도달하면 자동으로 호출되는 메서드
        anim.SetBool("isPointerOn", true);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        // 마우스 포인터가 이미지에서 빠져나가면 자동으로 호출되는 메서드
        anim.SetBool("isPointerOn", false);
    }
}

 

2.4 WorldPanelClayAnim 스크립트 설명

더보기

1. 변수

월드 판넬 속 점토에 마우스를 가져다 대면 점토의 모습이 계속해서 변하는 애니메이션을 수행할 것이다. 이를 위해 Animator 타입의 변수를 선언했다.

[Header("Animation")]
public Animator anim; // 점토 이미지에 마우스 가져다 대면 애니메이션 실행될 수 있도록..

 

 

2. Awake()

anim 에 컴포넌트를 할당해주었다.

private void Awake()
{
    anim = GetComponent<Animator>();
}

 

 

3. OnPointerEnter(PointerEventData eventData)

isPointerOn 값을 true 로 설정해서 애니메이션이 수행되도록 했다.

public void OnPointerEnter(PointerEventData eventData)
{
    // 마우스 포인터가 이미지에 도달하면 자동으로 호출되는 메서드
    anim.SetBool("isPointerOn", true);
}

 

 

4. OnPointerExit(PointerEventData eventData)

애니메이션을 Idle 상태로 다시 옮겨가도록 하기 위해 isPointerOn 값을 false 로 설정해줬다.

public void OnPointerExit(PointerEventData eventData)
{
    // 마우스 포인터가 이미지에서 빠져나가면 자동으로 호출되는 메서드
    anim.SetBool("isPointerOn", false);
}

 

2.5 ButtonMove 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ButtonMove : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
    [Header("Animation")]
    Animator anim;

    [Header("Sprite")]
    public Sprite nonClicked;
    public Sprite clicked;

    [Header("Button UI")]
    public Button uiButton;
    public Button[] otherButtons;

    [Header("Panel")]
    public GameObject panel; // 해당 버튼에 맞는 판넬 게임 오브젝트 할당

    [Header("Close Button")]
    public Button closeButton;

    void Start()
    {
        anim = GetComponent<Animator>();
        uiButton = GetComponent<Button>();
    }

    public void ButtonMoveStart()
    {
        // 이미 버튼이 눌려있는 상태에서 마우스를 가져다대면 위아래로 움직이는 모션이 실행되지 않도록..
        if (!anim.GetBool("clicked"))
        {
            anim.SetBool("draged", true); // 값을 true 로 줘서 Draged 애니메이션 실행
        }
        else
        {
            // 버튼이 눌린 상태면 버튼으로 마우스 갖다대도 false 로..
            anim.SetBool("draged", false);
        }
    }

    public void ButtonMoveEnd()
    {
        anim.SetBool("draged", false); // 값을 false 로 줘서 Idle 애니메이션 실행
    }

    public void ButtonClicked()
    {
        for (int i=0; i<otherButtons.Length; i++)
        {
            // 자신을 제외한 다른 버튼 모두 끄기
            otherButtons[i].GetComponent<ButtonMove>().CloseButton();

            if (otherButtons[i].GetComponent<ButtonMove>().panel != null)
            {
                otherButtons[i].GetComponent<ButtonMove>().panel.GetComponent<Animator>().SetBool("isOpened", false); // 창 닫힘 애니메이션 실행
            }
        }

        uiButton.image.sprite = clicked; // 스프라이트를 click 상태로

        if (panel != null)
        {
            panel.GetComponent<Animator>().SetBool("isOpened", true); // 창 열림 애니메이션 실행
        }
        anim.SetBool("clicked", true);
        anim.SetBool("closed", false);

        closeButton.gameObject.SetActive(true); // 클로즈 버튼 활성화
    }


    // Event Handler 이용
    public void OnPointerEnter(PointerEventData eventData)
    {
        ButtonMoveStart();
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        ButtonMoveEnd();
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        ButtonClicked();
    }

    public void ResetButtonSprite()
    {
        // 버튼 스프라이트를 nonClick 상태로 다시 바꿔주기
        uiButton.image.sprite = nonClicked;
        anim.SetBool("clicked", false);
        anim.SetBool("closed", true);
    }

    // 자기 자신을 끄는 함수
    public void CloseButton()
    {
        gameObject.GetComponent<ButtonMove>().ResetButtonSprite(); // 버튼 모습 초기화

        if (gameObject.GetComponent<ButtonMove>().panel != null)
        {
            gameObject.GetComponent<ButtonMove>().panel.GetComponent<Animator>().SetBool("isOpened", false); // 창 닫힘 애니메이션 실행

            if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<ClayPanel>() != null) // 점토 구매 판넬
                gameObject.GetComponent<ButtonMove>().panel.GetComponent<ClayPanel>().ClosePanel(); // 판넬 꺼
            else if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<UpgradePanel>() != null) // 업그레이트 판넬
                gameObject.GetComponent<ButtonMove>().panel.GetComponent<UpgradePanel>().ClosePanel(); // 판넬 꺼
            else if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<WorldPanel>() != null) // 월드 판넬
                gameObject.GetComponent<ButtonMove>().panel.GetComponent<WorldPanel>().ClosePanel(); // 판넬 꺼
        }
    }
}

 

2.6 ButtonMove 스크립트 변경 사항 설명

더보기

1. CloseButton()

기존 메서드에서 월드 판넬을 끄는 로직이 추가되었다.

// 자기 자신을 끄는 함수
public void CloseButton()
{
    gameObject.GetComponent<ButtonMove>().ResetButtonSprite(); // 버튼 모습 초기화

    if (gameObject.GetComponent<ButtonMove>().panel != null)
    {
        gameObject.GetComponent<ButtonMove>().panel.GetComponent<Animator>().SetBool("isOpened", false); // 창 닫힘 애니메이션 실행

        if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<ClayPanel>() != null) // 점토 구매 판넬
            gameObject.GetComponent<ButtonMove>().panel.GetComponent<ClayPanel>().ClosePanel(); // 판넬 꺼
        else if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<UpgradePanel>() != null) // 업그레이트 판넬
            gameObject.GetComponent<ButtonMove>().panel.GetComponent<UpgradePanel>().ClosePanel(); // 판넬 꺼
        else if (gameObject.GetComponent<ButtonMove>().panel.GetComponent<WorldPanel>() != null) // 월드 판넬
            gameObject.GetComponent<ButtonMove>().panel.GetComponent<WorldPanel>().ClosePanel(); // 판넬 꺼
    }
}

 

 


 

 

3. 애니메이션 & 애니메이터

이번에 새로 만든 애니메이터와 애니메이션은 다음과 같다.

 

3.1 WorldPanel 애니메이터, WorldPanelShow, WorldPanelNonShow 애니메이션

WorldPanel 애니메이터는 WorldPanel 의 Animator 컴포넌트 속 Controller 에 부착했다.

더보기

1. 애니메이터 상태

isOpened 값이 true 면 Show 애니메이션이 수행되도록, flase 면 NonShow 애니메이션이 수행되도록 했다.

 

 

2. 애셋

NonShow 에 WorldPanelNonshow 애니메이션, Show 에 WorldPanelShow 애니메이션을 넣어주었다.

 

3.2 WorldPanelClayImageAnim

월드 판넬 속 점토 이미지에 애니메이션을 적용하기 위해 만들었다.

더보기

1. 애셋

 

 

2. 애니메이터 상태

easyButton 컨트롤러를 오버라이딩 한 hardButton, normalButton 컨트롤러가 있다. 즉, 세 개의 컨트롤러 속 상태는 동일하고 각 애니메이션 칸에 포함된 애니메이션만 다르다.

 

isPointerOn 값이 true 가 되면 PointerOn 으로 상태가 넘어가서 점토가 계속해서 모습을 바꾸는 애니메이션이 수행되도록 했다. false 가 되면 Idle 상태로 가도록 했다.

 

 


 

 

4. 결과물

 

 

 

 

'유니티 프로젝트/점토게임' 카테고리의 다른 글
  • [개발일지] 26. 몬스터 기초 제작
  • [개발일지] 25. 야생 씬 기초 제작
  • [개발일지] 23. 도감 애니메이션 적용
  • [개발일지] 22. 데이터 로드 & 반영 로직 수정
dubu0721
dubu0721
dubu0721 님의 블로그 입니다.
  • dubu0721
    dubu0721 님의 블로그
    dubu0721
  • 전체
    오늘
    어제
    • 분류 전체보기 (334)
      • 프로그래밍언어론 정리 (0)
      • 컴퓨터네트워크 정리 (5)
      • 알고리즘&자료구조 공부 (64)
        • it 취업을 위한 알고리즘 문제풀이 입문 강의 (60)
        • 학교 알고리즘 수업 (3)
        • 실전프로젝트I (0)
      • 백준 문제 (193)
        • 이분탐색 (7)
        • 투포인트 (10)
        • 그래프 (7)
        • 그리디 (24)
        • DP (25)
        • BFS (15)
        • MST (7)
        • KMP (4)
        • Dijkstra (3)
        • Disjoints Set (4)
        • Bellman-Ford (2)
        • 시뮬레이션 (3)
        • 백트래킹 (15)
        • 위상정렬 (5)
        • 자료구조 (25)
        • 기하학 (1)
        • 정렬 (11)
        • 구현 (8)
        • 재귀 (8)
        • 수학 (8)
      • 유니티 공부 (11)
        • 레트로의 유니티 게임 프로그래밍 에센스 (11)
        • 유니티 스터디 자료 (0)
        • C# 공부 (0)
      • 유니티 프로젝트 (48)
        • 케이크게임 (13)
        • 점토게임 (35)
      • 언리얼 공부 (10)
        • 이득우의 언리얼 프로그래밍 (10)
      • 진로 (1)
      • 논문 읽기 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    레트로의 유니티 프로그래밍
    스택
    수학
    언리얼
    오블완
    유니티 프로젝트
    티스토리챌린지
    그리디
    우선순위큐
    이벤트 트리거
    백준
    시뮬레이션
    dp
    바킹독
    유니티 공부 정리
    백트래킹
    이득우
    맵
    정렬
    자료구조
    이분탐색
    C#
    BFS
    투포인터
    큐
    해시
    재귀
    그래프
    골드메탈
    유니티
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dubu0721
[개발일지] 24. 월드 판넬 제작
상단으로

티스토리툴바