프로그래밍/유니티 및 C#

[유니티/C#] 책 UI 만들기

바토파 2024. 1. 23. 20:00
반응형

 

 

레시피북

위와 같은 책을 만들어보자.

 

레시피 패널의 구조

구조는 이렇게 되어 있다.

public class RecipePanel : MonoBehaviour
{
    public List<GameObject> recipePages; // 페이지를 저장해둘 리스트
    int pageIndex = 0; // 현재 페이지 인덱스

    public GameObject frontPageButton; // 누르면 앞 페이지로 이동하는 버튼 (왼쪽)
    public GameObject backPageButton; // 누르면 뒤 페이지로 이동하는 버튼 (오른쪽)

    public GameObject pages; // 페이지를 담아둘 부모 오브젝트
    public GameObject pagePrefab; // 페이지 프리팹

	// 레시피북을 여는 버튼을 눌렀을 때
    public void OnRecipeButtonClicked()
    {
    	// 맨 앞 페이지라면 앞 페이지로 이동하는 버튼을 꺼준다
        if (pageIndex == 0)
        {
            frontPageButton.SetActive(false);
        }
		
        // 맨 뒤 페이지라면 뒤 페이지로 이동하는 버튼을 꺼준다
        if (pageIndex + 1 == recipePages.Count)
        {
            backPageButton.SetActive(false);
        }

        recipePages[pageIndex].SetActive(true); // 현재 페이지를 켜준다
        gameObject.SetActive(true); // 패널을 켜준다
        Time.timeScale = 0f; // 일시 정지 시킨다
    }
    
    // 앞 페이지로 이동하는 버튼을 눌렀을 때
    public void OnFrontPageButtonClicked()
    {
        recipePages[pageIndex].SetActive(false); // 현재 페이지를 꺼준다
        pageIndex--; // 페이지 인덱스를 빼서 앞 페이지를 가리키도록 한다
        recipePages[pageIndex].SetActive(true); // 현재 페이지를 켜준다

		// 맨 앞 페이지라면 앞 페이지로 이동하는 버튼을 꺼준다
        if (pageIndex == 0)
        {
            frontPageButton.SetActive(false);
        }

		// 뒤 페이지로 이동하는 버튼이 꺼져있다면 켜준다
        if (backPageButton.activeSelf == false)
        {
            backPageButton.SetActive(true);
        }
    }

    // 뒤 페이지로 이동하는 버튼을 눌렀을 때
    public void OnBackPageButtonClicked()
    {
        recipePages[pageIndex].SetActive(false);
        pageIndex++;
        recipePages[pageIndex].SetActive(true);
		
        // 맨 뒤 페이지라면 뒤 페이지로 이동하는 버튼을 꺼준다
        if (pageIndex + 1 == recipePages.Count)
        {
            backPageButton.SetActive(false);
        }

		// 앞 페이지로 이동하는 버튼이 꺼져있다면 켜준다
        if (frontPageButton.activeSelf == false)
        {
            frontPageButton.SetActive(true);
        }
    }
	
    // 나가기 버튼을 눌렀을 때
    public void OnExitButtonClicked()
    {
        recipePages[pageIndex].SetActive(false); // 현재 페이지를 꺼준다
        gameObject.SetActive(false); // 패널을 꺼준다
        Time.timeScale = 1f; // 일시 정지를 해제한다
    }

	// 패널 초기화
    // 원하는 형태로 만들자
    void InitializeRecipePanel()
    {
        bool isFull = true;
        GameObject tempPage = null;

        for (int i = 1; i < 4; i++)
        {
            if (!GameManager.instance.ownRecipes.TryGetValue(i.ToString(), out var recipes)) continue;
            foreach (string menuName in recipes)
            {
                if (isFull)
                {
                    tempPage = Instantiate(pagePrefab, pages.transform);
                    tempPage.transform.GetChild(0).GetComponent<RecipePage>().UpdatePage(menuName, GameManager.instance.menus[menuName]);
                    recipePages.Add(tempPage);
                    tempPage.transform.GetChild(0).gameObject.SetActive(true);
                    isFull = false;
                }
                else
                {
                    tempPage.transform.GetChild(1).GetComponent<RecipePage>().UpdatePage(menuName, GameManager.instance.menus[menuName]);
                    tempPage.transform.GetChild(1).gameObject.SetActive(true);
                    isFull = true;
                }
            }
        }
        
        gameObject.SetActive(false);
    }

    void Start()
    {
        InitializeRecipePanel();
    }
}

 

Start() 안에 초기화 하는 함수를 넣었는데, 이렇게 만들면 패널을 끈 상태로 시작하면 안 된다.

패널을 끈 상태로 시작한다면 패널을 여는 버튼을 눌렀을 때(위의 예시에서는 OnRecipeButtonClicked) 초기화 되지 않은 상태로 패널이 켜져 오류가 난다.

패널을 꺼둔 상태로 시작하고 싶다면 bool 타입 변수를 선언하여 초기화 했는지를 체크하고 초기화 하는 함수 안에 if 문으로 초기화 했는지를 체크하자.

private bool isInitialized;

public void OnButtonClicked()
{
    if (!isInitialized)
    {
    	Initialize();
        
        isInitialized = true;
    }
}

이런 식으로 만들면 된다.

 

그리고 나는 한 페이지 안에 두 개의 레시피가 들어가도록 만들었다.

초기화 하는 함수 내부를 보면 페이지가 가득 찼을 때(페이지 안에 레시피 두 개가 들어있을 때)는 페이지를 새로 만들어주고

페이지가 가득 차지 않았다면 두 번째 레시피의 내용을 넣어준다.

반응형