不改变按钮大小,扩大点击区域
本期的问题是,如何扩大一个按钮(Button)的点击区域。
比如,将下图的 **TAP TO START**(点击开始游戏)的有效点击区域扩大到红色区域。
遇到这样的需求,你会怎么去寻找方案呢?
每个问题,综合起来,都有这么几个解题思路:
1. 问有经验的人
2. 网上搜是否有类似问题
3. 看手册了解原理,然后自行设计方案
了解我的人,知道我比较喜欢自己琢磨。所以,我一般的思路是
1. 先看手册了解原理,然后尝试设计方案并测试。
2. 如果不行,第二选择是问Google。因为我们遇到的大部分问题,都不是新问题。只要你有一个明确的问题,用对关键字,一般都能找到**同病相怜**的人。
3. 最后,如果手册里讲的不清楚,而网上搜不到类似案例(这时候多半是因为我们用错了搜索关键字),那就去请教有经验的人。
可惜的是,关于如何扩大按钮的点击区域,手册里并没有太多可以参考的……
如果不反编译Unity的代码,那么Unity对于我们就是一个黑盒。不过,对于一个设计合理的黑盒,我们依然可以从它的表现猜测出一些工作原理。
由于Unity是基于组件设计的,任何一个对象,或者说一个具体的功能,都是由一个或者多个组件配合实现的。
关于Button对象,我们可以看到它包含这么几个组件并猜测各自的具体工作:
-
RectTransform 管理位置和尺寸
-
CanvasRenderer 管理具体渲染
-
Image 管理显示内容
-
Button 管理按钮的逻辑
对于我们要解决的问题,最重要的一个点:
**点击区域,由谁来决定。**
边看边猜
-
负责逻辑的Button组件,没有看到任何点击区域相关的信息。
-
负责位置和尺寸的RectTransform,由于有坐标/尺寸/旋转等信息,完全可以计算出可点击区域。
-
负责显示的Image组件,虽然看起来只是用于显示,但是,有个 **Raycast Target** 这个奇怪的选项开关。
大胆测试
-
测试 1.
修改RectTransform的Width和Height,扩大按钮的尺寸,点击区域就变大了。
然而,这带来了负面作用:
Image也被拉伸了。
但是这离我们的目标近了一步,现在,问题转换为:
有没有可能不拉伸图片的同时,改变按钮的尺寸?
可以明确的是,
如果Image组件和Button组件在同一个GameObject里,这是不可能实现的,或者需要很复杂的技巧,比如修改渲染方式(修改shader之类),使Image维持原尺寸渲染。
那么,能否把Image作为子对象呢?
-
测试 2.
1. 从Button对象上,移除Image组件,然后改变按钮尺寸。
简单点,直接勾掉,设为disable就可以了。
2. 添加一个Image的子对象。
3. 为了保持按钮的状态切换效果(点击高亮什么的),需要把子GameObject对象(GameObject的名字叫Image)设置为Button的Target Graphic
测试结果:
还是只有图片区域可以点击……
但是,这不科学,对不对?
**按钮的尺寸明明扩大了,但是并没有生效。**
更过分的是,如果我把子对象去掉,这时候,整个按钮都没法响应点击事件了!
且慢,刚刚我们说Image组件有个奇怪的选项:
**Raycast Target**
莫非,Image组件还负责**控制是否可以响应点击事件**?
-
测试 3.
1. 保留测试2里的图片子对象
2. 保留Button对象里的Image组件,为了不影响显示,把Image的alpha(透明度)设为0
测试结果:
成功!!
点击开始游戏图片外的区域,依然可以正常响应。
总结
于是,我们就得到了这个问题的解决方法:
-
将按钮图片分离出来,作为按钮的子对象,同时把它设置为Button组件的Target Graphic,因为我们需要根据按钮的状态切换不同图片。
-
把Button对象自身的Image组件透明度设为 0(用于响应点击事件)
-
改变Button对象的尺寸。这里要注意子对象的位置,可以将其设为不受父节点的尺寸变化而变化。(这个问题比较简单,留给大家自己试咯)
这是我自己测试出来的一个方案。实际上,如果你去Google,这个问题还有很多别的方案。