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个方向的位置的计算
- unity3d基于ugui的ui模块
- 【Unity3D】【UGUI】UI Overview
- [Unity3d]基于UGUI写的Joystick
- Unity3D基于UGUI的虚拟摇杆实现
- Unity3D 基于UGUI的图文混排组件
- 基于Unity3D(UGUI)的背包系统<二>
- 基于Unity3D(UGUI)的背包系统<三>
- 基于Unity3D(UGUI)的背包系统<四>完结篇
- 基于UGUI 的 游戏UI框架的一些想法
- 【Unity3D ugui】UI特效的位置自适应及调整层次关系的一种解决方案
- 【Unity3D】UGUI组件的监听
- 基于Unity3D(UGUI)的背包系统(装备系统,锻造系统,购买系统)
- Unity3d UGUI判断鼠标是否在UI上
- UGUI基于EventTrigger的UI交互事件监听系统&动态加载
- (二十七)unity4.6学习Ugui中文文档-------Unity3D UI (uGUI)窗口扩展
- Unity3d UGUI 控制Image的旋转
- unity3D中UGUI改变字体的颜色
- 【Unity3D ugui】简单控件的事件监听
- 【郑轻】[1775]和尚特烦恼1——是不是素数
- 树莓派(一)安装win10 IoT
- 图像恢复及滤波处理
- Git的简单使用(一)
- 黑马程序员-C语言-构造类型
- unity3d基于ugui的ui模块
- The SetStack Computer(UVa12096&&POJ3121) (集合栈)
- CentOS安装squid代理服务器
- 先安装IIS后,在安装net framewor应用池没有刚安装版本的版本
- 删除首位空格的方法
- Hello World
- 【郑轻】[1776]和尚特烦恼2——第几个素数
- 基于安卓客户端的百度云消息推送实现DEMO
- hdu2553 N皇后问题--DFS