unity游戏开发之NGUI的UISprite染色
游戏的UI开发中常常会遇到染色问题。比如button失效变灰的效果,同一个道具通过策划表配的颜色值染上红绿蓝紫等颜色,效果例如以下
最笨最挫的方法当然是让美术多出几个资源图。这种一个缺点是浪费资源,在手游上资源的大小显得尤为重要。并且不好维护和复用。改动一个资源须要同一时候改动其它颜色的多个同类资源。一种比較好的解决方式是通过更换渲染的材质,用染色材质取代原来的材质。然后把原来材质的主纹理和透明纹理赋值给新的材质。这样就能够实现用程序动态切换颜色。并且仅仅须要一个基础资源。节省资源大小。easy维护。
以下给出这个解决方式的流程图。例如以下图所看到的
以下写一个样例,通过按r键,g键。b键。y键来动态切换染红色,染绿色。染蓝色,灰化效果。项目的GameObject图例如以下
染色普通颜色的材质相应的shader例如以下
- Shader "Winter/ChangeColor" {
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
- _Color ("Main Color", Color) = (1,1,1,1)
- }
- SubShader {
- Tags { "Queue" = "Transparent+10" }
- LOD 200
- Pass
- {
- ZWrite On
- ZTest Off
- Blend SrcAlpha OneMinusSrcAlpha
- Lighting Off
- //Cull Off
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- sampler2D _MainTex;
- fixed4 _Color;
- float _ColorCtrl;
- struct v2f
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- };
- float4 _MainTex_ST;
- v2f vert (appdata_base v)
- {
- v2f o;
- o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
- o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
- return o;
- }
- fixed4 frag (v2f i) : COLOR
- {
- fixed4 texcol = tex2D (_MainTex, i.uv);
- result = texcol * _Color;
- result.a = texcol.a;
- return result;
- }
- ENDCG
- }
- }
- }
不同颜色要创建不同的材质,而且设置其颜色值,例如以下
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXdpbnRlcmljZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" style="border:none; max-width:100%">
灰化效果比較特殊,颜色值不能弄成(0,0,0,1)或者(1,1,1,1)。
须要用到灰化函数
终于颜色的r = (原图r+原图g+原图b)*0.33
终于颜色的g = (原图r+原图g+原图b)*0.33
终于颜色的b = (原图r+原图g+原图b)*0.33
终于颜色的透明值 = 原图的透明值
依据上面。有以下的灰化shader
- Shader "Winter/Gray"
- {
- Properties
- {
- _MainTex ("Base (RGB)", 2D) = "white" { }
- }
- SubShader
- {
- Tags
- {
- "Queue" = "Transparent+10"
- }
- Pass
- {
- Lighting Off
- ZTest Off
- Cull Off
- Blend SrcAlpha OneMinusSrcAlpha
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- sampler2D _MainTex;
- sampler2D _AlphaTex;
- half4 _Color;
- struct v2f
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- };
- half4 _MainTex_ST;
- half4 _AlphaTex_ST;
- v2f vert (appdata_base v)
- {
- v2f o;
- o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
- o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
- return o;
- }
- half4 frag (v2f i) : COLOR
- {
- half4 texcol = tex2D (_MainTex, i.uv);
- half4 result = half4((texcol.r + texcol.g + texcol.b) * 0.33f,(texcol.r + texcol.g + texcol.b) * 0.33f,(texcol.r + texcol.g + texcol.b) * 0.33f,texcol.a);
- return result;
- }
- ENDCG
- }
- }
- }
接着就是要改动Ngui的UISprite源代码。加入一个渲染的材质WinterMaterial, 在读取material值的时候。假设有自己定义的渲染材质,则须要读取自己定义渲染材质
- public override Material material
- {
- get
- {
- Material mat = base.material;
- if (mat == null)
- {
- mat = (mAtlas != null) ?
mAtlas.spriteMaterial : null;
- mSprite = null;
- material = mat;
- if (mat != null) UpdateUVs(true);
- }
- if (WinterMaterial!=null)
- {
- return WinterMaterial;
- }
- else
- {
- return mat;
- }
- }
- }
然后。加入下面几个染色函数
- public void ShowAsRed()
- {
- ShowAsColor("file:///D:/u3dAB/WinterRedMat.assetbundle", WinterRedMat);
- }
- public void ShowAsGreen()
- {
- ShowAsColor("file:///D:/u3dAB/WinterGreenMat.assetbundle", WinterGreenMat);
- }
- public void ShowAsBlue()
- {
- ShowAsColor("file:///D:/u3dAB/WinterBlueMat.assetbundle", WinterBlueMat);
- }//须要加入染色值的,则须要加入材质和染色函数
- public void ShowAsGray()
- {
- StartCoroutine(<span style="font-family: Arial, Helvetica, sans-serif;">//自己定义的www函数</span>
- IzUtils.LoadAB("file:///D:/u3dAB/WinterGrayMat.assetbundle", (w) =>
- {//assetbundle是打包好的材质
- Material mat = w.assetBundle.mainAsset as Material;
- mat.mainTexture = material.mainTexture;
- WinterMaterial = mat;
- w.assetBundle.Unload(false);
- RefreshPanel(gameObject);
- })
- );
- }
- private void ShowAsColor(string matName, Material colorMaterial)
- {
- if (WinterMaterial == null || colorMaterial != WinterMaterial)
- {
- if (colorMaterial == null)
- {
- StartCoroutine(
- IzUtils.LoadAB(matName, (w) =>
- {
- Material mat = w.assetBundle.mainAsset as Material;
- mat.mainTexture = material.mainTexture;
- colorMaterial = mat;
- WinterMaterial = mat;
- w.assetBundle.Unload(false);
- RefreshPanel(gameObject);
- })
- );
- }
- else
- {
- WinterMaterial = colorMaterial;
- RefreshPanel(gameObject);
- }
- }
- }
- GameObject GetMostClosePanel(Transform rootTrans)
- {
- if (rootTrans.GetComponent<UIPanel>() != null)
- {
- return rootTrans.gameObject;
- }
- else if (rootTrans.parent == null)
- {
- return null;
- }
- else
- {
- return GetMostClosePanel(rootTrans.parent);
- }
- }
- GameObject panelObj = null;
- public bool selfRefresh = true;
- void RefreshPanel(GameObject go)
- {
- if (!selfRefresh)
- return;
- if (panelObj == null)
- {
- panelObj = GetMostClosePanel(go.transform);
- }
- if (panelObj != null)
- {
- panelObj.GetComponent<UIPanel>().enabled = false;
- panelObj.GetComponent<UIPanel>().enabled = true;
- go.SetActive(false);
- go.SetActive(true);
- }
- }
主程序调用方法
- using UnityEngine;
- using System.Collections;
- public class ChangeColorExample : MonoBehaviour {
- private UISprite m_kSprite;
- void Start ()
- {
- GameObject obj = GameObject.Find("Root/Camera/Anchor/Panel/Sprite");
- m_kSprite = obj.GetComponent<UISprite>();
- void Update()
- {
- if (Input.GetKeyUp(KeyCode.R))
- {
- m_kSprite.ShowAsRed();
- }
- else if (Input.GetKeyUp(KeyCode.G))
- {
- m_kSprite.ShowAsGreen();
- }
- else if (Input.GetKeyUp(KeyCode.B))
- {
- m_kSprite.ShowAsBlue();
- }
- else if (Input.GetKeyUp(KeyCode.Y))
- {
- m_kSprite.ShowAsGray();
- }
- }
核心的代码部分如上图所看到的,这样就能够通过按键rgby来切换染红绿蓝灰的效果。
效果如上面第一幅图所看到的。
总结,用程序来实现动态染色能够高度复用资源,节省空间大小。
可是资源的划分须要注意的一点是,假设在一个UIPanel里面有两个不同图集须要用同一个材质进行染色,那么会出现当中的一个出现纹理错乱的现象。眼下的解决方式是做多一个颜色值同样的材质。不同的图集用不同的染色材质,这样能够解决上面说的纹理错乱现象。
还有一个方法是设法把不同的图集弄到一块。这样也能够避免这个问题。
unity游戏开发之NGUI的UISprite染色的更多相关文章
- Unity游戏开发之“屏幕截图”
原地址:http://sygame.lofter.com/post/117105_791680 在unity游戏开发中,可能会遇到在游戏中截屏的效果.这儿提供两种截屏方法.(方法二提供显示截图缩略图代 ...
- Unity游戏开发之C#快速入门
C#是微软团队在开发.NET框架时开发的,它的构想接近于C.C++,也和JAVA十分相似,有许多强大的编程功能. 个人感受是C#吸收了众多编程语言的优点,从中可以看到C.C++.Java.Javasc ...
- unity游戏开发之entitas框架
框架介绍 entitas是一个超快.超轻量的c# Entity-Component-System (ECS)框架,专门为Unity引擎设计.提供内部缓存和高速的组件访问,经过精心设计,可以在垃圾收集环 ...
- Unity游戏开发之“分层碰撞”
有没有同学遇到过这样的情况:在游戏开发3D游戏中非经常见,比方让一个物体能穿过一个物体 而还有一个物体不能穿过这个物体,并且3个物体都不能穿过地面.在unity中这样的情况的处理是通过分层碰撞来解决的 ...
- [整理]Unity3D游戏开发之Lua
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读
---------------------------------------------------------------------------------------------------- ...
- [Unity3D]Unity3D游戏开发之从Unity3D到Eclipse
---------------------------------------------------------------------------------------------------- ...
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)
---------------------------------------------------------------------------------------------------- ...
- Cocos2d-x 3.x游戏开发之旅
Cocos2d-x 3.x游戏开发之旅 钟迪龙 著 ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x ...
随机推荐
- go并发编程 WaitGroup, Mutex
1.背景 记录一下,方便后续写代码直接使用. 需要注意几点: chan 默认支持多协程工作,不需要加锁. 其他变量操作需要使用锁保护(map多协程并发写会panic, 并且无法捕获). 启动gorou ...
- nodejs 中使用 mysql 实现 crud
首先要使用 mysql 就必须要安装 npm install mysql 然后封装 sql 函数 const mySql = require('mysql'); let connection ; le ...
- (转)用JS实现表格中隔行显示不同颜色
用JS实现表格中隔行显示不同颜色 第一种: <style> tr{bgColor:expression( this.bgColor=((this.rowIndex)%2==0 )? ...
- hibernate_07_单表操作_增删改操作
首先,创建类对象 package com.imooc.hibernate; public class Address { private String postcode; //邮编 private S ...
- 蘑菇街TeamTalk应用安卓源码
该源码是蘑菇街TeamTalk应用源码,该产品目标用户为中小型企业用户,支持单聊和群聊,提供文字.表情和图片的富文本实时聊天功能 详细说明:http://android.662p.com/thread ...
- jQuery中容易让人困惑的东西
前言:jqueryt很灵活,太灵活了,可以说是他一个优点,也是他一个缺点,达到一种效果,十个人也许会用十种不同的方法来实现这个过程,结果一样,过程不一样,这到底是好,还是坏呢. 一,什么是jquery ...
- js 立即调用函数
function makeCounter() { //不能立即执行 // 只能在makeCounter内部访问i var i = 0; return function () { console.log ...
- 团体程序设计天梯赛-练习集-L1-047. 装睡
L1-047. 装睡 你永远叫不醒一个装睡的人 —— 但是通过分析一个人的呼吸频率和脉搏,你可以发现谁在装睡!医生告诉我们,正常人睡眠时的呼吸频率是每分钟15-20次,脉搏是每分钟50-70次.下面给 ...
- 团体程序设计天梯赛-练习集-L1-034. 点赞
L1-034. 点赞 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持 ...
- matlab学习滚动条改变文本数值
如下分别添加滚动条,静态文本框和可编辑文本框,字体大小改为10,string值按下图,并使用对齐工具 保存名为GUI_02,会自动出来一个.m文件 注意代码一个字都不要错 %定义变量var,保存滚动条 ...