unity3d基于ugui的ui模块

来源:互联网 发布:js 手动触发click事件 编辑:程序博客网 时间:2024/06/05 09:58

对于u3d客户端最好的学习方法就是实践!!
今天终于有时间可以写写博客,这次我写一个基于ugui的ui模块,也可以理解为封装,把ui相关封装起来方便使用。
回到正题!
首先我会用到单例模式,不懂的自行百度。我这里添加一个创建gameobject的单例。

using UnityEngine;using System.Collections;public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>{    protected static readonly T instance = Create();    public static T GetSingleton()    {        return instance;    }    private static T Create()    {        T instance = GameObject.FindObjectOfType<T>();        if (null == instance)        {            instance = new GameObject(typeof(T).Name + "_Singleton").AddComponent<T>();        }        GameObject.DontDestroyOnLoad(instance);        return instance;    }    protected static V AddComponent<V>() where V : MonoBehaviour    {        return instance.gameObject.AddComponent<V>();    }}

1.ui我采用的是ngui那种双摄像机,首先创建一个ui摄像机的单例吧

using UnityEngine;using System.Collections;[RequireComponent(typeof(Camera))]public class UICamera : MonoSingleton<UICamera>{    public Camera UI_Camera { get; set; }    void Awake()    {        UI_Camera = GetComponent<Camera>();        UI_Camera.clearFlags = CameraClearFlags.Depth;        UI_Camera.cullingMask = 1 << LayerMask.NameToLayer("UI");        UI_Camera.orthographic = true;        UI_Camera.orthographicSize = 3.2f;    }}

然后测试一下这个单例
这里写图片描述
测试结果
这里写图片描述

2.基本东西已经准备好了,现在开始书写我们的ui框架
ui基本框架有三个东西
这里写图片描述
UISystem :管理ui,包括创建ui,查找ui,删除ui等等(其他功能可以自己扩展)
UIWidget:处理ui逻辑,注册ui事件(点击,拖拽之类),设置sprite、设置label等等接口(很多功能可以自己扩展,例如:点击音效,ui动画)
IEventListener : 是对EventTrigger进行下一层封装,封装成类似ngui事件监听

看UISystem的代码之前,我要补充一下,RectTransformUtility.CalculateRelativeRectTransformBounds可以计算ui的包围盒,不过他的大小位置是根据屏幕缩放之前的rect。 Canvas获取RectTransform. rect是屏幕缩放过的rect,因为我是按照高度适应,所以根据高度来算出比例来算出屏幕缩放之前rect,根据包围盒和Canvas的rect可以用来判断ui是否超出界面,判断超出有什么用?例如:物品属性面板是跟着物品图标位置改变而改变,如果靠太边,属性面板就会超出屏幕。如果超出会做相应工作把他放在屏幕内,这个代码已经写好,下次放出。
计算缩放前的rect代码如下
这里写图片描述

UISystem代码

using UnityEngine;using System.Collections.Generic;using UnityEngine.EventSystems;using UnityEngine.UI;[RequireComponent(typeof(Canvas))][RequireComponent(typeof(CanvasScaler))][RequireComponent(typeof(GraphicRaycaster))][RequireComponent(typeof(EventSystem))][RequireComponent(typeof(StandaloneInputModule))][RequireComponent(typeof(TouchInputModule))]public sealed class UISystem : MonoSingleton<UISystem>{    public const int WIDTH = 960;    public const int HEIGHT = 640;    public Canvas Canvas { get; set; }    public CanvasScaler CanvasScaler { get; set; }    public Camera UI_Camera { get; set; }    public RectTransform UIRectTranform { get; set; }    public Rect UI_Rect { get; set; }    /// <summary>    /// 存放由uisystem创建的ui    /// </summary>    private Dictionary<string, UIWidget> m_UI_Dic = new Dictionary<string, UIWidget>();    void Awake()    {        this.gameObject.layer = LayerMask.NameToLayer("UI");        this.Canvas = GetComponent<Canvas>();        this.CanvasScaler = GetComponent<CanvasScaler>();        this.UI_Camera = UICamera.GetSingleton().UI_Camera;        this.Canvas.renderMode = RenderMode.ScreenSpaceCamera;        this.Canvas.worldCamera = UI_Camera;        this.CanvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;        this.CanvasScaler.matchWidthOrHeight = 1;        this.CanvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;        this.CanvasScaler.referenceResolution = new Vector2(WIDTH, HEIGHT);        this.UIRectTranform = GetComponent<RectTransform>();        Rect screenRect = UIRectTranform.rect;        float scale = CanvasScaler.matchWidthOrHeight == 1 ? (float)HEIGHT / (float)Screen.height : (float)WIDTH / (float)Screen.width;        UI_Rect = new Rect(screenRect.x * scale, screenRect.y * scale, screenRect.width * scale, screenRect.height * scale);    }    /// <summary>    /// 创建ui控件    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="resourcePath"></param>    /// <param name="visable"></param>    /// <returns></returns>    public T CreateWight<T>(string resourcePath,bool visable = true) where T : UIWidget    {        T panel = null;        if (m_UI_Dic.ContainsKey(resourcePath))        {            panel = GetWidget<T>(resourcePath);            panel.SetVisable(visable);            panel.rectTransform.SetAsLastSibling();            return panel;        }        panel = CreateResource(resourcePath, transform).AddComponent<T>();        panel.SetVisable(visable);        panel.rectTransform.SetAsLastSibling();        panel.rectTransform.sizeDelta = Vector2.zero;        panel.rectTransform.anchoredPosition = Vector3.zero;        panel.transform.localScale = Vector3.one;        m_UI_Dic[resourcePath] = panel;        return panel;    }    /// <summary>    /// 创建一个ui控件    /// </summary>    /// <param name="resoucePath"></param>    /// <param name="parent"></param>    /// <returns></returns>    public GameObject CreateWidget(string resoucePath,Transform parent)    {        GameObject go = CreateResource(resoucePath,parent);        RectTransform rt = go.GetComponent<RectTransform>();        rt.anchoredPosition = Vector2.zero;        rt.localScale = Vector3.one;        return go;    }    /// <summary>    /// 获取ui控件    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="resourcePath"></param>    /// <returns></returns>    public T GetWidget<T>(string resourcePath) where T : UIWidget    {        if (!m_UI_Dic.ContainsKey(resourcePath)) { return null; }        if (null == m_UI_Dic[resourcePath]) { return null; }        return m_UI_Dic[resourcePath] as T;    }    /// <summary>    /// 创建ui的游戏对象    /// </summary>    /// <param name="resourcePath"></param>    /// <param name="parent"></param>    /// <returns></returns>    private GameObject CreateResource(string resourcePath,Transform parent)    {        GameObject resource = Resources.Load(resourcePath) as GameObject;        if (null == resource)        {            throw new System.NullReferenceException(resourcePath);        }        GameObject widget = (GameObject)Instantiate(resource);        widget.name = resourcePath;        widget.transform.parent = parent;        return widget;    }    /// <summary>    /// 删除创建的ui    /// </summary>    /// <param name="resourcePath"></param>    public void DestoryWidget(string resourcePath)    {        if (!m_UI_Dic.ContainsKey(resourcePath)) { return; }        if (null == m_UI_Dic[resourcePath]) { m_UI_Dic.Remove(resourcePath); }        Destroy(m_UI_Dic[resourcePath].gameObject);        m_UI_Dic.Remove(resourcePath);    }}

UIWidget代码,注册事件我添加了一个根据ui名字注册和gameobject注册,其实都是gameobject注册 ,里面只添加了点击事件,其他事件可以自己添加。部分接口隐藏ui,显示ui,设置精灵,设置文字等等接口

using UnityEngine;using System.Collections.Generic;using UnityEngine.UI;using UnityEngine.EventSystems;public class UIWidget : MonoBehaviour{    protected Dictionary<string, GameObject> m_Widgets = new Dictionary<string, GameObject>();    public const string CONTAIN_WORLD = "UI";    /// <summary>    /// 初始化控件    /// </summary>    /// <param name="aryName"></param>    protected void InstallWidgets(string[] aryName)    {        List<RectTransform> trans = new List<RectTransform>(gameObject.GetComponentsInChildren<RectTransform>());        for (int i = 0; i < aryName.Length; i++)        {            for (int j = 0; j < trans.Count; j++)            {                if (trans[j].name == aryName[i])                {                    m_Widgets[aryName[i]] = trans[j].gameObject;                    trans.RemoveAt(j);                    break;                }            }        }    }    /// <summary>    /// 当前面板的rect    /// </summary>    public RectTransform rectTransform    {        get        {            if(null == m_RectTransform)            {                m_RectTransform = GetComponent<RectTransform>();            }            return m_RectTransform;        }    }    private RectTransform m_RectTransform;    /// <summary>    /// 查找ui控件接口    /// </summary>    /// <param name="name"></param>    /// <returns></returns>    public GameObject Find(string name)    {        if (!m_Widgets.ContainsKey(name)) { return null; }        return m_Widgets[name];    }    /// <summary>    /// 通过gameobject注册点击事件    /// </summary>    /// <param name="go"></param>    /// <param name="execute"></param>    public void RegisterClickEvent(GameObject go, UIEventListener.VoidDelegate execute)    {        if (null == go) { return; }        UIEventListener.Get(go).onPointerClick = execute;    }    /// <summary>    /// 通过控件名称注册点击事件    /// </summary>    /// <param name="widget"></param>    /// <param name="execute"></param>    public void RegisterClickEvent(string widget, UIEventListener.VoidDelegate execute)    {        RegisterClickEvent(Find(widget), execute);    }    /// <summary>    /// 设置精灵    /// </summary>    /// <param name="go"></param>    /// <param name="sprite"></param>    public void SetSprite(GameObject go,Sprite sprite)    {        if (null == go) { return; }        Image image = go.GetComponent<Image>();        if (null == image) { return; }        image.sprite = sprite;    }    public void SetSprite(string widget, Sprite sprite)    {        SetSprite(Find(widget), sprite);    }    /// <summary>    /// 设置进度条    /// </summary>    /// <param name="go"></param>    /// <param name="value"></param>    public void SetSlider(GameObject go,float value)    {        if (null == go) { return; }        Slider slider = go.GetComponent<Slider>();        if (null == slider) { return; }        slider.value = value;    }    public void SetSlider(string widget, float value)    {        SetSlider(Find(widget), value);    }    /// <summary>    /// 设置toggle    /// </summary>    /// <param name="go"></param>    /// <param name="enable"></param>    public void SetToggle(GameObject go,bool enable)    {        if (null == go) { return; }        Toggle toggle = go.GetComponent<Toggle>();        if (null == toggle) { return; }        toggle.isOn = enable;    }    public void SetToggle(string widget,bool enable)    {        SetToggle(Find(widget), enable);    }    /// <summary>    /// 设置文字    /// </summary>    /// <param name="go"></param>    /// <param name="content"></param>    public void SetText(GameObject go,string content)    {        if (null == go) { return; }        Text text = go.GetComponent<Text>();        if (null == text) { return; }        text.text = content;    }    public void SetText(string widget,string content)    {        SetText(Find(widget), content);    }    /// <summary>    /// 设置输入文字    /// </summary>    /// <param name="go"></param>    /// <param name="content"></param>    public void SetInputText(GameObject go,string content)    {        if (null == go) { return; }        InputField input = go.GetComponent<InputField>();        if (null == input) { return; }        input.text = content;    }    public void SetInputText(string widget,string content)    {        SetInputText(Find(widget), content);    }    /// <summary>    /// 设置控件颜色    /// </summary>    /// <param name="go"></param>    /// <param name="color"></param>    public void SetColor(GameObject go,Color color)    {        if (null == go) { return; }        Graphic graphic = go.GetComponent<Graphic>();        if (null == graphic) { return; }        graphic.color = color;    }    public void SetColor(string widget,Color color)    {        SetColor(Find(widget), color);    }    /// <summary>    /// 获取进度条的value    /// </summary>    /// <param name="go"></param>    /// <returns></returns>    public float GetSliderValue(GameObject go)    {        if (null == go) { return 0; }        Slider slider = go.GetComponent<Slider>();        if (null == slider) { return 0; }        return slider.value;    }    public float GetSliderValue(string widget)    {        return GetSliderValue(Find(widget));    }    /// <summary>    /// 获取toggle状态    /// </summary>    /// <param name="go"></param>    /// <returns></returns>    public bool GetToggle(GameObject go)    {        if (null == go) { return false; }        Toggle toggle = go.GetComponent<Toggle>();        if (null == toggle) { return false; }        return toggle.isOn;    }    public void GetToggle(string widget)    {        GetToggle(Find(widget));    }    /// <summary>    /// 获取输入框的文字    /// </summary>    /// <param name="go"></param>    /// <returns></returns>    public string GetInputText(GameObject go)    {        if (null == go) { return string.Empty; }        InputField input = go.GetComponent<InputField>();        if (null == input) { return string.Empty; }        return input.text;    }    public string GetInputText(string widget)    {        return GetInputText(Find(widget));    }    /// <summary>    /// 显示控件    /// </summary>    /// <param name="name"></param>    protected void Show(string name)    {        GameObject go = Find(name);        if (null == go) { return; }        go.SetActive(true);    }    /// <summary>    /// 隐藏控件    /// </summary>    /// <param name="name"></param>    protected void Hide(string name)    {        GameObject go = Find(name);        if (null == go) { return; }        go.SetActive(false);    }    public void SetVisable(bool visable)    {        gameObject.SetActive(visable);    }}

UIEventListener 代码
这个不多说看过用过ngui的都知道。我只是继承EventTrigger,然后重写方法而已

using UnityEngine;using System.Collections;using UnityEngine.EventSystems;public class UIEventListener : EventTrigger{    public delegate void VoidDelegate(GameObject go, BaseEventData eventData);    public VoidDelegate onBeginDrag;    public VoidDelegate onCancel;    public VoidDelegate onDeSelect;    public VoidDelegate onDrag;    public VoidDelegate onDrop;    public VoidDelegate onEndDrag;    public VoidDelegate onInitializePotentialDrag;    public VoidDelegate onMove;    public VoidDelegate onPointerClick;    public VoidDelegate onPointerDown;    public VoidDelegate onPointerEnter;    public VoidDelegate onPointerExit;    public VoidDelegate onPointerUp;    public VoidDelegate onScroll;    public VoidDelegate onSelect;    public VoidDelegate onSubmit;    public VoidDelegate onUpdateSelect;    public override void OnBeginDrag(PointerEventData eventData)    {        if(null != onBeginDrag) { onBeginDrag(gameObject, eventData); }    }    public override void OnCancel(BaseEventData eventData)    {        if (null != onCancel) { onCancel(gameObject, eventData); }    }    public override void OnDeselect(BaseEventData eventData)    {        if (null != onDeSelect) { onDeSelect(gameObject, eventData); }    }    public override void OnDrag(PointerEventData eventData)    {        if (null != onDrag) { onDrag(gameObject, eventData); }    }    public override void OnDrop(PointerEventData eventData)    {        if (null != onDrop) { onDrop(gameObject, eventData); }    }    public override void OnEndDrag(PointerEventData eventData)    {        if (null != onEndDrag) { onEndDrag(gameObject, eventData); }    }    public override void OnInitializePotentialDrag(PointerEventData eventData)    {        if (null != onInitializePotentialDrag) { onInitializePotentialDrag(gameObject, eventData); }    }    public override void OnMove(AxisEventData eventData)    {        if (null != onMove) { onMove(gameObject, eventData); }    }    public override void OnPointerClick(PointerEventData eventData)    {        if (null != onPointerClick) { onPointerClick(gameObject, eventData); }    }    public override void OnPointerDown(PointerEventData eventData)    {        if (null != onPointerDown) { onPointerDown(gameObject, eventData); }    }    public override void OnPointerEnter(PointerEventData eventData)    {        if (null != onPointerEnter) { onPointerEnter(gameObject, eventData); }    }    public override void OnPointerExit(PointerEventData eventData)    {        if (null != onPointerExit) { onPointerExit(gameObject, eventData); }    }    public override void OnPointerUp(PointerEventData eventData)    {        if (null != onPointerUp) { onPointerUp(gameObject, eventData); }    }    public override void OnScroll(PointerEventData eventData)    {        if (null != onScroll) { onScroll(gameObject, eventData); }    }    public override void OnSelect(BaseEventData eventData)    {        if (null != onSelect) { onSelect(gameObject, eventData); }    }    public override void OnSubmit(BaseEventData eventData)    {        if (null != onSubmit) { onSubmit(gameObject, eventData); }    }    public override void OnUpdateSelected(BaseEventData eventData)    {        if (null != onUpdateSelect) { onUpdateSelect(gameObject, eventData); }    }    static public UIEventListener Get(GameObject go)    {        UIEventListener listener = go.GetComponent<UIEventListener>();        if (listener == null) listener = go.AddComponent<UIEventListener>();        return listener;    }}

现在测试一下这个ui模块
首先添加一个ui预设先
这里写图片描述
然后预设路径放在
这里写图片描述
ui对应的脚本UITest
这里写图片描述
添加测试代码
这里写图片描述
运行效果,点击按钮就有打印
这里写图片描述
下期会放出ui超出屏幕的处理以及把ui位置设定在某个ui的8个方向的位置的计算

0 0
原创粉丝点击