Search Unity

Crossfade 2 cameras, overlay a third

Discussion in 'Image Effects' started by OhiraKyou, Mar 4, 2017.

  1. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    I am crossfading from one camera (depth 0) to another (depth -1) using this script: http://wiki.unity3d.com/index.php/CrossFadePro

    I then overlay a character on top of this with a third camera (depth 1). However, although the third camera is overlayed, it also fades in when it should have no reason to. It's not referenced at all in the script; only camera 1 and 2 are. Camera 3 is just an unrelated camera rendering a character.

    Anyone know what I can do to solidly overlay the third camera without it fading?
     
  2. ElKrullo

    ElKrullo

    Joined:
    Feb 24, 2013
    Posts:
    17
    This is an old question but I came across the same thing today. The reason for this problem is that CrossFadePro renders the texture in the GUI which is always rendered on top of all cameras.

    Code (JavaScript):
    1. function OnGUI () {
    2.     GUI.depth = -9999999;
    3.     GUI.color.a = alpha;
    4.     GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), tex);
    5. }
    I imagine a solution for this might be to modify that part of the script and let it push the texture onto a plane in the scene instead. Make sure that plane is always the same size as the screen.
     
    OhiraKyou likes this.
  3. ElKrullo

    ElKrullo

    Joined:
    Feb 24, 2013
    Posts:
    17
    OK, so I made my own version of the ScreenWipe/CrossFadePro script to fit my needs. Maybe someone else will find it useful. This solution requires a Canvas and a child GameObject with a RawImage component and a special Camera to render the fade effect. I have tested it on iOS 11 (iPhone 6) and it seems to work fine there.

    Scene setup:
    • Create a Canvas and add a CanvasGroup component to it. The CanvasGroup is what you use to fade the RenderTexture.
    • Create a child GameObject to the canvas and add a RawImage component to it. In the RectTransform, make sure to set it to stretch so that it will fill the whole canvas (and screen).
    • Create a custom layer and assign it to the Canvas and the RawImage object.
    • Create a special camera to render the result on top of the cameras you are fading between. It should have a depth setting larger than the cameras we are fading between. Also, set Clear Flags to Don't Clear and Culling Mask to render only the layer you created earlier.
    • Create additional cameras with larger depth settings to render UI or other things on top of the fade effect.
    Below is my script, but first an example of how you invoke it from another script. Of course you need to assign public variables and hook them up in the inspector:

    Code (CSharp):
    1. yield return StartCoroutine(
    2.    CameraTransition.instance.CrossFade(
    3.       swap?cam1:cam2,
    4.       swap?cam2:cam1,
    5.       fadeTime,
    6.       rawImage,
    7.       canvasGroup,
    8.       animationCurve
    9.    )
    10. );
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class CameraTransition : MonoBehaviour
    6. {
    7.     private Texture _tex;
    8.     private RenderTexture _renderTex;
    9.     private CanvasGroup _canvasGroup;
    10.     private float _alpha;
    11.     private AnimationCurve _curve;
    12.     private bool  _reEnableListener;
    13.  
    14.     public static CameraTransition instance;
    15.  
    16.     void Awake()
    17.     {
    18.         if (instance == null)
    19.             instance = this;
    20.         else if (instance != this)
    21.             Destroy(gameObject);
    22.     }
    23.  
    24.     IEnumerator AlphaTimer ( float time )
    25.     {
    26.         float rate = 1.0f/time;
    27.    
    28.         if( _curve != null )
    29.         {
    30.             float t = 0.0f;
    31.        
    32.             while( t < 1.0f )
    33.             {
    34.                 _alpha = _curve.Evaluate( t );
    35.                 t += Time.deltaTime * rate;
    36.                 _canvasGroup.alpha = _alpha;
    37.                 yield return 0;
    38.             }
    39.         }
    40.         else
    41.         {
    42.             for (_alpha = 1.0f; _alpha > 0.0f; _alpha -= Time.deltaTime * rate)
    43.             {
    44.                 _canvasGroup.alpha = _alpha;
    45.                 yield return 0;
    46.             }
    47.         }
    48.     }
    49.  
    50.     void CameraSetup( Camera cam1, Camera cam2, bool cam1Active, bool enableThis )
    51.     {
    52.         if (enableThis)
    53.         {
    54.             this.enabled = true;
    55.         }
    56.    
    57.         cam1.gameObject.SetActive(cam1Active);
    58.         cam2.gameObject.SetActive(true);
    59.         AudioListener listener = cam2.GetComponent<AudioListener>();
    60.    
    61.         if (listener)
    62.         {
    63.             _reEnableListener = listener.enabled? true : false;
    64.             listener.enabled = false;
    65.         }
    66.     }
    67.  
    68.     void CameraCleanup ( Camera cam1, Camera cam2 )
    69.     {
    70.         AudioListener listener = cam2.GetComponent<AudioListener>();
    71.         if (listener && _reEnableListener) {
    72.             listener.enabled = true;
    73.         }
    74.         cam1.gameObject.SetActive(false);
    75.         this.enabled = false;
    76.     }
    77.  
    78.     public IEnumerator CrossFade (Camera cam1, Camera cam2, float time, RawImage canvasImage, CanvasGroup canvasGroup)
    79.     {
    80.         yield return CrossFade(cam1, cam2, time, canvasImage, canvasGroup, null);
    81.     }
    82.  
    83.     public IEnumerator CrossFade ( Camera cam1, Camera cam2, float time, RawImage canvasImage, CanvasGroup canvasGroup, AnimationCurve curve)
    84.     {
    85.  
    86.         if (!_renderTex)
    87.         {
    88.             _renderTex = new RenderTexture(Screen.width, Screen.height, 24);
    89.         }
    90.  
    91.         cam1.targetTexture = _renderTex;
    92.         _tex = _renderTex;
    93.         _curve = curve;
    94.         canvasImage.texture = _tex;
    95.         _canvasGroup = canvasGroup;
    96.         _canvasGroup.gameObject.SetActive(true);
    97.         CameraSetup (cam1, cam2, true, true);
    98.    
    99.         yield return StartCoroutine(AlphaTimer(time));
    100.  
    101.         _canvasGroup.gameObject.SetActive(false);
    102.         cam1.targetTexture = null;
    103.         _renderTex.Release();
    104.         CameraCleanup (cam1, cam2);
    105.     }
    106.  
    107. }
     
    Last edited: Feb 26, 2018