Administrator
发布于 2025-09-08 / 29 阅读
0
0

我要成为游戏开发高手!!!!!!!!!

(37 封私信 / 81 条消息) 在 Unity 查找场景下的对象,一篇就够了!!! - 知乎

通用的UIPanle管理类

公共UI

UIType

//==========================
// - FileName: UiType.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:存储当前UI的信息,包括名字路径
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class UIType 
{
    /// <summary>
    /// UI名字
    /// </summary>
    public string Name { get; private set; }
    /// <summary>
    /// UI路径
    /// </summary>
    public string Path { get; private set; }

    public UIType(string path)
    {
        Path = path;
        Name = path.Substring(path.LastIndexOf('/')+1); 
        //取最后一个路径前的名称
    } 
}

BasePanel

//==========================
// - FileName: BasePanel.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:所有UI继承的基类
// 包含所有UI面板的状态信息
//==========================
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;


public abstract class BasePanel 
{
    /// <summary>
    /// UI信息
    /// </summary>
    public UIType UIType { get; private set; }
    /// <summary>
    /// UI工具管理器
    /// </summary>
    public UITool UITool { get; private set; }  
    /// <summary>
    /// 面板管理器
    /// </summary>
    public PanleManager PanleManager { get; private set; }
    /// <summary>
    /// UI管理器
    /// </summary>
    public UIManager UIManager { get; private set; }

    public BasePanel(UIType uitype) 
    {
        UIType = uitype;    
    }

    /// <summary>
    /// 初始化UITool
    /// </summary>
    /// <param name="tool"></param>
    public void Initialize(UITool tool)
    {
        UITool = tool;
    }

    public void Initialize(PanleManager panleManager)
    {
        PanleManager= panleManager; 
    }

    public void Initialize(UIManager uIManager)
    {
        UIManager = uIManager;
    }
    /// <summary>
    /// 进入时候的方法,只会执行一次,onLoad
    /// </summary>
    public virtual void OnEnter() { }
    /// <summary>
    /// 暂停执行,点开别的UI,对原有UI的处理
    /// </summary>
    public virtual void OnPuase() 
    {
        UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
    }
    /// <summary>
    /// 暂停结束后继续执行
    /// </summary>
    public virtual void OnResume() 
    {
        UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
    }

    /// <summary>
    /// 退出时执行的方法
    /// </summary>
    public virtual void OnExit() 
    {
        UIManager.DestorySingleUI(UIType);
    }
    

}

PanleManager

//==========================
// - FileName: PanleManager.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:面板的管理器,用栈来存
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class PanleManager 
{
    /// <summary>
    /// 栈来存储UI
    /// </summary>
    private  Stack<BasePanel> stackPanel;
    /// <summary>
    /// 面板管理器
    /// </summary>
    private UIManager uiManager;
    private BasePanel panel;
    public PanleManager()
    {
        stackPanel = new Stack<BasePanel>();
        uiManager = new UIManager();
    }
    /// <summary>
    /// UI的入栈操作,此操作会显示一个面板
    /// </summary>
    /// <param name="nextPanel">要显示的面板</param>
    public void Push(BasePanel nextPanel)
    {
        if (stackPanel.Count > 0)
        {
            panel=stackPanel.Peek();
            panel.OnPuase();
        }
        GameObject panleGo = uiManager.GetSingleUI(nextPanel.UIType);
        nextPanel.Initialize(new UITool(panleGo));
        nextPanel.Initialize(this);  //这里添加的是自己的
        nextPanel.Initialize(uiManager);
        stackPanel.Push(nextPanel);
        nextPanel.OnEnter(); 
    }
    /// <summary>
    /// 弹出操作
    /// </summary>
    public BasePanel Peek()
    {
        if(stackPanel.Count > 0)
        {
            panel= stackPanel.Peek();
            panel.OnResume();
            return panel;
        }
        else
        {
            Debug.LogError("当前无在运行的UI,请注意检查是否入栈");
            return null;
        }
    
    }
    /// <summary>
    /// 删除操作
    /// </summary>
    public void Pop()
    {
        if(stackPanel.Count > 0 )
        {
            panel=stackPanel.Peek();
            panel.OnExit();
            stackPanel.Pop();
            if (stackPanel.Count > 0)
            {
                stackPanel.Peek().OnResume();
            }
        }
        else
        {
            Debug.LogError("当前无在运行的UI,请注意检查是否入栈");
        }
    }

}

StartManager

//==========================
// - FileName: StarManger.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class StartManger : MonoBehaviour 
{
    public PanleManager PanleManager;
    private void Awake()
    {
        PanleManager = new PanleManager();
    }
    private void Start()
    {
        PanleManager.Push(new StarPanle());
    }
}

UITool

//==========================
// - FileName: UITool.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description: UI的管理工具
// 包括获取某个子对象的操作
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UITool 
{   
    /// <summary>
    /// 当前的活动面板
    /// </summary>
    private GameObject activePanle;
    public UITool(GameObject panle)
    {
        activePanle = panle;
    }
    /// <summary>
    /// 给当前的活动面板获取或者添加一个组件
    /// </summary>
    /// <typeparam name="T">组件的类型</typeparam>
    /// <returns>组件</returns>
    public T GetOrAddComponent<T>() where T : Component
    {
        if(activePanle.GetComponent<T>() == null)
        {
            activePanle.AddComponent<T>();
        }
        return activePanle.GetComponent<T>();
    }
    /// <summary>
    /// 根据名称找一个子对象
    /// </summary>
    /// <param name="name">子对象名称</param>
    /// <returns></returns>
    public GameObject FindChildGameObject(string name)
    {
        Transform[] trans= activePanle.GetComponentsInChildren<Transform>();
        //找到所有儿子
        foreach(var item in trans)
        {
            if(item.name == name)
            {
                return item.gameObject;
            }
        }
        Debug.LogError($"{activePanle.name}里找不到名称为" + name + "的prefab");
        return null;
    }
    /// <summary>
    /// 根据名称找子对象的组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <returns></returns>
    public T GetOrAddCopmponentInChildren<T>(string name) where T : Component
    {
        GameObject son=FindChildGameObject(name);
        if (son != null)
        {
            if (son.GetComponent<T>() == null)
                son.AddComponent<T>();
            return son.GetComponent<T>();
        }
        return null;    
    }
}

UIManager

//==========================
// - FileName: UIManager.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:控制UI的创建与销毁
// 存储所有UI信息
//==========================
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;


public class UIManager
{
    /// <summary>
    /// 存储所有UI信息的字典,每一个UI都会对应一个GameObject
    /// </summary>
    private Dictionary<UIType, GameObject> dicUI;

    public  UIManager()
    {
        dicUI= new Dictionary<UIType, GameObject>();   
        

    }
    /// <summary>
    /// 获取UI,没有则创建
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public GameObject GetSingleUI(UIType type)
    {
        GameObject parent = GameObject.Find("Canvas"); //这里的父类是运行时的名称,在页面上
        if (!parent)
        {
            Debug.LogError("ui未添加Canvas,请仔细检查有无对象" + type.Path);
            return null;
        }
        if (dicUI.ContainsKey(type)) return dicUI[type];
        GameObject ui = GameObject.Instantiate(Resources.Load<GameObject>(type.Path), parent.transform);
        ui.name = type.Name;
        dicUI[type] = ui;
        return ui;
    }
    /// <summary>
    /// 销毁一个UI对象
    /// </summary>
    /// <param name="type"></param>
    public void DestorySingleUI(UIType type)
    {
        if(dicUI.ContainsKey(type))
        {

            GameObject.Destroy(dicUI[type]);
            dicUI.Remove(type);
        }
        else
        {
            return ;
        }
    }
}

具体ui的使用

SettingPanle

//==========================
// - FileName: SettingPanel.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class SettingPanel : BasePanel
{
    static readonly string path = "Prefabs/UI/Panle/SetingPanle";
    public SettingPanel() : base(new UIType(path))
    {

    }
    public override void OnEnter()
    {
        Debug.Log("yzh进入设置界面");
        UITool.GetOrAddCopmponentInChildren<Button>("BtnExit").onClick.AddListener(() =>
        {
            Debug.Log("销毁");
            PanleManager.Pop();
        });
    }

}

StarPanle

//==========================
// - FileName: StarPanle.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description: 开始面板
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class StarPanle : BasePanel
{
    static readonly string path = "Prefabs/UI/Panle/Canvas2";
    public StarPanle() : base(new UIType(path))
    {

    }
    public override void OnEnter()
    {
        UITool.GetOrAddCopmponentInChildren<Button>("btn1").onClick.AddListener(() =>
        {
            Debug.Log("yzh真帅");
           PanleManager.Push(new  SettingPanel());
        });
    }
    /*
     * 这些都移到父类去写
    public override void OnPuase()
    {
        UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
    }
    public override void OnResume()
    {
        UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
    }
    public override void OnExit()
    {
        UIManager.DestorySingleUI(UIType);
    }
    */
}

场景管理TODO


评论