CG游麟网官方站
查看: 2645|回复: 22

[首发]组件化思想及简单自制工具组件分享

[复制链接]

1

主题

11

帖子

42

积分

初入江湖

Rank: 1

麒麟币
31
任务币
15
威望
0
贡献
0
主题
1
在线时间
1 小时
发表于 2020-5-29 09:42:20 | 显示全部楼层 |阅读模式
本帖最后由 洛神同学 于 2020-5-29 09:43 编辑

1.为什么要有组件化思想:        楼主认为,组件就是能够满足一定功能的能够挂在到对象上面的控件,就比如unity自己封装的Transform组件、Renderer组件等,其实都是满足了一定功能的,而且组件与组件之间的联系很低,这也就是所谓的“高内聚,低耦合”。
2.如何实现组件化:
        想要实现组件化,首先你要明确自己要做怎么的组件,它能够满足什么功能,它里面需要包含哪些数据等,当你清楚了,你就可以开始去写,写的过程中也可能需要写多个类来控制,但是要遵守一点,那就是你挂载到对象上的脚本只能是一个,就比如Transform组件中包含Vector3的类,却不需要挂载一样的道理;
        想要写好一个组件,那就需要充分的了解这个组件的所有可能性,以下面我自己写的一个UI工具组件为例:
我的需求是:
1、点击按钮保持选中状态图标,
2、选中状态文字会改变颜色,可以保持,
3、高亮状态,文字颜色改变,
4、点击完毕能够保持状态或不保持状态。
制作这个组件需要考虑:
1、Img加文本式btn
2、RawImg加文本式btn
3、仅Text式Btn
4、仅Img式Btn
5、仅RawImg式Btn
        常见的Btn也就这几种了,还有一些其他比较特殊的Btn类型,反正笔者从未用过,所以不在考虑范围内,也不作为组件考虑范围内,毕竟组件也是够用就行,太过复杂就会使得脚本过于臃肿,反而影响效率。
        好了,废话不多说,开始上代码

  • using System.Collections;
  • using System.Collections.Generic;
  • using UnityEngine;
  • using UnityEngine.UI;
  • using UnityEngine.EventSystems;
  • [ExecuteInEditMode]
  • [RequireComponent(typeof(Button))]
  • public class UIButtonState : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler , IPointerUpHandler {
  •     [Header("选中状态的图片")]
  •     public Sprite selectSprite;
  •     [Header("是否保持选中状态")]
  •     public bool isKeepSelect = true;
  •     [Header("高亮颜色")]
  •     public Color hightLightColor = new Color(0,0,0,1);
  •     [Header("点击颜色")]
  •     public Color pressColor = new Color(0, 0, 0, 1);
  •     [Header("需要改变颜色的文本")]
  •     public Text text;
  •     private Button m_Btn;
  •     private Color m_oldColor;
  •     private Color m_curColor;
  •     private Image m_Img;
  •     private RawImage m_RawImg;
  •     private Texture m_NomalRawImg;
  •     void Awake () {
  •         m_Btn = GetComponent<Button>();
  •         m_Img = m_Btn.GetComponent<Image>();
  •         m_RawImg = m_Btn.GetComponent<RawImage>();
  •         if (text == null) text = m_Btn.GetComponentInChildren<Text>();
  •         if (text) { m_oldColor = text.color; m_curColor = m_oldColor; }
  •         if (m_Img)
  •         {
  •             if (selectSprite == null) selectSprite = m_Btn.spriteState.pressedSprite;
  •             m_Btn.spriteState = new SpriteState() {  highlightedSprite = m_Btn.spriteState.highlightedSprite, pressedSprite = m_Btn.spriteState.pressedSprite, disabledSprite = m_Img.sprite};
  •         }
  •         else if (m_RawImg)
  •         {
  •             if (selectSprite == null) selectSprite = m_Btn.spriteState.pressedSprite;
  •             m_NomalRawImg = m_RawImg.texture;
  •         }
  •     }
  •     public void Select()
  •     {
  •         CancelAll();
  •         m_Btn.enabled = false;
  •         if (m_Img)
  •             m_Img.sprite = selectSprite;
  •         else if (m_RawImg)
  •             m_RawImg.texture = selectSprite.texture;
  •         if (text) text.color = pressColor;
  •         UnityEngine.EventSystems.EventSystem.current.SetSelectedGameObject(null);
  •     }
  •     void CancelAll()
  •     {
  •         UIButtonState[] uIButtonStates = m_Btn.transform.parent.GetComponentsInChildren<UIButtonState>(true);
  •         for (int i = 0; i < uIButtonStates.Length; i++)
  •         {
  •             uIButtonStates.CancelSelect();
  •         }
  •     }
  •     public void CancelSelect()
  •     {
  •         m_Btn.enabled = true;
  •         if (m_Img)
  •             m_Img.sprite = m_Btn.spriteState.disabledSprite;
  •         else if (m_RawImg)
  •             m_RawImg.texture = m_NomalRawImg;
  •         if (text)
  •         {
  •             text.color = m_oldColor;
  •             m_curColor = m_oldColor;
  •         }
  •     }
  •     public void OnPointerEnter(PointerEventData eventData)
  •     {
  •             if (text && m_Btn.enabled)
  •                 text.color = hightLightColor;
  •     }
  •     public void OnPointerExit(PointerEventData eventData)
  •     {
  •             if (text && m_Btn.enabled)
  •                 text.color = m_curColor;
  •     }
  •     public void OnPointerUp(PointerEventData eventData)
  •     {
  •         if (!isKeepSelect)
  •         {
  •             CancelSelect();
  •         }
  •     }
  •     public void OnPointerDown(PointerEventData eventData)
  •     {
  •         Select();
  •     }
  • }


[color=rgb(106, 205, 243) !important]复制代码




代码其实是比较简单的,就是定义好变量,初始化阶段通过拖拽好的3类型Btn图标,将第四种图标设置为nomalSprite,然后选中时,改变图标为选中图标,并释放UI选中(此部不可省略,原因是你选中时,对其失活后,UGUI内部仍处于悬浮状态,此时改变图标后可能会与此冲突,而显示悬浮图标),取消选中时,更改为第四种状态的Btn图标,这就是楼主的思路了,相对来说脚本的实现是相当简单了,就这样轻松的满足了需求。
      考虑其组件化的意义,本来我的按钮事件完全可以以用自己模拟NGUI封装的监听脚本,通过UIListener.Get的方式来注册,但是毕竟是要当做一个组件来用的,就必须要减少与其他脚本的关联,所以就改为了UGUI自带的那么那么长的接口,虽然我也是非常的不愿意,但是没有办法,毕竟代码优化重要,其中还有好几点是可以优化的地方,但是楼主也是比较懒的人,就懒得再优化了,喜欢的可以优化一下。



        如果有更好的意见,欢迎在在下方回复栏里留言,让我们一起学习,一起进步。

楼主热帖
回复

使用道具 举报

0

主题

5508

帖子

5720

积分

誉满一方

Rank: 8Rank: 8

麒麟币
83
任务币
0
威望
0
贡献
0
主题
0
在线时间
0 小时

最佳新人

发表于 2020-5-29 10:40:31 | 显示全部楼层
真是 收益 匪浅
回复 支持 反对

使用道具 举报

0

主题

5503

帖子

6048

积分

四方传颂

Rank: 9Rank: 9Rank: 9

麒麟币
418
任务币
0
威望
0
贡献
0
主题
0
在线时间
0 小时
发表于 2020-5-29 10:50:32 | 显示全部楼层
找了很久终于找到你了!寡人死而无憾!
回复 支持 反对

使用道具 举报

960

主题

6217

帖子

73万

积分

天外飞仙

Rank: 16Rank: 16Rank: 16Rank: 16

麒麟币
726278
任务币
0
威望
3
贡献
382
主题
960
在线时间
203 小时

最佳新人忠实会员

发表于 2020-5-29 11:40:40 | 显示全部楼层
小手一抖,积分到手!
回复 支持 反对

使用道具 举报

75

主题

5594

帖子

7208

积分

四方传颂

Rank: 9Rank: 9Rank: 9

麒麟币
1589
任务币
0
威望
0
贡献
0
主题
75
在线时间
27 小时

论坛元老超级版主最佳新人优秀版主突出贡献

发表于 2020-5-29 11:50:41 | 显示全部楼层
过来看看的
回复 支持 反对

使用道具 举报

40

主题

5601

帖子

5722

积分

誉满一方

Rank: 8Rank: 8

麒麟币
116
任务币
0
威望
0
贡献
0
主题
40
在线时间
20 小时
发表于 2020-5-29 12:10:44 | 显示全部楼层
帮帮顶顶!!
回复 支持 反对

使用道具 举报

0

主题

5560

帖子

6121

积分

四方传颂

Rank: 9Rank: 9Rank: 9

麒麟币
447
任务币
0
威望
0
贡献
0
主题
0
在线时间
0 小时

最佳新人

发表于 2020-5-29 14:01:00 | 显示全部楼层
太棒了,我喜欢
回复 支持 反对

使用道具 举报

91

主题

5493

帖子

6794

积分

版主

Rank: 7Rank: 7Rank: 7

麒麟币
1186
任务币
0
威望
0
贡献
0
主题
91
在线时间
13 小时
发表于 2020-5-29 15:01:12 | 显示全部楼层
找了很久终于找到你了!寡人死而无憾!
回复 支持 反对

使用道具 举报

0

主题

5200

帖子

7943

积分

四方传颂

Rank: 9Rank: 9Rank: 9

麒麟币
2627
任务币
0
威望
0
贡献
0
主题
0
在线时间
1 小时
发表于 2020-5-29 21:32:25 | 显示全部楼层
不错不错,很好哦
回复 支持 反对

使用道具 举报

47

主题

5561

帖子

7356

积分

四方传颂

Rank: 9Rank: 9Rank: 9

麒麟币
1725
任务币
0
威望
0
贡献
0
主题
47
在线时间
7 小时
发表于 2020-5-30 08:00:00 | 显示全部楼层
过来看看的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

在线客服
客服QQ:
47413829
新QQ群:
418757022
在线时间:周一至周五
9:00-22:00 Email:
47413829@qq.com
举报:网盘资源失效
在线客服
快速回复 返回顶部 返回列表