首先切换scene 使用sceneManager
SceneManager.LoadScene("Shop");
具体的scene的名字,是按照中的scene的索引值来设置的。
现在需要写一个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 ->