【Unity3D ugui】UI特效的位置自适应及调整层次关系的一种解决方案
来源:互联网 发布:乐视高清直播软件 编辑:程序博客网 时间:2024/05/22 14:59
前言
在UI上显示3D的特效,要考虑两个问题:
1、特效的位置自适应与UGUI自适应一致,否则在16:9下把特效调好位置后,切成16:10后,位置对应不上
2、特效显示层次最好能夹在UI中间
UGUI毕竟是个新的UI系统,各方面还很不成熟,显示特效的问题着实让我头疼了一番。
1、UI特效叠层显示可以参考雨松MOMO的博客:UGUI研究院之不添加摄像机解决UI与UI特效叠层问题(九),但是只能解决叠层的问题,而且对于复杂的界面系统,每一层都加一个UIDepth的组件非常蛋疼。自适应的问题要根据不同分辨率再进行一番艰难的调整,除非你可以写一套类似的Canvas自适应系统。
2、使用UGUI的RawImage,把Camera拍摄特效输出的RenderTexture拖到RawImage上,运行时即可看到效果。这种方法不仅能使用UGUI的自适应,而且层级也可以调整,通常显示UI模型时都是用这种方法,但是对于半透明的粒子、Mesh就不那么好处理了。最后找到一位前辈的文章,终于解决了困扰了我好几天的问题。想看原文点这里。
原理
1、用一个单独的相机,对着特效拍照,设置输出的Target Texture
2、使用UGUI的RawImage组件,设置Texture为相机输出的Texture
这部分的内容,其实官方已经给出demo,打开RenderTexture场景就可以看到这个例子,就不详述了
实现
参照原文。
下面用图来说明几个步骤:
先说一下demo的层次结构,“Window”下有两个Image,一个RawImage,RawImage夹在两个Image中间,我们想要的效果就是RawImage在Image1上,在Image2下。
1、相机参数设置
2、特效设置层次为UI3D(自己添加的Layer)
相机拍到特效的效果如下:
3、在UI中加上一个RawImage,设置Texture为上一步相机输出的Texture,加一个Default No-Alpha的材质(Shader在下面贴出,demo资源里也有)
4、运行查看效果
一些问题
1、RenderTexture的尺寸越大,内存占用越多,尽可能缩减RenderTexture的尺寸吧
2、RenderTexture的尺寸要与RawImage的大小一致,否则出现拉伸变形
3、每个特效对应一个相机,如果特效多的话,还是用代码管理特效相机吧
进一步思考,通常美术把一个特效的prefab发过来,我们只要把这个prefab和UI中的RawImage绑定即可,相机什么的才不想每次都动手加一遍,所以有了下面偷懒的代码
using UnityEngine;using UnityEngine.UI;[RequireComponent(typeof(RawImage))]public class UI3DEffect : MonoBehaviour{ [SerializeField] private GameObject effectPrefab; private GameObject effectGO; private RenderTexture renderTexture; private Camera rtCamera; private RawImage rawImage; void Awake() { //RawImage可以手动添加,设置no alpha材质,以显示带透明的粒子 rawImage = gameObject.GetComponent<RawImage>(); if (rawImage == null) { rawImage = gameObject.AddComponent<RawImage>(); } } public RectTransform rectTransform { get { return transform as RectTransform; } } void OnEnable() { if (effectPrefab != null) { effectGO = Instantiate(effectPrefab); GameObject cameraObj = new GameObject("UIEffectCamera"); rtCamera = cameraObj.AddComponent<Camera>(); renderTexture = new RenderTexture((int)rectTransform.sizeDelta.x, (int)rectTransform.sizeDelta.y, 24); renderTexture.antiAliasing = 4; rtCamera.clearFlags = CameraClearFlags.SolidColor; rtCamera.backgroundColor = new Color(); rtCamera.cullingMask = 1 << 8; rtCamera.targetTexture = renderTexture; effectGO.transform.SetParent(cameraObj.transform, false); rawImage.enabled = true; rawImage.texture = renderTexture; } else { rawImage.texture = null; Debug.LogError("EffectPrefab can't be null"); } } void OnDisable() { if (effectGO != null) { Destroy(effectGO); effectGO = null; } if (rtCamera != null) { Destroy(rtCamera.gameObject); rtCamera = null; } if (renderTexture != null) { Destroy(renderTexture); renderTexture = null; } rawImage.enabled = false; }}
当RawImage启用时,立刻创建动态相机、RenderTexture,设置参数。不启用时,自动销毁相机和RenderTexture。当然特效多的话,也可以做个对象池把Camera和RenderTexture缓存起来。
然后用的时候是这样的,只需要一步,把特效prefab拖进来即可
附
demo
UI-Default-No-Alpha.shader
Shader "UI/Default No-Alpha"{ Properties { [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {} _Color("Tint", Color) = (1,1,1,1) _StencilComp("Stencil Comparison", Float) = 8 _Stencil("Stencil ID", Float) = 0 _StencilOp("Stencil Operation", Float) = 0 _StencilWriteMask("Stencil Write Mask", Float) = 255 _StencilReadMask("Stencil Read Mask", Float) = 255 _ColorMask("Color Mask", Float) = 15 } SubShader { Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } Stencil { Ref[_Stencil] Comp[_StencilComp] Pass[_StencilOp] ReadMask[_StencilReadMask] WriteMask[_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest[unity_GUIZTestMode] Fog{ Mode Off } Blend One Zero ColorMask[_ColorMask] Blend One OneMinusSrcAlpha // 源rgba*1 + 背景rgba*(1-源A值) Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; half2 texcoord : TEXCOORD0; }; fixed4 _Color; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex); OUT.texcoord = IN.texcoord; #ifdef UNITY_HALF_TEXEL_OFFSET OUT.vertex.xy -= (_ScreenParams.zw - 1.0); #endif OUT.color = IN.color * _Color; return OUT; } sampler2D _MainTex; fixed4 frag(v2f IN) : SV_Target { half4 color = tex2D(_MainTex, IN.texcoord) * IN.color; //clip (color.a - 0.01); return color; } ENDCG } }}
- 【Unity3D ugui】UI特效的位置自适应及调整层次关系的一种解决方案
- Unity3d 调整UI和粒子特效的层次关系
- Unity3D的UGUI—Canvas的渲染顺序及层次关系总结
- unity3d 在UGUI中制作自适应调整大小的滚动布局控件
- unity3d 在UGUI中制作自适应调整大小的滚动布局控件
- unity3d 在UGUI中制作自适应调整大小的滚动布局控件
- unity3d 在UGUI中制作自适应调整大小的滚动布局控件
- unity3d 在UGUI中制作自适应调整大小的滚动布局控件
- Unity3D在2D游戏中利用UGUI实现分辨率自适应的一种可行实践方案
- Unity3D 实例化UGUI自适应的预设
- unity3d基于ugui的ui模块
- Unity的UGUI调节层次而不影响位置
- [Unity3D]UGUI分辨率自适应的组件和方法
- UGUI多个Canvas的渲染先后层次关系设置
- Unity NGUI和UGUI与模型、特效的层级关系
- Unity NGUI和UGUI与模型、特效的层级关系
- UGUI播放UI特效以及解决特效与UI的层级问题
- Unity2d 移动设备的横竖屏适配及UGUI画布调整使Editor与真实设备的UI显示保持一致
- HTTP响应头和请求头信息对照表
- XML学习笔记(一):HTML文件转成XML文件
- Android 监听数据变化比较合理的写法总结
- Android Studio学习笔记3创建新窗口(activity)并进行跳转
- POJ-1656-Counting Black- 四分树
- 【Unity3D ugui】UI特效的位置自适应及调整层次关系的一种解决方案
- 初识Jenkins(一)
- CentOS 7默认的jdk 1.7升级方法(到1.8) - alternatives的功能
- 页面跳转与重定向(之二)
- License的攻与防
- re.MatchObject() Python
- 六款值得推荐的android(安卓)开源框架(包含下载链接)
- 开始iOS 7中自动布局教程(一)
- CF R334 div2