Unity初识之淡入淡出切换scene

首先切换scene 使用sceneManager

SceneManager.LoadScene("Shop");

具体的scene的名字,是按照中的scene的索引值来设置的。

Unity初识之淡入淡出切换scene_第1张图片

现在需要写一个shader ,来做纹理颜色的处理,将纹理按钮某个值,从白色变到黑色。或者黑色变成白色,可以达到淡入淡出的效果.关于Graphics.Blit中的mat参数,Material to use. Material’s shader could do some post-processing effect, for example. 我理解的是,它通过mat的shader去处理前面赋值的texture.

Shader "Unlit/Trans_scene_shader"

{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}

        _Color("Main Color", Color) = (1,1,1,1)
        _ColorRange("color range", Range(0,1)) = 1.0

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata

            {
                float4 vertex : POSITION;

                float2 uv : TEXCOORD0;

            };

            struct v2f

            {
                float2 uv : TEXCOORD0;

                float4 vertex : SV_POSITION;

            };

            sampler2D _MainTex;

            float _ColorRange;

            fixed4 _Color ;

            v2f vert (appdata v)

            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                o.uv = v.uv;
                return o;

            }

            fixed4 frag (v2f i) : SV_Target

            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv) * _ColorRange;

                return col;

            }
            ENDCG
        }
    }

    Fallback off

}

一个c#脚本,绑定在某个想要使用淡入淡出的scene的主摄像机上,

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.Events;

public class shader_transform_scene : MonoBehaviour {

    private Material m_transMat;

//淡入淡出时间
    public float transTime = 0.3f ;

//淡入淡出后的回调
    private UnityAction m_transCallBack = null ;

    private bool m_isStartChange = false ;

//判断是淡入还是淡出
    private bool m_isDisppear = true;

    void Start()

    {

    }

    public void DoChange(UnityAction callback , bool isDisppear , bool isImmidiate) {

        if (m_transMat == null) {

            m_transMat = new Material(Shader.Find("Unlit/Trans_scene_shader"));

            m_transMat.SetFloat("_ColorRange", 0);

        }

        m_transCallBack = callback ;

        m_isDisppear = isDisppear ;

        m_isStartChange = true ;

        if (m_isDisppear) {

            m_transMat.SetFloat("_ColorRange", 0);

        }
        else {

            m_transMat.SetFloat("_ColorRange", 1);

        }

        if (isImmidiate) {

            m_isStartChange = false ;

            m_transMat.SetFloat("_ColorRange", 1);

        }
    }

    void Update()

    {
        if (m_isStartChange) {

            changeColor();
        }
    }

    private void changeColor() {

        float dist = m_isDisppear ? -1 : 1 ;

        float count = m_transMat.GetFloat("_ColorRange") - transTime*Time.deltaTime*dist;

        m_transMat.SetFloat("_ColorRange", count);

        if (m_transMat.GetFloat("_ColorRange") <= 0 && m_isDisppear == false ||

            m_transMat.GetFloat("_ColorRange") >=1 && m_isDisppear == true) {

            if (m_transCallBack!= null) {

                m_transCallBack.Invoke();
            }
            m_isStartChange = false;

        }
    }

    //https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnRenderImage.html
    //得到渲染后的屏幕图像
  void OnRenderImage(RenderTexture src, RenderTexture dest) {

        if (m_transMat == null) {

            return ;

        }
        //用Blit来完成对渲染纹理的处理
  //unity 会把当前渲染得到的图像存储在第一个参数的源渲染纹理中,通过函数中的一些列操作,再把目标渲染纹理,即第二个参数对应的渲染纹理显示在屏幕上。
        // Copy the source Render Texture to the destination,
    // applying the material along the way.
          //https://docs.unity3d.com/ScriptReference/Graphics.Blit.html
         // Material to use. Material's shader could do some post-processing effect, for example.
        Graphics.Blit(src, dest , m_transMat);

    }
}

在scene中使用,
进入的时候

private shader_transform_scene m_transScript = null ;

    private bool m_isInTransform = false ;

    void Start()

    {

          m_btnHome.onClick.AddListener(()=> handleTouch(m_btnHome));

        m_transScript = Camera.main.GetComponent<shader_transform_scene>();

        if (m_transScript) {

            m_transScript.DoChange(null , true, false);

        }
    }

点击按钮切换

private void handleTouch(Button btn) {

        if (btn == m_btnHome) {

            if (m_transScript) {

                m_isInTransform = true ;

                m_transScript.DoChange(transToMain , false, false);

            }

            SoundsManager.getInstance().playSounds(SoundsManager.clipNameClick);
        }
    }

    public void transToMain() {

        SceneManager.LoadScene("Menu");
        m_isInTransform = true ;

    }

NOTE:
这种使用shader的方式,在editor中是ok的,但是如果要导出成其他平台的,比如ios,如果这个shader没有被引用过,是不会被包含在player的build中的。
解决方式是,可以将其改为引用的方式而不是脚本动态创建,用editor去索引。
或者,在Edit->project Setting -> graphics ->

Unity初识之淡入淡出切换scene_第2张图片

你可能感兴趣的:(unity初识,Unity初识)