UGUI ScrollView中显示模型和特效

游戏开发中有时候会遇到在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 = 0; i < renderers.Length; i++)
        {
            //Debug.LogError(renderers[i]);
            modelMaterials.AddRange(renderers[i].GetMaterials());
        }
        for(int i = 0; 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 = 0; 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 *(1- pivot.x),
            w = position.y + mHeight * (1 - 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) = (0,0,1,1)
            //
    }

    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(1)
                    #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( 0, 0, 0 ) ;
                    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多种多样的话,那工作量就比较大,需要其他的方法。

原文地址:https://www.cnblogs.com/pj2933/p/11839598.html

时间: 2024-11-05 13:28:16

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

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

目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 8.UGUI与模型和粒子特效穿插层级管理 写在前面 这篇笔记是整理了之前做的记录,在做项目的过程中,遇到了各种各样的界面穿插问题,界面层级混乱,比如,手机卡了或点快了,就导致两个界面相互交叉.对于界面,这应该算是一个很严重的bug,很大部分原因是整个UI框架没有从整体上考虑这个,后来决心弄清楚层级

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

方法一:直接更改listview的控件高度,动态获取(根据条目和每个条目的高度获取) 前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView.但刚开始的时候,会发现放入的小ListView会显示不完全,它的高度始终有问题.上网查了下,发现别人也有遇到这样的问题,而大多数人都不推荐这样的设计,因为默认情况下Android是禁止在ScrollView中放入另外的ScrollView的,它的高度是无法计

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

最近在设计Android程序时,因为需要在ScrollView中添加一个ListView列表来显示一些信息.刚开始并没有想太多,但添加进去后才发现ListView不论怎样定义都只能显示一行,显示效果很不正常. 后来在网上查了一下才知道,原因是ScrollView和ListView默认都带有滚动条,所以一起使用就会引起冲突.但因为程序中我必须要添加一个ListView,且不想取消外层的ScrollView(想保证用户在程序页面能够上下滑动来浏览更多内容),经过查询找到了解决此问题的方法. 下面记录

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

http://m.blog.csdn.net/blog/yusewuhen/43706169 转载请注明出处: http://blog.csdn.net/androiddevelop/article/details/38815493 希望得到的效果是ListView不能滚动,但是最大的问题在与ListView Item还必有点击事件,如果不需要点击事件那就简单了,直接设置ListView.setEnable(false); 如果还需要点击事件,滚动与点击都是在ListView Touch处理机制

Android -- 在ScrollView中嵌套ListView

在做一个工程,这个工程的布局可以相当的复杂,最外面是ScrollView,在ScrollView里面有两个Listview,这下好了,布局出来了,放在机子上跑,卡得想死有木有,信息乱跑乱出现,表示非常头疼. 在网上百度之后,发现有人解决了这个问题,便把这个解决方案转载过来分享一下. 它的思路就是在设置完ListView的Adapter后,根据ListView的子项目重新计算ListView的高度,然后把高度再作为LayoutParams设置给ListView,这样它的高度就正确了. public

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

前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView.但刚开始的时候,会发现放入的小ListView会显示不完全,它的高度始终有问题.上网查了下,发现别人也有遇到这样的问题,而大多数人都不推荐这样的设计,因为默认情况下Android是禁止在ScrollView中放入另外的ScrollView的,它的高度是无法计算的. 又搜索了一下,发现有StackOverflow上的牛人已经解决了这个问题,经过

UGUI中显示粒子特效

今天在UGUI上显示粒子特效的时候遇到的一些问题,Mark一下.原理:修改特效中每一个ParticleSystem的Layer为UI,并且把ParticleSystemRenderer.sortingOrder值设置为大于Canvas中的sortingOrder值.其实就是控制两个组件 的Render Order. 1. 在UI控件上(eg: Image)显示一个粒子特效 1).首先创建一个Canvas,RenderMode = Screen Space-Camera ,然后创建一个UICame

将.stl文件转化为.dae并动态加载到SceneKit显示(ios中显示3d模型)

ios8之后苹果推出了一个3D模型渲染框架.SceneKit.但是国内针对这方面的教程并不是很多.前两天搞了一下也是一头雾水,终于把最基础的内容搞明白了之后,写下这篇随笔作为cnblogs的开篇,希望能一直写下去. SceneKit现在可以支持有限的几种模型,截止到我写这篇文章为止似乎只有.dae和.abc后一种模型我没有使用过.这篇文章只针对.dae模型写. 首先如果是希望加载一个已有的,不需要程序在运行的时候动态添加的dae模型.那么我们可以直接新建一个game类型的工程.在选项中选择Sce

笔记整理1_1:解决在ScrollView中嵌套ListView不能显示全部item的问题

package com.example.scrollview; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import com.pb.custo