unity 让ui对齐_【Unity3D ugui】UI特效的位置自适应及调整层次关系的一种解决方案...

本文介绍了如何在Unity3D中解决UI特效的位置自适应和层次关系问题。通过使用单独的相机拍照并结合RawImage组件,实现了特效与UGUI的自适应一致性和夹在UI中间的显示效果。同时,文章提供了相应的代码示例和注意事项,如内存优化和渲染纹理尺寸的匹配。
摘要由CSDN通过智能技术生成

[unity3d 多语言 解决方案1——自定义本地文本今天在学习packerpro这款插件的使用的时候留意到它里边使用到的多语言方案十分有趣,算是一种比较朴素但是实用的方法——通过

前言

在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、相机参数设置

[http://www.supersuraccoon-有时候我们需要在程序中弹出一个模态对话框来告诉用户一些信息,这时候使用“EditorUtility.DisplayDialog” 就足够满足要求了,但是当我们需

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();

if (rawImage == null)

{

rawImage = gameObject.AddComponent();

}

}

public RectTransform rectTransform

{

get

{

return transform as RectTransform;

}

}

void OnEnable()

{

if (effectPrefab != null)

{

effectGO = Instantiate(effectPrefab);

GameObject cameraObj = new GameObject("UIEffectCamera");

rtCamera = cameraObj.AddComponent();

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拖进来即可

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

}

}

}[其实3D物体基本不用考虑渲染顺序问题,但是在纯2D以及3D和2D混杂的情况下就要考虑这个问题了。比如2D游戏当中的游戏场景,UI,UI特效,场景内特效。那么,使用一个统一的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值