Unity 고급 학습 노트: UI 프레임워크

일반적으로 게임에는 많은 수의 UI 구성 요소가 있습니다. 이전 메시지 프레임워크를 그대로 사용하여 모든 UI 관련 정보를 처리한다면 매우 복잡하고 비효율적일 것입니다. 따라서 UI 시스템을 독립적인 시스템으로 취급하여 UI 프레임워크를 구축합니다.

UI 프레임워크는 크게 3개의 레이어로 구분됩니다. UIManager는 모든 UI 구성 요소를 관리하는 데 사용되고 UIController는 역할 정보 패널, 상점 패널 등과 같은 특정 UI 패널을 관리하는 데 사용됩니다. UIControl은 각각의 개별 UI 구성요소를 제어하는 ​​데 사용됩니다.

UI 시스템에서는 이전 메시지 시스템에서 사용된 브로드캐스트 프레임워크를 버립니다. 이 솔루션은 각 UI 구성 요소에 대해 특별히 메시지를 보내고 받는 메서드를 작성해야 하는데 너무 복잡하기 때문입니다. UIController 및 UI Manager를 통해 각 UI 구성 요소가 다른 UI 구성 요소에 액세스할 수 있기를 바랍니다. 예를 들어, "상점" 컨트롤러의 버튼 구성 요소는 "백팩" 컨트롤러의 배낭 격자 그림을 직접 변경할 수 있으며 상점에서 구입한 항목을 배낭에 추가하는 기능을 직접 실현할 수 있습니다.

1 UIManager

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

public class UIManager : ManagerBase<UIManager> {
    
    

    public Dictionary<string, UIController> UIControllerDic = new Dictionary<string, UIController>();

    public void SetActive(string controllerName, bool active) {
    
    
        transform.Find(controllerName).gameObject.SetActive(active);
    }

    public UIControl GetUIControl(string controllerName, string controlName) {
    
    
        if (UIControllerDic.ContainsKey(controllerName)) {
    
    
            if (UIControllerDic[controllerName].UIControlDic.ContainsKey(controlName)) {
    
    
                return UIControllerDic[controllerName].UIControlDic[controlName];
            }
        }

        return null;
    }

    public override byte GetMessageType() {
    
    
        return MessageType.Type_UI;
    }


}

여기에서는 UIManager 아래에 모든 UIController를 저장하기 위한 사전을 만듭니다.

SetActive 메서드에서 각 UIController의 스위치를 제어합니다. GetUIControl은 특성 UIControl을 찾는 데 사용됩니다. 여기서 먼저 해당 UIController를 찾은 다음 UIController 아래에서 UIControl을 찾습니다. 이 방법은 순회할 구성 요소 수를 줄이고 효율성을 개선하며 다른 UIController에서 동일한 이름을 가진 구성 요소 문제를 피할 수 있습니다.

UIManager uiManager = UIManager.Instance as UIManager;

이 문장이 하는 일에 주목하세요. UIManager 클래스는 ManagerBase를 상속하고 ManagerBase는 SingletonBase를 상속하고 해당 유형을 ManagerBase로 만듭니다. 이로 인해 UIManager.Instance 유형이 여전히 ManagerBase에 속하게 되어 문제가 발생합니다. 따라서 여기에서 ManagerBase를 UIManager로 다운캐스트해야 합니다.

2 UI 컨트롤러

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

public class UIController : MonoBehaviour
{
    
    
    
    public Dictionary<string, UIControl> UIControlDic = new Dictionary<string, UIControl>();

    void Awake() {
    
    
        UIManager.Instance.UIControllerDic.Add(transform.name, this);
        foreach (Transform trans in transform) {
    
    
            if (trans.gameObject.GetComponent<UIControl>() == null) {
    
    
                trans.gameObject.AddComponent<UIControl>();
            }
        }
    }
}


UIController 아래에 UIControls를 저장하려면 UIController에 사전을 만듭니다.

Awake 메서드에서는 먼저 UIManager 사전에 구성 요소를 등록합니다. 동시에 하나의 UIController 아래에 많은 UI 구성 요소가 있을 수 있다는 점을 고려하면 수동으로 추가하는 것은 너무 번거로울 것입니다. 따라서 UIController 아래의 UI 객체를 순회하고 각각에 UIControl 구성 요소를 추가합니다.

3 UI 컨트롤

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

public class UIControl : MonoBehaviour
{
    
    
    void Awake() {
    
    
        if (transform.parent != null) {
    
    
            UIController controller = transform.GetComponentInParent<UIController>();
            if (controller != null) {
    
    
                controller.UIControlDic.Add(transform.name, this);
            }
        }
    }


    public void ChangeText(string str) {
    
    
        if (GetComponent<Text>() != null) {
    
    
            GetComponent<Text>().text = str;
        }
    }

    public void ChangeImage(Sprite sprite) {
    
    
        if (GetComponent<Image>() != null) {
    
    
            GetComponent<Image>().sprite = sprite;
        }
    }

    public void AddButtonClickEvent(UnityAction action) {
    
    
        Button control = GetComponent<Button>();
        if (control != null) {
    
    
            control.onClick.AddListener(action);
        }
    }

    public void AddSliderEvent(UnityAction<float> action) {
    
    
        Slider control = GetComponent<Slider>();
        if (control != null) {
    
    
            control.onValueChanged.AddListener(action);
        }
    }

    public void AddInputFieldEvent(UnityAction<string> action) {
    
    
        InputField control = GetComponent<InputField>();
        if (control != null) {
    
    
            control.onValueChanged.AddListener(action);
        }
    }
}

Awake 메서드에서 UIControl 구성 요소를 UIController에 등록합니다. 여기서 우리는 프레임워크의 구축을 완료했습니다. 후속 ChangeText, ChangeImage, AddButtonClickEvent 및 AddInputFieldEvent는 UI 작업을 용이하게 하는 함수입니다. 다음은 AddButtonClickEvent를 예로 들어 보겠습니다.

    public void AddButtonClickEvent(UnityAction action) {
    
    
        Button control = GetComponent<Button>();
        if (control != null) {
    
    
            control.onClick.AddListener(action);
        }
    }

AddButtonClickEvent의 파라미터 타입은 UnityAction으로 익명 메소드로 이해할 수 있으며, UnityAction 타입을 사용하기 위해서는 UnityEngine.Events를 임포트해야 합니다. 다음 프로그램에서는 게임 개체의 버튼 구성 요소 컨트롤을 가져오고 컨트롤에 액션 리스너를 마운트합니다.

다른 방법의 구현 원칙은 유사하며 후속 개발에서 실제 필요에 따라 더 많은 UI 제어 방법을 추가할 수 있습니다.

추천

출처blog.csdn.net/Raine_Yang/article/details/130617771