游戏开发中有时候会遇到在UI上显示模型和特效的需求,这次需要在ScrollView上显示。我们使用UGUI的Screen Space - Camera模式,修改模型和特效的layer使之显示在UI上面,但是会遇到ScrollView的mask无法剔除模型和特效的问题。

解决思路:计算出ScrollView的显示矩形框的世界坐标和尺寸,传给模型和特效的shader,在shader里判断这个像素的世界坐标是否超过矩形框,来判断是否显示图像。

C#代码部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class ScrollViewModelAndEffectClip : MonoBehaviour
{ public RectTransform scrollViewArea;
float mWidth, mHeight, m_canvasScale;
Canvas mCanvas;
public Vector4 area;
List<Material> modelMaterials = new List<Material>();
// Start is called before the first frame update
void Start()
{ var renderers=GetComponentsInChildren<Renderer>();
for(int i = ; i < renderers.Length; i++)
{
//Debug.LogError(renderers[i]);
modelMaterials.AddRange(renderers[i].GetMaterials());
}
for(int i = ; i < modelMaterials.Count; i++)
{
modelMaterials[i].shader = Shader.Find(modelMaterials[i].shader.name + "ScrollViewClip");
//Debug.LogError(modelMaterials[i].shader.name + "ScrollViewClip");
} mCanvas = GetComponentInParent<Canvas>();
GetArea();
} // Update is called once per frame
void Update()
{ } public void GetArea()
{
m_canvasScale = mCanvas.transform.localScale.x;
mWidth = scrollViewArea.rect.width * m_canvasScale;
mHeight = scrollViewArea.rect.height * m_canvasScale; area = CalculateArea(scrollViewArea.position, scrollViewArea.pivot); for (int i = ; i < modelMaterials.Count; i++)
{
//Debug.LogError(area);
modelMaterials[i].SetVector("_Area", area);
} } Vector4 CalculateArea(Vector3 position,Vector2 pivot)
{
return new Vector4()
{
x = position.x - mWidth*pivot.x,
y = position.y - mHeight * pivot.y,
z = position.x + mWidth *(- pivot.x),
w = position.y + mHeight * ( - pivot.y)
};
} }

接下来是Shader:

Shader "SonicDance/AddtiveScrollViewClip"
{
Properties
{
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Particle Texture", 2D) = "white" {}
_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
//Clip新增
_Area("Area", Vector) = (,,,)
//
} Category
{
SubShader
{
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
Cull Off
Lighting Off
ZWrite Off Pass { CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_particles
#pragma multi_compile_fog #include "UnityCG.cginc" struct appdata_t
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float4 texcoord : TEXCOORD0;
float4 worldPos:TEXCOORD3;
UNITY_FOG_COORDS()
#ifdef SOFTPARTICLES_ON
float4 projPos : TEXCOORD2;
#endif
UNITY_VERTEX_OUTPUT_STEREO }; uniform sampler2D _MainTex;
uniform fixed4 _TintColor;
uniform float4 _MainTex_ST;
uniform sampler2D_float _CameraDepthTexture;
uniform float _InvFade;
//Clip新增
float4 _Area;
// v2f vert ( appdata_t v )
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); v.vertex.xyz += float3( , , ) ;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos= mul(unity_ObjectToWorld, v.vertex);
#ifdef SOFTPARTICLES_ON
o.projPos = ComputeScreenPos (o.vertex);
COMPUTE_EYEDEPTH(o.projPos.z);
#endif
o.color = v.color;
o.texcoord = v.texcoord;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
} fixed4 frag ( v2f i ) : SV_Target
{ //新增,判断顶点坐标是否在裁剪框内 bool inArea = i.worldPos.x >= _Area.x && i.worldPos.x <= _Area.z && i.worldPos.y >= _Area.y && i.worldPos.y <= _Area.w;
if (!inArea)
discard;
//----end---- #ifdef SOFTPARTICLES_ON
float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
float partZ = i.projPos.z;
float fade = saturate (_InvFade * (sceneZ-partZ));
i.color.a *= fade;
#endif fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw );
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
CustomEditor "ASEMaterialInspector"
}

这个方法有一个问题就是,需要复制一份显示的模型和特效的shader,并且增加上面shader中注释的部分,如果模型和特效的shader多种多样的话,那工作量就比较大,需要其他的方法。

UGUI ScrollView中显示模型和特效的更多相关文章

  1. Android 6.0+ RecyclerView嵌套在ScrollView中显示不全

    ScrollView嵌套RecyclerView在Android6.0以下能正常显示,但是在6.0以上就会出现RecyclerView显示不全的bug.尝试多种方法之后终于找到解决办法,特在此记录下. ...

  2. Unity NGUI和UGUI与模型、特效的层级关系

    目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...

  3. 解决在ScrollView中套用ListView显示不正常

    最近在设计Android程序时,因为需要在ScrollView中添加一个ListView列表来显示一些信息.刚开始并没有想太多,但添加进去后才发现ListView不论怎样定义都只能显示一行,显示效果很 ...

  4. Android--------解决ScrollView中嵌套ExpandableListView显示不全的问题

    ##***Scrollview和ExpandableListView嵌套显示不全*** - 当我们将ExpandableListView嵌套在Scrollview之中时,我们必须要确保我们的不居中Ex ...

  5. ScrollView中嵌套ListView时,listview高度显示的问题

    方法一:直接更改listview的控件高度,动态获取(根据条目和每个条目的高度获取) 前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个Lis ...

  6. Android 如何在ScrollView中嵌套ListView

    前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView.但刚开始的时候,会发现放入的小ListVie ...

  7. Android 设置ListView不可滚动 及在ScrollView中不可滚动的设置

    http://m.blog.csdn.net/blog/yusewuhen/43706169 转载请注明出处: http://blog.csdn.net/androiddevelop/article/ ...

  8. Android实战技巧:如何在ScrollView中嵌套ListView

    前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView.但刚开始的时候,会发现放入的小ListVie ...

  9. Android -- 在ScrollView中嵌套ListView

    在做一个工程,这个工程的布局可以相当的复杂,最外面是ScrollView,在ScrollView里面有两个Listview,这下好了,布局出来了,放在机子上跑,卡得想死有木有,信息乱跑乱出现,表示非常 ...

随机推荐

  1. vue 生成 二维码 qrCode 插件 使用 方法

    首先安装方法:(--save 参数会改变package.json 推荐使用 下次直接install就行了) npm install --save qrcode 然后项目使用: import QRCod ...

  2. MySQL之Field 'email' doesn't have a default value问题

    MySQL在出现这个Field xxx doesn't have a default value错误的原因是:我们设置了该字段为非空,但是我们没有设置默认值照成的. 比如我们创建一个表: CREATE ...

  3. 中和IOS七层架构和TCP/IP四层架构的五层架构

    五层架构分别为应用层.运输层.网络层.数据链路层.物理层. IOS架构把应用层又细分为应用层.表示层.会话层 TCP/IP把网络层改名网际层,数据链路层和物理层结合成网络接口层 其实只要学习五层协议, ...

  4. H3C 配置路由器作为FTP客户端

  5. element ui 批量删除

    <el-table :data="tableData" stripe border style="width: 100%" @selection-chan ...

  6. H3C 三种生成树协议特性的比较

  7. 应用九:Vue之国际化(vue-i18n)

    vue-i18n是一款针对Vue.js 的国际化插件,具体应用步骤如下: 一.安装插件 npm install vue-i18n --save 二.在main.js中引入插件 import VueI1 ...

  8. Linux 内核总线

    一个总线是处理器和一个或多个设备之间的通道. 为设备模型的目的, 所有的设备都通过 一个总线连接, 甚至当它是一个内部的虚拟的,"平台"总线. 总线可以插入另一个 - 一个 USB ...

  9. RocketMQ各组件介绍

    Rocket 架构主要分为4部分: Producer 消息发布者,支持分布式集群部署.Produer 通过 MQ 负载均衡模块选择相应 Broker 中的 queue 进行消息投递,投递过程支持快速失 ...

  10. 解决win10台式机插入耳机没有声音或者音量不大

    没有声音 如果是插入机箱的前面板,尝试切换到后面板,因为有些组装机箱的前面板是不能用的 有声音,单音量不大(注意:并不一定适用于所有情况,但是可以尝试一下) 原因:缺少驱动,可以确定下控制面板是否有这 ...