정리/UNITY

Menu_UI 기능 구현

원클릭쓰리버그 2022. 4. 25. 11:26
728x90

위의 기능을 구현해보자.

 

메뉴 인터페이스 만들기

 

 

 

 

기능 구현

  1. EducationPage에서 메뉴 버튼을 연동시킨다.
  2. 각 챕터 버튼 클릭 시, 생략 및 확장 기능

기능 구성도 

  • 메뉴를 관리해주는 Script
  • 생략 및 확장 기능을 구현할 Script

 

생략 및 확장 기능 Script

요약 : 각 챕터 하위단의 버튼들은 상위 챕터의 위치를 저장하며, 챕터는 메뉴를 저장받아 서로 간 연결을 통해 메뉴 버튼을 생성한다.

 

 

 

챕터_ 스크립트

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

public class Chapter_Btn: MonoBehaviour
{
    int pre; // 자신의 상위 menu 버튼 인덱스값
    private int index; // 자신의 인덱스 값
   
    public bool isExtend; // 확장 여부
    Chapter root; // 자신의 부모
    Transform ssub_box; // 하위단 버튼을 모아놓은 오브젝트	
    public Transform[] ssub_btns; // 하위단의 버튼들
    Button m_btn;

    Vector3 m_Position;
    public int INDEX { get { return index; } }

    private void Awake()
    {
        isExtend = true;

        m_btn = GetComponent<Button>();
        m_btn.onClick.AddListener(Click_Self);
    }
	//초기값 설정
    public void Init(int idx, Chapter r) // idx == chapter / 0 == chapter1
    {
        if(ssub_box == null || ssub_btns == null)
        {
            ssub_box = transform.GetChild(0);
            ssub_btns = new Transform[ssub_box.childCount];
        }

        for (int i = 0; i < ssub_btns.Length; i++)
        {
            ssub_btns[i] = ssub_box.GetChild(i);
            ssub_btns[i].GetComponent<Education_Btn>().Init(this,i); //chapter 1-1 => [0,0]
        }

        index = idx;
        root = r;
        
        if(index ==0)
        {
            pre = int.MaxValue;
        }    
        else if(index == root.m_ChapterBtns.Length-1)
        {
            pre = index - 1;
        }
        else
        {
            pre = index - 1;
        }

        if (pre != int.MaxValue)
        {
            Chapter_Btn prebtn = root.m_ChapterBtns[pre].GetComponent<Chapter_Btn>();
            Transform pretransform = prebtn.ssub_btns[prebtn.ssub_btns.Length-1];
            Rect rect = pretransform.GetComponent<RectTransform>().rect;
            m_Position = pretransform.position - new Vector3 (0,rect.height);
            transform.position = m_Position;
        }
    }


    void Click_Self()
    {
        if (isExtend) // 확장 시, 닫아준다.
        { 
            CloseSet();  
            isExtend = false;
        }
        else 		// 생략 시, 확장한다.
        { 
            Extend(); 
            isExtend = true;
        }
    }

    void Extend()
    {
        for (int i = 0; i < ssub_btns.Length; i++)
        {
            Education_Btn child_s = ssub_btns[i].GetComponent<Education_Btn>();
            child_s.gameObject.SetActive(true);
            ssub_btns[i].position = child_s.pre_Position;

        }
        root.Init();
    }

    void CloseSet()
    {
        for (int i = 0; i < ssub_btns.Length; i++)
        {
            ssub_btns[i].position = transform.position;
            ssub_btns[i].gameObject.SetActive(false);
        }
        root.Init();
    }
}

 

 

버튼_ 스크립트

 

using UnityEngine;
using UnityEngine.UI;
using System;
public class Education_Btn : MonoBehaviour
{
    EducationPage educationPage;
    GameObject window_respown;
    ObjectPool objpool;

    int index; // 자신의 인덱스값
    Button m_btn;
    Vector3 extend_Position; // 확장 될 시 위치할 저장값

    Chapter_Btn parent_s; //자신의 상위 챕터
    
    public Vector3 pre_Position { get { return extend_Position; } }

    int reload_num; // 클릭 시, 로드될 스테이지 번호

    private void Awake()
    {
        extend_Position = transform.position;
        educationPage = GameManager.Instance.Get_GamePageScript<EducationPage>(_Enum.GAMESTATE.EducationPage);
    }
    
    public void Init(Chapter_Btn p, int idx)
    {
        objpool = GameManager.Instance.ObjPool;

        index = idx;
        if(m_btn == null)
        {
            m_btn = GetComponent<Button>();
            m_btn.onClick.AddListener(Click_Btn);
        }
        parent_s = p;
        
    }
    private void OnEnable()
    {
        if(parent_s !=null) // 자신의 인덱스 만큼 위치값을 저장한다.
            extend_Position = parent_s.transform.position - new Vector3(0, (GetComponent<RectTransform>().rect.height * ((index % 10) + 1)));
    }

    private void OnDisable()
    {
        extend_Position = parent_s.transform.position - new Vector3(0, (GetComponent<RectTransform>().rect.height * ((index % 10) + 1)));
    }

    void Click_Btn()
    {
        string prefab_name;
        
        if (index == 0)
            prefab_name = "Chapter" + (parent_s.INDEX + 1);
        else
            prefab_name = "Chapter";
        

        reload_num = (parent_s.INDEX + 1) * 10 + (index + 1);

        Debug.Log($"reload_num is {reload_num}");

        window_respown = educationPage._interface;

        if(window_respown.transform.childCount !=0)
        {
            for (int i = 0; i < window_respown.transform.childCount; i++)
            {
                objpool.Restore(window_respown.transform.GetChild(i).gameObject);
            }
        }
        GameObject obj =  objpool.Get_Object(null, window_respown.transform, $"Prefabs/Chapter/{prefab_name}");

        if (index != 0)
            obj.GetComponent<ChapterBase>().Init(reload_num);

        educationPage._Chapter.SetActive(false);
    }
}

'정리 > UNITY' 카테고리의 다른 글

유니티 게임 내 Scripts 최적화 (Unity Article)  (0) 2022.04.28
Unity 성능 향상을 위한 권장사항 (Microsoft)  (0) 2022.04.28
IL2CPP  (0) 2022.03.19
효율적 UI_Component 바인딩  (0) 2022.03.08
Unity Shader (셰이더)  (0) 2022.03.08