NGUI里没有变亮的效果

11 篇文章 0 订阅
NGUI里没有变亮的效果,通过着色只会变暗,那么怎么办呢,变亮的效果不仅可以用在按钮上,还可以用于某些控件的闪光等等。下面,我们开始征程吧!

第〇种办法,用UIImageButton。好吧,太弱智了,当我没说。Image Button不知道大家用的多不多,反正我是不用的,毕竟多了一到两倍的图量。用Image Button嘛,就无所谓是变亮还是怎么了,按下后图都不一样了,那想怎么变就怎么变。

第一种办法,还是用UIButton(或者UIButtonColor),将按钮原本就做的亮一些,也就是做一个按下状态的按钮,按钮的静息状态着上色变暗,这样的效果就是静息状态略暗,按下后恢复图片原本的亮状态。为了方便创建,要更改一下各颜色的默认值,在UICreateWidgetWizard.cs里修改源代码即可,具体将会在第二种办法里学会。

美术说,按钮绝大部分时间是静息状态,他们无法直接制作静息状态的图片,会使最终效果难以把握,所以又有了另一种办法。

第二种办法,修改Shader!

我们知道,控件(UIWidget)的着色是用一个颜色值“按分量乘”上原有的贴图颜色,颜色值Color是一个每个分量都在0~1范围的四维向量,那么乘上一个0~1的数必然不会变大,所以着色只能变暗。那么要如何变亮呢?只需在乘上颜色值之后再乘一个2,就可以变亮到两倍了。

这种方法需要修改Shader。找到通常使用的Unlit/Transparent Colored无光照透明着色Shader,Ctrl+D复制一份,名字改为Unlit/Transparent Colored Double,暂时就这么起名吧。双击打开。第一行是名称,也是在unity中选择Shader下拉菜单里的位置,所以改成:
[C#]  纯文本查看  复制代码
?
1
Shader "Unlit/Transparent Colored Double"

再找到最后的SetTexture [_MainTex]方法,加一个DOUBLE:
[C#]  纯文本查看  复制代码
?
1
2
3
4
SetTexture [_MainTex]
{
     Combine Texture * Primary DOUBLE
}

保存。
下面是使用这个Shader。
在Project里找到你的UIAtlas的Prefab物体,同时也可找到它对应的Material和Texture2D。选中Material,将Shader改为刚做的Double Shader,这时场景里所有用到这个Atlas的控件全都亮瞎了狗眼。

接下来就要改变默认状态的着色了,也就是UIWidget.color通通改为new Color(0.5f,0.5f,0.5f,1)(Color.white*0.5f会使alpha变为0.5,影响不大但不太好)。
对于已经制作好的控件,可以手改,当然应该写脚本批量改。对于新制作的控件,我们改一下Wizard和默认值。
先做后者。找到UICreateWidgetWizard类,其中定义了一连串的局部静态变量(m为前缀的),有一个static Color mColor = Color.white;改成:
[C#]  纯文本查看  复制代码
?
1
static Color mColor = new Color(0.5f, 0.5f, 0.5f, 1); //use Double Shader.
在UIButtonColor类里修改默认效果:
[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
///
/// Color to apply on hover event (mouse only).
///
  
public Color hover = new Color(0.75f, 0.75f, 0.75f, 1f);
  
///
/// Color to apply on the pressed event.
///
  
     public Color pressed = new Color(1f, 1f, 1f, 1f);

UIWidget类,修改默认颜色:
[C#]  纯文本查看  复制代码
?
1
[HideInInspector][SerializeField] Color mColor = new Color(0.5f, 0.5f, 0.5f, 1); //use Double Shader.


这样基本上OK了。
再来改工程里已有的控件。写一个如下的EditorWindow:
[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using UnityEngine;
using UnityEditor;
using System.Linq;
  
public class BatchWidgetOperator : EditorWindow
{
     [MenuItem( "Window/Batch Widget Operator" )]
     private static void Init()
     {
         var window = (BatchWidgetOperator) GetWindow( typeof (BatchWidgetOperator));
         window.title = "控件批量修改器" ;
     }
  
     private void OnGUI()
     {
         _operatePath = EditorGUILayout.TextField( "Path(e.g. Assets/Resouces/)" , _operatePath ?? "" );
         if (GUILayout.Button( "Edit All Widgets in the Folder" ))
         {
             EditAllWidgetInAssets();
         }
     }
  
     private static string _operatePath = "Assets/Resources/" ;
  
     private static void EditAllWidgetInAssets()
     {
         var allResourceAssetPaths = AssetDatabase.GetAllAssetPaths().Where(x => x.StartsWith(_operatePath)); //滤出所需路径下的
  
         var n = 0; //计数器
         foreach (var resAssPath in allResourceAssetPaths)
         {
             var prefab = AssetDatabase.LoadMainAssetAtPath(resAssPath) as GameObject;
             if (!prefab) continue ;
             var sprites = prefab.GetComponentsInChildren( true ); //遍历所有UISprite,UISlicedSprite、UIFilledSprite等等都是UISprite的派生类,所以都在里面
             foreach (var sprite in sprites)
             {
                 var color = sprite.color*0.5f;
                 if (color.a > 0.499f) color.a = 1; //原本不透明的依然不透明
                 sprite.color = color;
                 n++;
             }
             EditorUtility.SetDirty(prefab); //漏了就无法写到硬盘上
         }
         Debug.Log( string .Format( "{0} UISpirtes edited!" , n));
         AssetDatabase.SaveAssets();
         EditorApplication.SaveAssets();
         AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
     }
}

保存脚本回到Unity,菜单栏的Window>Batch Widget Operator打开这个修改器,可以修改路径,注意Project里的东西都在Assets/下,点击那个按钮,一会儿工夫会log出修改了多少个Sprites,此时工程里所有的UISprite及其派生类就都被修改好了,当然有些会改错,所以还得每个界面测试一下以防万一。
另外,如果用了Asset Server的话自然可以在Asset Server上备份。这个脚本的操作可以看出来是不可逆,不可重复的,所以,不敢用就先备份吧。
对于场景里的,可以用Selection.gameObjects,即选中的物体,来遍历所有UISprite,详见Unity文档。我不贴出来是因为我没有在场景里直接放置任何控件,以后我会长文说明为什么场景里不要放东西,什么是Unity下的MVC。

以后我工作中遇到的东西都发表出来给大家共享咯!

效果图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值