Unity3D实现RPG造梦西游(一)游戏基础UI框架

原创 2018年04月17日 21:20:20

大三下学期在培训机构寻找一处能做自己喜欢的地方,在学校每天还要担心点名,被学校女色迷惑

还是培训机构好,班里就三个女生,可以专心学习做游戏

还在学习。。。。有不足之处请指教

-------------------------------进入正题-----------------------------------

造梦西游是4399上挺火的小游戏,前几天玩了一会就发现不充钱就打不过了。。。一时兴起打算做一个

之前学了刘国柱老师的UI框架加上我自己的理解做了一个UI框架正好可以使用

这里附上刘国柱老师的博客 http://www.cnblogs.com/LiuGuozhu/ 受益颇深



基本UI框架的类图就是这样了,已经写了几天,今天才突发奇想或许可以记录一下,以后面试实习也能说我是写过博客的

大体是根据MVC加上我的魔改而成的框架,至少我自己暂时觉得还是思路挺清晰的

Panel的切换是使用的Canvas Group的更改透明度,在加上使用


此方法来更改显示顺序和显隐的

其中的界面反向切换是使用的栈后入先出的特性

反向切换是指一个窗口弹出小窗口后,父窗口的Raycast需要取消,下面贴上核心代码

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

public class UIManager :MonoBehaviour {

    /// <summary>
    /// 单例模式:
    /// 1.定义一个静态的对象 在外界访问 内部构造
    /// 2.构造方法私有化
    /// </summary>
    #region 单例模式

    private static UIManager _instance;

    public static UIManager Instance
    {
        get
        {
            if (_instance == null)
            {
                UIManager[] instances = FindObjectsOfType<UIManager>();
                if (instances != null)
                {
                    _instance = instances[0];
                    for (var i = 1; i < instances.Length; i++)
                    {
                        Destroy(instances[i].gameObject);
                    }
                }
            }
            return _instance;
        }
    }

    #endregion


    private Transform _canvas;
    public Transform Canvas
    {
        get
        {
            if (_canvas == null)
                _canvas = GameObject.Find("Canvas").transform;
            return _canvas;
        }
    }
    //存储所有面板prefab的地址
    private Dictionary<UIPanelType, string> _DicPanelPath;
    //存储所有实例化的面板身上的BasePanel组件
    private Dictionary<UIPanelType, BasePanel> _DicPanel;
    //存储所有显示的面板上的BasePanel组件
    private Dictionary<UIPanelType, BasePanel> _DicShowPanel;
    //表示显示面板的栈
    private Stack<BasePanel> _StackPanel;
    //全屏显示的节点
    private Transform _TraFullScreen = null;
    //固定显示的节点
    private Transform _TraFixed = null;
    //弹出节点
    private Transform _TraPopUp = null;
    ////脚本节点
    //private Transform _TraScript = null;


    private void Awake()
    {
        ParseUIPanelPathJson();
        _StackPanel = new Stack<BasePanel>();
        _DicPanel = new Dictionary<UIPanelType, BasePanel>();
        _DicShowPanel = new Dictionary<UIPanelType, BasePanel>();
        _TraFullScreen = Canvas.Find("FullScreen");
        _TraFixed = Canvas.Find("Fixed");
        _TraPopUp = Canvas.Find("PopUp");
        DontDestroyOnLoad(Canvas.gameObject);
        //_TraScript = Canvas.Find("Script");
    }



    /// <summary>
    /// 把类型为反向切换的窗体入栈
    /// </summary>
    /// <param name="type"></param>
    private void PushPanel(UIPanelType type)
    {
        BasePanel basePanel = GetPanel(type);
        if (_StackPanel.Count >= 1)
        {
            BasePanel topPanel = _StackPanel.Peek();
            topPanel.OnPause();
        }
        _StackPanel.Push(basePanel);
        basePanel.OnEnter();
    }

    /// <summary>
    /// 把类型为反向切换的窗体出栈
    /// </summary>
    /// <param name="type"></param>
    private void PopPanel(UIPanelType type)
    {
        //如果栈里面为空,则返回
        if (_StackPanel.Count <= 0) return;
        BasePanel basePanel = GetPanel(type);
        BasePanel topPanel = _StackPanel.Peek();
        //如果当前要出栈的界面跟栈顶界面相同时 才会出栈
        if(basePanel.gameObject == topPanel.gameObject)
        {
            _StackPanel.Pop();
            topPanel.OnExit();
            //如果出栈后栈里面还有界面则恢复
            if(_StackPanel.Count >= 1)
            {
                _StackPanel.Peek().OnResume();
            }
        }
        else
        {
            Debug.LogError("栈顶界面不是此界面,请检查进出栈!!");
        }
        
    }

    /// <summary>
    /// 显示界面
    /// </summary>
    /// <param name="type"></param>
    public void ShowUIForms(UIPanelType type)
    {
        BasePanel basePanel = GetPanel(type);
        switch (basePanel.uiType.uiFormShowMode)
        {
            case UIFormShowMode.Normal:
                EnterUIFormsCache(type);
                break;
            //如果是反切换类型则入栈
            case UIFormShowMode.ReverseChange:
                PushPanel(type);
                break;
            //如果是隐藏其他的类型,清空显示的界面
            case UIFormShowMode.HideOther:
                HideOtherPanel(type);
                break;
        }
    }

    /// <summary>
    /// 隐藏界面 如果显示界面字典里面存在此界面
    /// </summary>
    /// <param name="type"></param>
    public void HideUIForms(UIPanelType type)
    {
        BasePanel basePanel = GetPanel(type);

        switch (basePanel.uiType.uiFormShowMode)
        {
            case UIFormShowMode.Normal:
                HideUIFormsCache(type);
                break;
            //如果是反切换类型则出栈
            case UIFormShowMode.ReverseChange:
                PopPanel(type);
                break;
            case UIFormShowMode.HideOther:
                HideUIFormsCache(type);
                break;
        }
    }

    /// <summary>
    /// 隐藏除此之外的Panel,如果不赋值则清空所有
    /// </summary>
    /// <param name="type"></param>
    public void HideOtherPanel(UIPanelType type = UIPanelType.Null)
    {
        foreach (KeyValuePair<UIPanelType,BasePanel> item in _DicShowPanel)
        {
            item.Value.OnExit();
        }
        _DicShowPanel.Clear();
        if (type != UIPanelType.Null)
        {
            BasePanel basePanel = GetPanel(type);
            basePanel.OnEnter();
            _DicShowPanel.Add(type, GetPanel(type));
        }
            
    }

    /// <summary>
    /// 将UI加入到已显示面板的字典中
    /// </summary>
    /// <param name="type"></param>
    private void EnterUIFormsCache(UIPanelType type)
    {
        //如果显示面板字典里面有当前面板则返回
        if (_DicShowPanel.ContainsKey(type)) return;
        BasePanel basePanel = GetPanel(type);
        _DicShowPanel.Add(type, basePanel);
        basePanel.OnEnter();
    }

    /// <summary>
    /// 将UI隐藏
    /// </summary>
    /// <param name="type"></param>
    private void HideUIFormsCache(UIPanelType type)
    {
        //如果显示面板字典里面没有当前面板则返回
        if (!_DicShowPanel.ContainsKey(type)) return;
        BasePanel basePanel = GetPanel(type);
        _DicShowPanel.Remove(type);
        basePanel.OnExit();
    }

    /// <summary>
    /// 根据面板类型得到实例化的面板
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType type)
    {
        if (_DicPanel.ContainsKey(type))
        {
            return _DicPanel[type];
        }
        else
        {
            //如果找不到就找这个面板的prefab的路径,然后根据prefab去实例化面板
            BasePanel panel;
            string panelPath = _DicPanelPath.GetValue(type);
            GameObject insGo = GameObject.Instantiate(Resources.Load(panelPath),Canvas) as GameObject;
            insGo.name = type.ToString();
            panel = insGo.GetComponent<BasePanel>();
            switch (panel.uiType.uIFormParentType)
            {
                case UIFormParentType.FUllScreen:
                    insGo.transform.SetParent(_TraFullScreen);
                    break;
                case UIFormParentType.Fixed:
                    insGo.transform.SetParent(_TraFixed);
                    break;
                case UIFormParentType.PopUp:
                    insGo.transform.SetParent(_TraPopUp);
                    break;
            }
            _DicPanel.Add(type, panel);
            return panel;
        }
    }

    #region 解析地址json 并存储到字典中
    
    private void ParseUIPanelPathJson()
    {
        TextAsset text = Resources.Load<TextAsset>("UIPanelType");
        JSONObject jSONObject = new JSONObject(text.text);
        if (_DicPanelPath == null)
            _DicPanelPath = new Dictionary<UIPanelType, string>();
        foreach (JSONObject item in jSONObject.list)
        {
            string panelTypeString = item["panelTypeString"].str;
            string path = item["path"].str;
            UIPanelType uIPanelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
            _DicPanelPath.Add(uIPanelType, path);
        }
    }

    #endregion

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


public class BasePanel : MonoBehaviour {


    protected CanvasGroup cg;
    public UIType uiType;


    private void Awake()
    {
        InitData();
    }


    public virtual void OnCloseBtnClick()
    {
        UIManager.Instance.HideUIForms(uiType.uiPanelType);
    }


    public virtual void InitData()
    {
        if (cg == null)
            cg = this.gameObject.GetAndAddComponent<CanvasGroup>();
        if (uiType == null)
            uiType = new UIType();
    }




    /// <summary>
    /// 界面被显示出来
    /// </summary>
    public virtual void OnEnter()
    {
        cg.alpha = 1;
        cg.blocksRaycasts = true;
        this.gameObject.transform.SetAsLastSibling();
    }


    /// <summary>
    /// 界面暂停 指的是当其他界面在此界面之上,此界面不是主界面的时候,此界面不接受鼠标检测,如果不需要此功能可以适当更改
    /// </summary>
    public virtual void OnPause()
    {
        cg.blocksRaycasts = false;
    }


    /// <summary>
    /// 界面继续
    /// </summary>
    public virtual void OnResume()
    {
        cg.blocksRaycasts = true;
    }


    /// <summary>
    /// 界面不显示,退出这个界面
    /// </summary>
    public virtual void OnExit()
    {
        cg.alpha = 0;
        cg.blocksRaycasts = false;
    }
	
}

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

public class UIType  {

    /// <summary>
    /// panel类别
    /// </summary>
    public UIPanelType uiPanelType;
    /// <summary>
    /// Panel的显示方式,有正常显示,隐藏其他和反向切换
    /// </summary>
    public UIFormShowMode uiFormShowMode = UIFormShowMode.Normal;
    /// <summary>
    /// 这个透明度暂时没用
    /// </summary>
    public UIFormLucencyType uIFormLucencyType = UIFormLucencyType.Lucency;
    /// <summary>
    /// Panel的父物体类型
    /// </summary>
    public UIFormParentType uIFormParentType = UIFormParentType.PopUp;

代码比较多,不过都有贴心的注释


造梦西游辅助源码

  • 2012年04月08日 09:36
  • 11.73MB
  • 下载

ucbug造梦西游5修改器使用方法介绍

《造梦西游5》是由造梦工作室研发,4399小游戏独家发行的一款动作策略类网页游戏,是造梦西游系列的第五个版本。本作讲述了唐僧师徒为拯救上古天庭,与十大妖帅、天帝东皇太一战斗的故事。 ucbug造梦西...
  • ucbugcc
  • ucbugcc
  • 2017-08-08 19:43:49
  • 632

造梦西游3绝版源码

  • 2013年12月29日 15:37
  • 1.67MB
  • 下载

造梦西游3源码

  • 2017年10月13日 07:22
  • 600KB
  • 下载

造梦西游3源码+模板

  • 2013年07月07日 15:55
  • 571KB
  • 下载

造梦西游3修改器源码

  • 2013年05月16日 20:57
  • 9.61MB
  • 下载

造梦西游5幻宇辅助_全网最好用、最强大的辅助

造梦西游5幻宇辅助是为造梦西游5打造的一款辅助,该辅助功能十分强大。并且会持续更新更多的功能,可能为全网最好用的辅助! 说明 造梦西游5幻宇辅助功能强大、界面温馨,简便操作! ...
  • qagag
  • qagag
  • 2017-06-27 15:00:39
  • 1785

造梦西游修改器源码

  • 2014年05月19日 17:07
  • 2.93MB
  • 下载

自己总结的Unity3d RPG网络游戏 UI逻辑 框架(基于NGUI)

屌丝做了两年游戏,总结一下用U3D
  • rong123hao
  • rong123hao
  • 2014-10-31 17:45:28
  • 17310

造梦西游源码

  • 2013年08月16日 16:57
  • 18KB
  • 下载
收藏助手
不良信息举报
您举报文章:Unity3D实现RPG造梦西游(一)游戏基础UI框架
举报原因:
原因补充:

(最多只允许输入30个字)