Unity基本UIフレームワークのコンパイル

目次

パート 1: UIFrame_1.0

1. UI インターフェイスと要件を構築する

次に、上記の関数コードの欠点に注意してください。

1. BagPanel で Canvas を見つけて、高い結合率で、RolePanel を呼び出します。

2. 最初、RolePanel は非表示状態にあり、transform.Find() を使用してもオブジェクトが見つからない可能性があります。

3. 改善: 各パネルのステータスを制御および管理するための UIManager をセットアップします。

第 4 に、UIFrame1.0 にはまだ欠点があります。

1. 各パネルのリファレンスを個別に記述する必要があり、プロジェクトの複雑さへの対応が困難

2. メモリが急増し、統合シャットダウンの効率が低下します。

3. 各パネルに関数を個別に記述する必要があり、後の展開が貧弱すぎる

2 番目の部分: UIFrame_2.0

1. 新しい要件:


序文: 基礎が必要: MVC アイデア、UGUI、XML 基礎

小さな知識ポイント:

1.リソース: パッケージ化プロセス中、フォルダー内のリソースが有用であるかどうかに関係なく、それらはパッケージ化されます。パッケージ化後、このフォルダーは圧縮された形式で存在し、パッケージ化されたファイルには見つかりません (上限、最大4Gファイルのみ保存可能)

2. 一般的な制約

struct、class、クラス名、インターフェイス名 (継承制約)、new(): パラメーターのないパブリック コンストラクターが必要です

 3. UIコンポーネント - グリッドレイアウトグループ

パート 1: UIFrame_1.0

1. UI インターフェイスと要件を構築する

1. 右下のアイコンをクリックしてパネルを表示します

 2. パネル内に十字 ❌ があります。❌ をクリックしてパネルを閉じます

3. バックパックパネルにボタンが必要です。ボタンをクリックすると、キャラクター属性パネルが開き、キャラクター属性 (RolePanel) が表示されます。

 実装コード: MainPanel

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

public class MainPanel : MonoBehaviour
{
    Button btn_setting;
    Button btn_skill;
    Button btn_bag;
    Button btn_role;

    GameObject mainPanel;
    GameObject rolePanel;
    GameObject bagPanel;
    GameObject settingPanel;
    GameObject skillPanel;

    Transform BtnGroup;
    Transform Canvas;


    void Awake()
    {
        BtnGroup = transform.Find("BtnGroup");
        Canvas = transform.parent;
        Debug.Log(Canvas);

        btn_setting = BtnGroup.Find("Btn_Setting").GetComponent<Button>();
        btn_skill = BtnGroup.Find("Btn_Skill").GetComponent<Button>();
        btn_bag = BtnGroup.Find("Btn_Bag").GetComponent<Button>();
        btn_role = BtnGroup.Find("Btn_Role").GetComponent<Button>();

        settingPanel = Canvas.Find("SettingPanel").gameObject;
        skillPanel = Canvas.Find("SkillPanel").gameObject;
        bagPanel = Canvas.Find("BagPanel").gameObject;
        rolePanel = Canvas.Find("RolePanel").gameObject;


    }

    // Start is called before the first frame update
    void Start()
    {

        btn_setting.onClick.AddListener(() => { settingPanel.SetActive(!settingPanel.activeSelf); });
        btn_skill.onClick.AddListener(() => { skillPanel.SetActive(!skillPanel.activeSelf); });
        btn_bag.onClick.AddListener(() => { bagPanel.SetActive(!bagPanel.activeSelf); });
        btn_role.onClick.AddListener(() => { rolePanel.SetActive(!rolePanel.activeSelf); });

    }

    // Update is called once per frame
    void Update()
    {

    }
}

バッグパネル:

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

public class BagPanel : MonoBehaviour
{
    Transform RolePanel;
    Button btn_RolePanel;
    Transform Canvas;

    Transform Btn_close;
    Button btn_close;

    private void Awake()
    {
        Canvas = transform.parent;
        RolePanel = Canvas.Find("RolePanel");
        btn_RolePanel = transform.Find("Btn_RolePanel").GetComponent<Button>();

        Btn_close = GameObject.Find("Btn_close").transform;
        btn_close = Btn_close.GetComponent<Button>();   
            
    }
    // Start is called before the first frame update
    void Start()
    {
        btn_close.onClick.AddListener(() => {gameObject.SetActive(false); });
        btn_RolePanel.onClick.AddListener(() => { RolePanel.gameObject.SetActive(true); });
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

次に、上記の関数コードの欠点に注意してください。

1. BagPanel で Canvas を見つけて、高い結合率で、RolePanel を呼び出します。

2. 最初、RolePanel は非表示状態にあり、transform.Find() を使用してもオブジェクトが見つからない可能性があります。

3. 改善: 各パネルのステータスを制御および管理するための UIManager をセットアップします。

UIManager脚本:

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

public class UIManager : MonoBehaviour
{
    //UIManager一般会绑定在GameRoot脚本上面
    GameObject Canvas;
    GameObject mainPanel;
    GameObject rolePanel;
    GameObject bagPanel;
    GameObject settingPanel;
    GameObject skillPanel;

    Button btn_setting;
    Button btn_skill;
    Button btn_bag;
    Button btn_role;

    Transform BtnGroup;

    private static UIManager _instance;
    public static UIManager Instance
    {
        get
        {
            return _instance;
        }
    }

    private void Awake()
    {
        _instance = this;

        Canvas = GameObject.Find("Canvas");
        mainPanel = Canvas.transform.Find("MainPanel").gameObject;
        settingPanel = Canvas.transform.Find("SettingPanel").gameObject;
        skillPanel = Canvas.transform.Find("SkillPanel").gameObject;
        bagPanel = Canvas.transform.Find("BagPanel").gameObject;
        rolePanel = Canvas.transform.Find("RolePanel").gameObject;

        BtnGroup = mainPanel.transform.Find("BtnGroup");
        btn_setting = BtnGroup.Find("Btn_Setting").GetComponent<Button>();
        btn_skill = BtnGroup.Find("Btn_Skill").GetComponent<Button>();
        btn_bag = BtnGroup.Find("Btn_Bag").GetComponent<Button>();
        btn_role = BtnGroup.Find("Btn_Role").GetComponent<Button>();

    }

    public void showSettingPanel()
    {
        btn_setting.onClick.AddListener(() => { settingPanel.SetActive(!settingPanel.activeSelf); });
    }

    public void showMainPanel()
    {

    }

    public void showSkillPanel()
    {
        btn_skill.onClick.AddListener(() => { skillPanel.SetActive(!skillPanel.activeSelf); });
    }
    public void showBagPanel()
    {
        btn_bag.onClick.AddListener(() => { bagPanel.SetActive(!bagPanel.activeSelf); });
    }

    public void showRollPanel(bool isShowRollPanel)
    {
        if (isShowRollPanel)
        {
            //btn_role.onClick.AddListener(() => { rolePanel.SetActive(true); });
            rolePanel.SetActive(true);
            return;
        }
        else
        btn_role.onClick.AddListener(() => { rolePanel.SetActive(!rolePanel.activeSelf); });
        
        
    }

    // Start is called before the first frame update
    void Start()
    {
        rolePanel.SetActive(false);
        bagPanel.SetActive(false);
        settingPanel.SetActive(false);
        skillPanel.SetActive(false);

    }

    // Update is called once per frame
    void Update()
    {

    }
}

実行結果:

UIManager1

第 4 に、UIFrame1.0 にはまだ欠点があります。

1. 各パネルのリファレンスを個別に記述する必要があり、プロジェクトの複雑さへの対応が困難

解決策: 各参照はコンテナーに保管され、必要なときにコンテナーから取り出されます。

2. メモリが急増し、統合シャットダウンの効率が低下します。

最初に見つけられるようにするには、最初に各パネルを開いて、見つけたら閉じる必要があるため、ゲームを開始するとメモリが急増し、起動時の効率が悪くなります。均一に閉じた。

解決策: ゲームの実行を開始するとき、すべてのパネルを開くのではなく、各パネルをプレハブにし、最初に必要なときにロードしてコンテナーに保管し、コンテナーから取り出して再度使用します。

3. 各パネルに関数を個別に記述する必要があり、後の展開が貧弱すぎる

解決策: コンテナ検索メソッドを使用して、操作の特定の参照に対応させます。

2 番目の部分: UIFrame_2.0

1. 新しい要件:

1. UI パネルごとに異なる開閉効果を実現 (移動して開く、回転して開く、拡大・縮小してシェイクして開くなど)

2. 属性パネル内のバックパックパネル => 属性パネル = "火属性パネル" を開き、属性パネル => 属性パネル = "バックパックパネル" 内の火属性パネルを閉じるボタンをクリックして閉じます。

3. UIFrame_1.0の問題を改善し、パネルをプレハブ読み込み方式にし、コンテナを使用して格納する

4. 右下隅のアイコンをクリックすると、残りのアイコンがグレー表示になりクリックできなくなります。

注: Unity で XML ファイルを読み取るときは、XML をどこに配置する必要がありますか? Assets フォルダーの下にありますか? Application.Datapath を使用してファイルを読み取る必要がありますか?

プロジェクトがパッケージ化されると、Assets フォルダーは Unity によってバイナリ ファイルとしてパッケージ化されるため、Application.DataPath は Assets フォルダーの下に xml ファイルを見つけることができず、Resources フォルダーに配置する必要があります。

コード部分:

ファイル読み込みモジュール: XML 設定ファイルを読み込みます

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


public static class ResourcesManager
{

    public static Dictionary<string,GameObject> ResourcesDic = new Dictionary<string,GameObject>();
   /// <summary>
   /// 加载资源:加载预制体
   /// 1、判断容器中是否存在该路径,
   /// 2、如果有的话,直接返回GameObj-------------ect
   /// 3、如果没有的话,调用Resources.Load()加载资源,然后再存入在存入到容器中
   /// </summary>
   /// <param name="path"> 传入一个资源路径 </param>
   /// <returns></returns>
    public static GameObject Load(string path)
    {
        if (ResourcesDic.ContainsKey(path))
        {
            return ResourcesDic[path];
        }
        GameObject gobj= Resources.Load(path) as GameObject;
        //ResourcesDic.Add(path, gobj);
        //索引器
        ResourcesDic[path] = gobj;
        return gobj;
    }

    /// <summary>
    /// 重载:加载非预制体的资源
    /// </summary>
    /// <typeparam name="Object"></typeparam>
    /// <param name="path"></param>
    /// <returns></returns>
    /// Hashtable : 非泛型键值对容器,键名和键值都可以是任意的数据类型
    public static Hashtable ResHtb = new Hashtable();
    //泛型函数
    public static T Load<T>(string path) where T : Object
    {
        if (ResHtb.ContainsKey(path))
        {
            //as:只能是引用类型之间的转换,这里必须约束T为引用类型 
            return ResHtb[path] as T ;
        }
        //Resources.Load()方法能返回的东西必须继承自Object:需要保证T可以隐式转换为Object
        T t= Resources.Load<T>(path);
        ResHtb[path] = t;
        return t;
    }
}

MyUIManager: すべての UI インターフェイスの開閉を管理します。これは、MVC のコントロール層に相当します。

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

public enum MyUIEnum
{
    MainPanel=1,
    RolePanel,
    SkillPanel,
    BagPanel,
    SettingPanel
}

/// <summary>
/// 管理所有UI界面的开启和关闭
/// </summary>
public static class MyUIManager 
{
    public static Transform canvas = null;

    public static Transform ThisCanvas
    {
        get 
        {
            if (canvas ==null)
            {
                canvas = GameObject.Find("Canvas").transform;
            }  
            return canvas;  
        }

    }

    //
    private static Dictionary<MyUIEnum, string> prefabDic = new Dictionary<MyUIEnum, string>();

    private static Dictionary<MyUIEnum, BasePanel> panelDic = new Dictionary<MyUIEnum, BasePanel>();

    private static Stack<BasePanel> UIStack = new Stack<BasePanel>();
    /// <summary>
    /// 一开始的时候,从xml中读取所有UI预制体的地址和枚举类型的对应关系
    /// </summary>
    public static void OnloadXml()
    {
        //TextAsset所有外部加载的文本,使用这个数据类型保存
        TextAsset xml = Resources.Load<TextAsset>("Configs/UIPanel");

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml.text);//加载xml文件中的内容
        XmlNodeList list = xmlDoc.SelectSingleNode("root").ChildNodes;

        foreach (XmlElement item in list)
        {   
            MyUIEnum  uiEnum =(MyUIEnum) int.Parse(item.GetAttribute("id"));
            string path ="Prefabs/"+ item.GetAttribute("path");
            prefabDic.Add(uiEnum, path);

        }

    }

    /// <summary>
    /// 根据枚举(编号)拿到对应的ui预制体
    /// </summary>
    /// <param name="uiEnum"></param>
    /// <returns></returns>
    static BasePanel GetPanel(MyUIEnum uiEnum,Transform parent=null)
    {
        if (panelDic.ContainsKey(uiEnum))
        {
            return panelDic[uiEnum];
        }
        //如果这个界面从来没有被打开过
        string path = prefabDic[uiEnum];
        GameObject prefab = ResourcesManager.Load(path);
        GameObject go = GameObject.Instantiate(prefab);//拿到并实例化预制体
        if (parent ==null)
        {
            parent = ThisCanvas;
        }
        go.transform.SetParent(parent);
        BasePanel panel = go.GetComponent<BasePanel>();
        panelDic.Add(uiEnum, panel);
        return panel;
    }

    public static void Load(MyUIEnum uiEnum,Transform parent = null)
    {
        if (UIStack.Count>0)
        {
            BasePanel topPanel = UIStack.Peek();//拿到栈顶元素但不出栈
            topPanel.Pause();
        }
        BasePanel panel = GetPanel(uiEnum,parent);
        UIStack.Push(panel);
        panel.Enter();

    }

    public static void UnLoad()
    {
        if (UIStack.Count<=0)
        {
            return;
        }
        BasePanel topPanel = UIStack.Pop();
        topPanel.Close();
        if (UIStack.Count > 0)
        {
            BasePanel resumePanel = UIStack.Peek();
            resumePanel.Resume();
        }
    }

    public static void Clear()
    {
        canvas = null;
        UIStack.Clear();
    }

}

おすすめ

転載: blog.csdn.net/qq_53663718/article/details/127717650