位置: 编程技术 - 正文

unity游戏开发之NGUI的UISprite染色(unity游戏开发入门经典)

编辑:rootadmin

推荐整理分享unity游戏开发之NGUI的UISprite染色(unity游戏开发入门经典),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:unity游戏开发流程,unity程序开发,unity 开发游戏,unity游戏项目开发教程,unity开发的小游戏,unity游戏开发技术详解与典型案例,unity游戏开发技术详解与典型案例,unity游戏项目开发教程,内容如对您有帮助,希望把文章链接给更多的朋友!

欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d培训、学习第一品牌。

游戏的UI开发中经常会遇到染色问题。例如按钮失效变灰的效果,同一个道具通过策划表配的颜色&#;染上红绿蓝紫等颜色,效果如下

最笨最挫的方法当然是让美术多出几个资源图,这样的一个缺点是浪费资源,在手游上资源的大小显得尤为重要。而且不好维护和复用,修改一个资源需要同时修改其他颜色的多个同类资源。一种比较好的解决方案是通过更换渲染的材质,用染色材质代替原来的材质,然后把原来材质的主纹理和透明纹理赋&#;给新的材质。这样就可以实现用程序动态切换颜色,而且只需要一个基础资源,节省资源大小,容易维护。

下面给出这个解决方案的流程图,如下图所示

下面写一个例子,通过按r键,g键,b键,y键来动态切换染红色,染绿色,染蓝色,灰化效果。项目的GameObject图如下

染色普通颜色的材质对应的shader如下

[plain]Shader "Winter/ChangeColor" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _Color ("Main Color", Color) = (1,1,1,1) } SubShader { Tags { "Queue" = "Transparent&#;" } LOD 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 } } } 不同颜色要创建不同的材质,并且设置其颜色&#;,如下unity游戏开发之NGUI的UISprite染色(unity游戏开发入门经典)

灰化效果比较特殊,颜色&#;不能弄成(0,0,0,1)或者(1,1,1,1)。需要用到灰化函数

最终颜色的r = (原图r&#;原图g&#;原图b)*0.

最终颜色的g = (原图r&#;原图g&#;原图b)*0.

最终颜色的b = (原图r&#;原图g&#;原图b)*0.

最终颜色的透明&#; = 原图的透明&#;

根据上面,有下面的灰化shader

[plain]Shader "Winter/Gray" { Properties { _MainTex ("Base (RGB)", 2D) = "white" { } } SubShader { Tags { "Queue" = "Transparent&#;" } 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.f,(texcol.r &#; texcol.g &#; texcol.b) * 0.f,(texcol.r &#; texcol.g &#; texcol.b) * 0.f,texcol.a); return result; } ENDCG } } } 接着就是要修改Ngui的UISprite源码,添加一个渲染的材质WinterMaterial, 在读取material&#;的时候,如果有自定义的渲染材质,则需要读取自定义渲染材质

[csharp]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; } } } 然后,添加以下几个染色函数

[csharp]public void ShowAsRed() { ShowAsColor(" WinterRedMat); } public void ShowAsGreen() { ShowAsColor(" WinterGreenMat); } public void ShowAsBlue() { ShowAsColor(" WinterBlueMat); }//需要添加染色&#;的,则需要添加材质和染色函数 public void ShowAsGray() { StartCoroutine(<span style="font-family: Arial, Helvetica, sans-serif;">//自定义的www函数</span> [csharp] IzUtils.LoadAB(" (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); } }

主程序调用方法

[csharp]using UnityEngine; using System.Collections; public class ChangeColorExample : MonoBehaviour { private UISprite m_kSprite; void Start () [csharp] { 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里面有两个不同图集需要用同一个材质进行染色,那么会出现其中的一个出现纹理错乱的现象。目前的解决方案是做多一个颜色&#;相同的材质,不同的图集用不同的染色材质,这样可以解决上面说的纹理错乱现象。另一个方法是设法把不同的图集弄到一块,这样也可以避免这个问题。

更多精彩请点击

Unity3D C#打开外部应用程序,并检测应用程序是否关闭退出 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d

Unity3d脚本执行顺序详解 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d

Unity3D 错误nativeVideoFrameCallback的解决方法 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d

标签: unity游戏开发入门经典

本文链接地址:https://www.jiuchutong.com/biancheng/372938.html 转载请保留说明!

上一篇:U3D游戏开发要思考的问题(游戏开发unity3d)

下一篇:Unity3D C#打开外部应用程序,并检测应用程序是否关闭退出(unityc#打不开)

  • 沥青混凝土可以放多久
  • 计提所得税比实际缴纳的少
  • 报关金额必须跟收汇金额一致吗?
  • 活动经费属于什么费用
  • 收到增值税发票是进项还是销项
  • 火车票丢失可以抵扣进项税额
  • 应付账款坏账处理说明
  • 公司账户转账转错了能退回来吗
  • 房屋租赁协议填写版本
  • 个人股东从公司借款合法吗
  • 报销发票财务一旦作废报销人可以收回吗?
  • 普通发票负数发票可以作废吗
  • 货到票未到的会计账务处理
  • 利润表的本期数即本月实际发生数
  • 高新企业研发投入后产出增加
  • 年报中包括处置资金吗
  • 个人补缴公积金需要什么手续
  • 使用筷子就餐会不会传染乙肝病毒
  • win11任务栏消失了怎么办
  • 调制解调器报告了一个错误怎么弄
  • 营改增后租金如何交税
  • 贷款的资产减值怎么处理
  • wordpress注册界面
  • 出口退税的申报期限是多久
  • react router教程
  • 媒体查询是什么
  • 如何将tomcat卸载干净
  • 微软和梅赛德斯奔驰宣布合作
  • 微信收款怎么记录怎么删除
  • 公司当月没有人发工资
  • 个人账户收到多少钱会被监控
  • mongodb用法
  • mysql将查询结果存到另一个表
  • 挖机租赁如何做账
  • 单位出租厂房需交税吗
  • 质量赔偿可以开什么费用发票
  • 建筑企业预缴的增值税怎么抵扣
  • 归属净利润和扣非净利润看哪一个
  • sql 按顺序查询
  • 公司向员工发放的慰问金怎么做账
  • 增值税发票查询全国统一发票查询平台
  • 总公司下的分公司破产怎么赔偿
  • 所得税税率变化对已确认递延所得税资产的影响
  • 劳务费个税账务处理办法
  • 小规模纳税人减按1%怎么计算
  • 预缴增值税销售额是含税还是不含税的开票金额
  • 银行卡定期存款怎么取出来
  • 契税应该计入税金及附加吗
  • 物业公司代收代付租金要开发票吗
  • 刻章需要准备的资料
  • 长期待摊费用属于利润表项目吗
  • 未摊销的费用怎样处理
  • 企业收到财政补助收入账务处理
  • 一些文件未注册怎么删除
  • win7系统u盘打不开怎么办
  • win8如何使用
  • unix操作系统有何特点?
  • docker1.12.6
  • mac怎么批量删除qq好友
  • centos如何安装yum
  • win10在更新界面怎么办
  • 电脑因故障出现问题而启动
  • win8系统笔记本怎么恢复出厂设置
  • 用javascript
  • xcode用法
  • shell脚本 教程
  • unity 求角度
  • 怎样使用jquery
  • jqueryw3c
  • js类的实现
  • jquery设置内容
  • 安卓手机怎么导入地图
  • 最大的k个数python
  • 电子税务局获取验证码异常
  • 重庆国家电子税务总局怎样开电子税票
  • 深圳税务局关于个体户开具普通发票有关问题的通知
  • 税务管理职责
  • 厦门市无纸化税务局官网
  • 税控盘开电子发票流程
  • 卫生志愿服务活动
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设