统一场景之间的自动淡入淡出在 OSX 上不起作用
Auto fade between scenes in unity not working on OSX
我刚刚将我的项目导入到 mac 的 unity 中。我有 unity pro 许可证,我在两台计算机(带 windows 8 的电脑)和 OS X yosemite 上都使用 unity 4.6.3。当我在 pc(windows)中测试我的项目时,自动淡入淡出工作正常,但是当我在我的 mac 上进行时,它会等待场景之间的时间,但它只会使屏幕变黑而不会褪色.这是脚本:
using UnityEngine;
using System.Collections;
public class AutoFade : MonoBehaviour
{
private static AutoFade m_Instance = null;
private Material m_Material = null;
private string m_LevelName = "";
private int m_LevelIndex = 0;
private bool m_Fading = false;
private static AutoFade Instance
{
get
{
if (m_Instance == null)
{
m_Instance = (new GameObject("AutoFade")).AddComponent<AutoFade>();
}
return m_Instance;
}
}
public static bool Fading
{
get { return Instance.m_Fading; }
}
private void Awake()
{
DontDestroyOnLoad(this);
m_Instance = this;
m_Material = new Material("Shader \"Plane/No zTest\" { SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Off Fog { Mode Off } BindChannels { Bind \"Color\",color } } } }");
}
private void DrawQuad(Color aColor,float aAlpha)
{
aColor.a = aAlpha;
m_Material.SetPass(0);
GL.Color(aColor);
GL.PushMatrix();
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.Vertex3(0, 0, -1);
GL.Vertex3(0, 1, -1);
GL.Vertex3(1, 1, -1);
GL.Vertex3(1, 0, -1);
GL.End();
GL.PopMatrix();
}
private IEnumerator Fade(float aFadeOutTime, float aFadeInTime, Color aColor)
{
float t = 0.0f;
while (t<1.0f)
{
yield return new WaitForEndOfFrame();
t = Mathf.Clamp01(t + Time.deltaTime / aFadeOutTime);
DrawQuad(aColor,t);
}
if (m_LevelName != "")
Application.LoadLevel(m_LevelName);
else
Application.LoadLevel(m_LevelIndex);
while (t>0.0f)
{
yield return new WaitForEndOfFrame();
t = Mathf.Clamp01(t - Time.deltaTime / aFadeInTime);
DrawQuad(aColor,t);
}
m_Fading = false;
}
private void StartFade(float aFadeOutTime, float aFadeInTime, Color aColor)
{
m_Fading = true;
StartCoroutine(Fade(aFadeOutTime, aFadeInTime, aColor));
}
public static void LoadLevel(string aLevelName,float aFadeOutTime, float aFadeInTime, Color aColor)
{
if (Fading) return;
Instance.m_LevelName = aLevelName;
Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
}
public static void LoadLevel(int aLevelIndex,float aFadeOutTime, float aFadeInTime, Color aColor)
{
if (Fading) return;
Instance.m_LevelName = "";
Instance.m_LevelIndex = aLevelIndex;
Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
}
}
在播放器设置中将图形 API 设置为打开 GL ES 2.0。这可能与随 Unity 4.6.3 发布的新 iOs Metal Rendering 有关。
问题是,Windows 上的 Unity 使用的是 DirectX 而不是 OpenGL,所以它在那里工作(正如你问题的评论中已经提到的)。
只需在 Windows 上使用 -force-opengl
启动 Unity,您会注意到,它也会在那里停止工作。
见http://answers.unity3d.com/questions/447206/forcing-opengl-in-windows-editor.html
进一步调查表明,您的着色器不符合您的需要。你需要一个顶点着色器。
见http://answers.unity3d.com/questions/55392/why-my-glcolor-doesnt-work.html
例如:
Shader "Unlit Transparent Vertex Colored"
{
Properties
{
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
Category
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
ZWrite Off
//Alphatest Greater 0
Blend SrcAlpha OneMinusSrcAlpha
Fog { Color(0,0,0,0) }
Lighting Off
Cull Off //we can turn backface culling off because we know nothing will be facing backwards
BindChannels
{
Bind "Vertex", vertex
Bind "texcoord", texcoord
Bind "Color", color
}
SubShader
{
Pass
{
SetTexture [_MainTex]
{
Combine texture * primary
}
}
}
}
}
只需将该着色器存储在 Assets/Resources
中的某处,例如作为 test.shader
并将其加载到 Awake()
中,如下所示:
private void Awake()
{
DontDestroyOnLoad(this);
m_Instance = this;
var shader = Shader.Find("Unlit Transparent Vertex Colored"); // <= it's some kind of best practise to put shaders in separate files, and load them like this
m_Material = new Material(shader);
}
Shader.Find
http://docs.unity3d.com/ScriptReference/Shader.Find.html
此外,您必须将 GL.Begin()
放在 DrawQuad()
方法中 GL
内容的开头。
private void DrawQuad(Color aColor,float aAlpha)
{
aColor.a = aAlpha;
m_Material.SetPass(0);
GL.Begin(GL.QUADS); // <= put it here
GL.Color(aColor);
GL.PushMatrix();
GL.LoadOrtho();
GL.Vertex3(0, 0, -1);
GL.Vertex3(0, 1, -1);
GL.Vertex3(1, 1, -1);
GL.Vertex3(1, 0, -1);
GL.End();
GL.PopMatrix();
}
现在对我来说就像一个魅力。 :-)
如果您对此有任何问题,请告诉我!
旧答案:
我保留了第一个答案,因为这是解决该问题的一个很好的替代方法。
这似乎是一个 OpenGL 问题,因为它也无法在使用 -force-opengl
的 Unity 4.6.3 上使用 Windows,正如您的问题的评论中已经提到的那样(无需强制即可正常工作OpenGL).
见http://answers.unity3d.com/questions/447206/forcing-opengl-in-windows-editor.html
因此,我建议使用以下方法,因为它适用于 OpenGL 和 DirectX。
只需更改您的 "DrawQuad" 方法,如下所示:
private void DrawQuad(Color aColor, float aAlpha)
{
aColor.a = aAlpha;
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, aColor);
texture.Apply();
GUI.skin.box.normal.background = texture;
GUI.Box(new Rect(0, 0, Screen.width, Screen.height), GUIContent.none);
}
另见 http://forum.unity3d.com/threads/draw-a-simple-rectangle-filled-with-a-color.116348/
根据 GL.Color 的文档,它 "can only be called between GL.Begin and GL.End functions"。您对 GL.Color 的调用发生在 GL.Begin.
之前
我刚刚将我的项目导入到 mac 的 unity 中。我有 unity pro 许可证,我在两台计算机(带 windows 8 的电脑)和 OS X yosemite 上都使用 unity 4.6.3。当我在 pc(windows)中测试我的项目时,自动淡入淡出工作正常,但是当我在我的 mac 上进行时,它会等待场景之间的时间,但它只会使屏幕变黑而不会褪色.这是脚本:
using UnityEngine;
using System.Collections;
public class AutoFade : MonoBehaviour
{
private static AutoFade m_Instance = null;
private Material m_Material = null;
private string m_LevelName = "";
private int m_LevelIndex = 0;
private bool m_Fading = false;
private static AutoFade Instance
{
get
{
if (m_Instance == null)
{
m_Instance = (new GameObject("AutoFade")).AddComponent<AutoFade>();
}
return m_Instance;
}
}
public static bool Fading
{
get { return Instance.m_Fading; }
}
private void Awake()
{
DontDestroyOnLoad(this);
m_Instance = this;
m_Material = new Material("Shader \"Plane/No zTest\" { SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Off Fog { Mode Off } BindChannels { Bind \"Color\",color } } } }");
}
private void DrawQuad(Color aColor,float aAlpha)
{
aColor.a = aAlpha;
m_Material.SetPass(0);
GL.Color(aColor);
GL.PushMatrix();
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.Vertex3(0, 0, -1);
GL.Vertex3(0, 1, -1);
GL.Vertex3(1, 1, -1);
GL.Vertex3(1, 0, -1);
GL.End();
GL.PopMatrix();
}
private IEnumerator Fade(float aFadeOutTime, float aFadeInTime, Color aColor)
{
float t = 0.0f;
while (t<1.0f)
{
yield return new WaitForEndOfFrame();
t = Mathf.Clamp01(t + Time.deltaTime / aFadeOutTime);
DrawQuad(aColor,t);
}
if (m_LevelName != "")
Application.LoadLevel(m_LevelName);
else
Application.LoadLevel(m_LevelIndex);
while (t>0.0f)
{
yield return new WaitForEndOfFrame();
t = Mathf.Clamp01(t - Time.deltaTime / aFadeInTime);
DrawQuad(aColor,t);
}
m_Fading = false;
}
private void StartFade(float aFadeOutTime, float aFadeInTime, Color aColor)
{
m_Fading = true;
StartCoroutine(Fade(aFadeOutTime, aFadeInTime, aColor));
}
public static void LoadLevel(string aLevelName,float aFadeOutTime, float aFadeInTime, Color aColor)
{
if (Fading) return;
Instance.m_LevelName = aLevelName;
Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
}
public static void LoadLevel(int aLevelIndex,float aFadeOutTime, float aFadeInTime, Color aColor)
{
if (Fading) return;
Instance.m_LevelName = "";
Instance.m_LevelIndex = aLevelIndex;
Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
}
}
在播放器设置中将图形 API 设置为打开 GL ES 2.0。这可能与随 Unity 4.6.3 发布的新 iOs Metal Rendering 有关。
问题是,Windows 上的 Unity 使用的是 DirectX 而不是 OpenGL,所以它在那里工作(正如你问题的评论中已经提到的)。
只需在 Windows 上使用 -force-opengl
启动 Unity,您会注意到,它也会在那里停止工作。
见http://answers.unity3d.com/questions/447206/forcing-opengl-in-windows-editor.html
进一步调查表明,您的着色器不符合您的需要。你需要一个顶点着色器。
见http://answers.unity3d.com/questions/55392/why-my-glcolor-doesnt-work.html
例如:
Shader "Unlit Transparent Vertex Colored"
{
Properties
{
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
Category
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
ZWrite Off
//Alphatest Greater 0
Blend SrcAlpha OneMinusSrcAlpha
Fog { Color(0,0,0,0) }
Lighting Off
Cull Off //we can turn backface culling off because we know nothing will be facing backwards
BindChannels
{
Bind "Vertex", vertex
Bind "texcoord", texcoord
Bind "Color", color
}
SubShader
{
Pass
{
SetTexture [_MainTex]
{
Combine texture * primary
}
}
}
}
}
只需将该着色器存储在 Assets/Resources
中的某处,例如作为 test.shader
并将其加载到 Awake()
中,如下所示:
private void Awake()
{
DontDestroyOnLoad(this);
m_Instance = this;
var shader = Shader.Find("Unlit Transparent Vertex Colored"); // <= it's some kind of best practise to put shaders in separate files, and load them like this
m_Material = new Material(shader);
}
Shader.Find
http://docs.unity3d.com/ScriptReference/Shader.Find.html
此外,您必须将 GL.Begin()
放在 DrawQuad()
方法中 GL
内容的开头。
private void DrawQuad(Color aColor,float aAlpha)
{
aColor.a = aAlpha;
m_Material.SetPass(0);
GL.Begin(GL.QUADS); // <= put it here
GL.Color(aColor);
GL.PushMatrix();
GL.LoadOrtho();
GL.Vertex3(0, 0, -1);
GL.Vertex3(0, 1, -1);
GL.Vertex3(1, 1, -1);
GL.Vertex3(1, 0, -1);
GL.End();
GL.PopMatrix();
}
现在对我来说就像一个魅力。 :-)
如果您对此有任何问题,请告诉我!
旧答案:
我保留了第一个答案,因为这是解决该问题的一个很好的替代方法。
这似乎是一个 OpenGL 问题,因为它也无法在使用 -force-opengl
的 Unity 4.6.3 上使用 Windows,正如您的问题的评论中已经提到的那样(无需强制即可正常工作OpenGL).
见http://answers.unity3d.com/questions/447206/forcing-opengl-in-windows-editor.html
因此,我建议使用以下方法,因为它适用于 OpenGL 和 DirectX。
只需更改您的 "DrawQuad" 方法,如下所示:
private void DrawQuad(Color aColor, float aAlpha)
{
aColor.a = aAlpha;
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, aColor);
texture.Apply();
GUI.skin.box.normal.background = texture;
GUI.Box(new Rect(0, 0, Screen.width, Screen.height), GUIContent.none);
}
另见 http://forum.unity3d.com/threads/draw-a-simple-rectangle-filled-with-a-color.116348/
根据 GL.Color 的文档,它 "can only be called between GL.Begin and GL.End functions"。您对 GL.Color 的调用发生在 GL.Begin.
之前