Unity组件开发--UI管理器

1.Canvas组件:

Unity组件开发--UI管理器_第1张图片注意属性:

(1)渲染模式是:屏幕空间相机

(2)创建一个UICamera节点,管理相机

(3)屏幕画布缩放模式

(4)画布下挂载两个脚本:UIRoot和UIManager

(5)事件系统管理节点必须有:

Unity组件开发--UI管理器_第2张图片

2.画布下其他节点类型:用于不同界面类型的管理归类window类型

Unity组件开发--UI管理器_第3张图片

3.先看UIRoot脚本:

using UnityEngine;

/// 
/// 这个脚本用来定位UIROOT,因为GameObject.Find在浏览器上会踩坑
/// 
public class UIRoot : MonoBehaviour {

    private void Awake() {
        DontDestroyOnLoad(gameObject);
    }

    void Start () {
    }

}

4.所有的UI界面预设体都用一个json文本管理起来:UIPanelType

Unity组件开发--UI管理器_第4张图片

{
"infoList":
[

{"panelTypeString":"HOME_PANEL",
"path":"HomePanel"},

{"panelTypeString":"WELCOME_PANEL",
"path":"WelcomePanel"},

{"panelTypeString":"MAIN_PANEL",
"path":"MainPanel"}

]
}

5.上面这个json文件中的path,对应的就是UI预设体的名字:由于我们的UI预制体都是用AB包的方式加载的,就都放在BundleAsset文件夹中

Unity组件开发--UI管理器_第5张图片

6.C#代码中也有有一个对应UI预设体名字的枚举类:

public enum UIPanelType {
    ALERT_PANEL,
    CONNECT_PANEL,
    HOME_PANEL,
    WELCOME_PANEL,
    MAIN_PANEL,
}

7.然后所有UI类脚本必须继承的基类:BasePanel

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

[RequireComponent(typeof(CanvasGroup))]
public class BasePanel : MonoBehaviour {

    public enum PanelLayer {
        Normal,
        Hud,
        Addition,
        Windows,
        Wanring,
        ModelView,
    }

    [HideInInspector]
    public UIPanelType panelTpe;

    public PanelLayer Layer;


    protected CanvasGroup canvasGroup;
    protected virtual void Awake() {

        子类会继承这个函数,所以这里不应该写任何代码
        //name = GetType() + ">>";
        //canvasGroup = gameObject.GetComponent();
    }

    protected new string name;



    /// 
    /// 开启交互,页面显示
    /// 
    public virtual void OnEnter() {
        //Debug.Log(name + "Enter");
        
        SetPanelActive(true);
        SetPanelInteractable(true);

    }

    /// 
    /// 界面暂停,关闭交互
    /// 
    public virtual void OnPause() {
        SetPanelInteractable(false);
    }

    /// 
    /// 界面继续,恢复交互
    /// 
    public virtual void OnResume() {
        SetPanelInteractable(true);
    }

    /// 
    /// 界面不显示,退出这个界面,界面被关闭
    /// 
    public virtual void OnExit() {
        SetPanelActive(false);
        SetPanelInteractable(false);
    }


    /// 
    /// 关闭自身
    /// 
    public void CloseSelf() {
        SetPanelActive(false);
        UIManager.Instance.CloseWindowMask();
        UIManager.Instance.ClosePannel(panelTpe);
    }

    private void SetPanelActive(bool isActive) {
        //isActive ^= this.gameObject.activeSelf;
        bool compare = isActive ^ gameObject.activeSelf;
        if (compare) {
            gameObject.SetActive(isActive);
        }
    }

    private void SetPanelInteractable(bool isInteractable) {
        //canvasGroup = canvasGroup == null ? gameObject.GetComponent() : canvasGroup;
        //bool compare = isInteractable ^ canvasGroup;
        //if (compare) 
        //{
        //    canvasGroup.interactable = isInteractable; 
        //}
        //canvasGroup = canvasGroup == null ? gameObject.GetComponent() : canvasGroup;
        //if (isInteractable ^ canvasGroup.interactable) canvasGroup.interactable = isInteractable;
    }

}

8.UI管理器脚本:UIManager

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using static BasePanel;

public class UIManager : MonoBehaviour {

    private static UIManager sInstanceUiManager;
    private Dictionary mPanelPathDictionary;//存储所有面板Prefab的路径
    private Dictionary mPanelPool;//保存所有实例化面板的游戏物体身上的BasePanel组件
    private Stack mPanelStack; //TODO:需要拆分成多个堆栈,否则会有各种奇怪的问题


    private Transform mUIRootTransform;
    private GameObject windowsMask;
    
    
    
    
    

    public static UIManager Instance
    {
        get { return sInstanceUiManager; }
    }


    [Serializable]
    public class UIPanelTypeJson {
        public List infoList;
    }
    /// 
    /// 实例化UIManager
    /// 
    /// 



    void Awake() {
        sInstanceUiManager = this;
        DontDestroyOnLoad(gameObject);

        ParseUIPanelTypeJson();
        mUIRootTransform = GameObject.FindAnyObjectByType().transform;
        windowsMask = mUIRootTransform.Find("Windows/Mask").gameObject;
        windowsMask.GetComponent

9.AB包加载管理器:AssetBundleManager

using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

public class AssetBundleManager : MonoBehaviour {
    private static AssetBundleManager instance;

    

    private Dictionary>> m_loadingActions = new Dictionary>>(); 

    public static AssetBundleManager Instance {
        get {
            if (instance == null) {
                instance = new GameObject("AssetBundleManager").AddComponent();
            }
            return instance;
        }
    }

    private Dictionary loadedAssetBundles = new Dictionary();

    //public AssetBundle LoadAssetBundle(string bundleName, string sceneName = "") {
    //    if (loadedAssetBundles.ContainsKey(bundleName)) {
    //        return null;
    //    }

    //    string path = Application.streamingAssetsPath + "/" + bundleName;
    //    AssetBundle bundle = AssetBundle.LoadFromFile(path);
    //    if (bundle == null) {
    //        Debug.LogError($"Failed to load asset bundle: {bundleName}");
    //        return null;
    //    }

    //    loadedAssetBundles.Add(bundleName, bundle);

    //    if (!string.IsNullOrEmpty(sceneName)) {
    //        SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
    //    }

    //    return bundle;
    //}

    public void UnloadAssetBundle(string bundleName, string sceneName = "") {
        if (!loadedAssetBundles.ContainsKey(bundleName)) {
            return;
        }

        AssetBundle bundle = loadedAssetBundles[bundleName];
        bundle.Unload(true);
        loadedAssetBundles.Remove(bundleName);

        if (!string.IsNullOrEmpty(sceneName)) {
            SceneManager.UnloadSceneAsync(sceneName);
        }
    }

    public bool IsAssetBundleLoaded(string bundleName) {
        return loadedAssetBundles.ContainsKey(bundleName);
    }

    /// 
    /// 示例 Prefab/Com/NpcHello
    /// 
    /// 
    /// 
    public void LoadPrefab(string prefabPath,System.Action callback) {

        if (m_loadingActions.TryGetValue(prefabPath,out var list)) {
            list.Add(callback);
            return; //这里返回不需要再开启协程
        }
        else {
            m_loadingActions.Add(prefabPath, new List>());
            m_loadingActions[prefabPath].Add(callback);
        }

        StartCoroutine(LoadPrefabCoroutine(prefabPath));
    }

    enum Platefrom
    {
        PC,
        Mobile
    }


    string GetPrefabName(string prefabPath, Platefrom platefrom)
    {
        string desPlatform = "";
        if (platefrom == Platefrom.Mobile)
        {

            desPlatform = prefabPath + "_Mobile";

        }
        else
        {
            desPlatform = prefabPath;

        }
        var prefabName = UtilsFunc.GetFileNameWithoutExtension(desPlatform) + ".prefab";
        return prefabName;
    }

    
    private IEnumerator LoadPrefabCoroutine(string prefabPath) {
        
        var desPlatform = "";
        Debug.Log("UI路径LoadPrefabCoroutine......" + prefabPath);
        if (!PlayerData.Instance.isRunningPC)
        {

            desPlatform = prefabPath + "_Mobile";
            
        }
        else
        {
            desPlatform = prefabPath;

        }

        desPlatform = $"{Host.AssetBundleIP}/{desPlatform.ToLower()}.bundle";
        string prefabName = "";
        string bundlePath = $"{prefabPath.ToLower()}.bundle";
        string fullBundlepath = $"{Host.AssetBundleIP}/{bundlePath.ToLower()}";
        AssetBundle bundle = null;
        if (loadedAssetBundles.ContainsKey(prefabPath)) {
            yield return new WaitForEndOfFrame();
            bundle = loadedAssetBundles[prefabPath];
            if (bundle.Contains(GetPrefabName(prefabPath,Platefrom.Mobile)))
            {
                prefabName = GetPrefabName(prefabPath, Platefrom.Mobile);
            }
            else
            {
                prefabName = GetPrefabName(prefabPath, Platefrom.PC);
            }
        }
        else {
#if UNITY_EDITOR
            if (AppConst.useShowBundlePath) { //打需要演示的包时候需要先读取本地的streamAsset,如果存在侧不执行
                    var showBundlePath = Application.streamingAssetsPath + $"/webgl/{bundlePath.ToLower()}";
                    Debug.Log("showBundlePath:"+ showBundlePath);
                    UnityWebRequest showRequest = UnityWebRequestAssetBundle.GetAssetBundle(showBundlePath);
                    yield return showRequest.SendWebRequest();

                    if (showRequest.result == UnityWebRequest.Result.Success) {
                        Debug.Log($"load bundle ok: {showBundlePath}");
                        bundle = DownloadHandlerAssetBundle.GetContent(showRequest);
                    }
                    else {
                        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                        yield return request.SendWebRequest();
                        if (request.result != UnityWebRequest.Result.Success) {
                            Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                            yield break;
                        }
                        Debug.Log($"load bundle ok: {fullBundlepath}");
                        bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }
                }else {
                    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(desPlatform);
                    yield return request.SendWebRequest();
                    if (request.result != UnityWebRequest.Result.Success) {
                        Debug.LogError($"Failed to load asset bundle at path: {desPlatform}");
                        request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                        yield return request.SendWebRequest();
                        if (request.result != UnityWebRequest.Result.Success) {
                            Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                            yield break;
                        }
                        Debug.Log($"load bundle ok: {fullBundlepath}");
                        prefabName = GetPrefabName(prefabPath,Platefrom.PC);
                        bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }else{
                    
                         Debug.Log($"load bundle ok: {desPlatform}");
                         prefabName =  GetPrefabName(prefabPath, PlayerData.Instance.isRunningPC ? Platefrom.PC : Platefrom.Mobile);
                         bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }
                   

                }
#else


            UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(desPlatform);
            yield return request.SendWebRequest();
            if (request.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"Failed to load asset bundle at path: {desPlatform}");

                request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                yield return request.SendWebRequest();
                if (request.result != UnityWebRequest.Result.Success)
                {
                    Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                    yield break;
                }

                Debug.Log($"load bundle ok: {fullBundlepath}");
                bundle = DownloadHandlerAssetBundle.GetContent(request);
                prefabName = GetPrefabName(prefabPath,Platefrom.PC);

            }
            else {
                Debug.Log($"load bundle ok: {desPlatform}");
                prefabName = GetPrefabName(prefabPath, PlayerData.Instance.isRunningPC ? Platefrom.PC : Platefrom.Mobile);
                bundle = DownloadHandlerAssetBundle.GetContent(request);
            }
            
           
#endif
            loadedAssetBundles.Add(prefabPath, bundle);
        }

        
     
        if (bundle == null) {
            Debug.LogError($"Failed to get asset bundle content at path: {fullBundlepath}");
            doCallBack(prefabPath);
             yield break;
        }
        else {
            ResetBundleMaterials(bundle);
        }

        Debug.Log($"load bundle ok: {fullBundlepath}");
        AssetBundleRequest prefabRequest = bundle.LoadAssetAsync(prefabName);
        yield return prefabRequest;

        if (prefabRequest.asset == null) {
            Debug.LogError($"Failed to load prefab {prefabName} from asset bundle at path: {desPlatform}");
            doCallBack(prefabPath);
            yield break;
        }

        doCallBack(prefabPath, prefabRequest.asset);
        //bundle.UnloadAsync(true);
    }

    public void PreLoadBundle(string prefabPath) {
        StartCoroutine(PreLoadBundleCoroutine(prefabPath));
    }

    private IEnumerator PreLoadBundleCoroutine(string prefabPath) {


        var desPlatform = "";
        Debug.Log("UI路径PreLoadBundleCoroutine......" + prefabPath);
        if (!PlayerData.Instance.isRunningPC)
        {

            desPlatform = prefabPath + "_Mobile";
        }
        else
        {
            desPlatform = prefabPath;

        }

        desPlatform = $"{Host.AssetBundleIP}/{desPlatform.ToLower()}.bundle";

        string bundlePath = $"{prefabPath.ToLower()}.bundle";
        string prefabName = "";

        string fullBundlepath = $"{Host.AssetBundleIP}/{bundlePath.ToLower()}";

        AssetBundle bundle = null;
        if (loadedAssetBundles.ContainsKey(prefabPath)) {
            yield return null;
            bundle = loadedAssetBundles[prefabPath];
        }
        else {
#if !UNITY_EDITOR
            if (AppConst.useShowBundlePath) { //打需要演示的包时候需要先读取本地的streamAsset,如果存在侧不执行
                    var showBundlePath = Application.streamingAssetsPath + $"/webgl/{bundlePath.ToLower()}";
                    Debug.Log("showBundlePath:"+ showBundlePath);
                    UnityWebRequest showRequest = UnityWebRequestAssetBundle.GetAssetBundle(showBundlePath);
                    yield return showRequest.SendWebRequest();

                    if (showRequest.result == UnityWebRequest.Result.Success) {
                        Debug.Log($"load bundle ok: {showBundlePath}");
                        bundle = DownloadHandlerAssetBundle.GetContent(showRequest);
                    }
                    else {
                        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                        yield return request.SendWebRequest();
                        if (request.result != UnityWebRequest.Result.Success) {
                            Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                            yield break;
                        }
                        Debug.Log($"load bundle ok: {fullBundlepath}");
                        bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }
                }else {
                    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(desPlatform);
                    yield return request.SendWebRequest();
                    if (request.result != UnityWebRequest.Result.Success) {
                        Debug.LogError($"Failed to load asset bundle at path: {desPlatform}");
                        request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                        yield return request.SendWebRequest();
                        if (request.result != UnityWebRequest.Result.Success) {
                            Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                            yield break;
                        }
                        Debug.Log($"load bundle ok: {fullBundlepath}");
                        prefabName = UtilsFunc.GetFileNameWithoutExtension(fullBundlepath) + ".prefab";
                        bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }else{
                        Debug.Log($"load bundle ok: {desPlatform}");
                         prefabName = UtilsFunc.GetFileNameWithoutExtension(desPlatform) + ".prefab";
                        bundle = DownloadHandlerAssetBundle.GetContent(request);
                    }

                }
#else
            UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(desPlatform);
                yield return request.SendWebRequest();
            if (request.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"Failed to load asset bundle at path: {desPlatform}");
                request = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
                yield return request.SendWebRequest();
                if (request.result != UnityWebRequest.Result.Success)
                {
                    Debug.LogError($"Failed to load asset bundle at path: {fullBundlepath}");
                    yield break;
                }
                Debug.Log($"load bundle ok: {fullBundlepath}");
                prefabName = UtilsFunc.GetFileNameWithoutExtension(fullBundlepath) + ".prefab";
                bundle = DownloadHandlerAssetBundle.GetContent(request);
            }
            else {

                Debug.Log($"load bundle ok: {desPlatform}");
                prefabName = UtilsFunc.GetFileNameWithoutExtension(desPlatform) + ".prefab";
                bundle = DownloadHandlerAssetBundle.GetContent(request);
            }
                
#endif
        }

        if (bundle == null) {
            Debug.LogError($"Failed to get asset bundle content at path: {fullBundlepath}");
            yield break;
        }


        loadedAssetBundles.Add(prefabPath, bundle);
    }


    void doCallBack(string prefabPath, UnityEngine.Object asset = null) {

        if (asset == null) {
            m_loadingActions.Remove(prefabPath);
            return;
        }

        m_loadingActions.TryGetValue(prefabPath, out var list);
        if (list != null) {
            foreach (var action in list) {
                GameObject prefab = Instantiate(asset) as GameObject;
                action(prefab);
            }
            m_loadingActions.Remove(prefabPath);
        }
        else {
            Debug.LogError($"doCallBack {prefabPath}");
        }

    }

    public async Task LoadSceneSync(string sceneName) {

        string fullBundlepath = $"{Host.AssetBundleIP}/scenes/{sceneName.ToLower()}.bundle";

        UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(fullBundlepath);
        var asyncOp = await www.SendWebRequest();

        if (asyncOp.result != UnityWebRequest.Result.Success) {

            Debug.LogError(www.error);
        }
        else {
            Debug.Log("LoadSceneSync");
            DownloadHandlerAssetBundle.GetContent(www);
            await SceneManager.LoadSceneAsync(sceneName);

            ResetSceneAllMaterials();
        }

        return asyncOp;

    }

    private void ResetSceneAllMaterials() {
#if UNITY_EDITOR
        var scene = SceneManager.GetActiveScene();
        GameObject[] roots = scene.GetRootGameObjects();
        foreach (GameObject root in roots) {
            var renderers = root.GetComponentsInChildren();
            foreach (var render in renderers) {
                ResetMaterials(render.materials);
            }
        }
        if (RenderSettings.skybox != null)
            RenderSettings.skybox.shader = Shader.Find(RenderSettings.skybox.shader.name);
#endif
    }
    private void ResetMaterials(Material[] materials) {
        foreach (Material m in materials) {
            var shaderName = m.shader.name;
            if (shaderName == "Hidden/InternalErrorShader")
                continue;
            var newShader = Shader.Find(shaderName);
            if (newShader != null) {
                m.shader = newShader;
            }
            else {
                Debug.LogWarning("unable to refresh shader: " + shaderName + " in material " + m.name);
            }
        }
    }

    private  void ResetBundleMaterials(AssetBundle bundle) {

#if UNITY_EDITOR
        var materials = bundle.LoadAllAssets();
        ResetMaterials(materials);
#endif
    }



    void OnDestroy() {
        foreach (var bundle in loadedAssetBundles.Values) {
            bundle.Unload(true);
        }
        loadedAssetBundles.Clear();
    }
}
public static class Host
{
    /// 
    /// 如果StreamAsset CONFIG 里面有配置AssetBundleIP,则使用那边的
    /// 
    public static string AssetBundleIP = Application.dataPath.Replace("Assets", "") + "ABundles/webgl";
    public static string gameServer = "";
    public static string ApiHost = "";
    public static string remote = "";
}

10.新建一个UI预设体:

Unity组件开发--UI管理器_第6张图片

这个界面的业务脚本:WarningPanel

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

public class WarningPanel : BasePanel
{
    static string showText;
    public Text text;
    
    public GameObject confirmBtn;
    public GameObject closeBtn;

    private static Action confirmCallBack;
    private static Action closeCallBack;

    public static void Show(string showText,Action confirmBack,Action closeBack)
    {
        WarningPanel.showText = showText;

        WarningPanel.confirmCallBack = confirmBack;
        WarningPanel.closeCallBack = closeBack;
        UIManager.Instance.PushPanel(UIPanelType.WARNING_PANEL);
    }

    public override void OnEnter()
    {
        base.OnEnter();
        text.text = WarningPanel.showText;
        confirmBtn.GetComponent

你可能感兴趣的:(ui,unity,游戏程序)