using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FadeInOutSaveGameText : MonoBehaviour
{
public Animator animator;
// Start is called before the first frame update
void Start()
{
}
public void FadeOut()
{
animator.SetTrigger("FadeOut");
}
public void FadeIn()
{
animator.SetTrigger("FadeIn");
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.I))
{
FadeOut();
}
if (Input.GetKeyDown(KeyCode.O))
{
FadeIn();
}
}
public void FadeOutMessage(string message)
{
if(message == "FadeInEnded")
{
//FadeOut();
}
}
public void FadeInMessage(string message)
{
if(message == "FadeOutEnded")
{
//FadeIn();
}
}
public IEnumerator canvasAlphaOverTime(Canvas canvas, float duration)
{
float counter = 0;
var alphaColor = canvas.GetComponent<CanvasGroup>().alpha;
while (counter < duration)
{
counter += Time.deltaTime;
alphaColor = Vector3.Lerp(/* FadeOut, FadeIn*/, counter / duration);
yield return null;
}
}
}
In the canvasAlphaOverTime I want to change the alphaColor from 0 to 1 then back to 0 and then to 1 again make ping pong between 0 and 1 slowly smooth with speed.
The duration is how many time it will make the ping pong !
For example if the duration is 5 seconds then make ping pong between 1 and 0 and 0 and 1 for 5 seconds.
After 5 seconds stop the transition between 1 and 0.
The idea is that I give it a duration and it will ping pong make transition between 1 and 0 nonstop and after 5 seconds the transition will stop.
So I have a problem to complete and make the line :
This is more or less what I wanted, It’s working in general but there are things to fix/add/change :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FadeInOutSaveGameText : MonoBehaviour
{
public Animator animator;
public Canvas canvas;
public float fadingSpeed;
private bool stopFading = false;
// Start is called before the first frame update
void Start()
{
StartCoroutine(OverAllTime(5f));
}
IEnumerator CanvasAlphaChangeOverTime(Canvas canvas, float duration)
{
var alphaColor = canvas.GetComponent<CanvasGroup>().alpha;
while (true)
{
alphaColor = (Mathf.Sin(Time.time * duration) + 1.0f) / 2.0f;
canvas.GetComponent<CanvasGroup>().alpha = alphaColor;
if(stopFading == true)
{
break;
}
yield return null;
}
}
IEnumerator OverAllTime(float time)
{
StartCoroutine(CanvasAlphaChangeOverTime(canvas, fadingSpeed));
yield return new WaitForSeconds(time);
stopFading = true;
StopCoroutine("CanvasAlphaChangeOverTime");
}
}
Things to fix/change :
Does the line StopCoroutine really work ? If I’m not using the helper flag and make break; inside the loop then the fading weill never stop.
Should I use a helper flag and break; only or also StopCoroutine ?
When the CanvasAlphaChangeOverTime Coroutine stop then the fading also stop at the same point it is. but I want it to finish fading first depending on the fading direction. If it was changing to the 0 then first finish fading to 0 then stop the Coroutine and same if it was more then 0.5 changing to the 1 then first finish changing to 1 then stop the Coroutine.
Things to add :
An option to change the fadingSpeed in real time while the fading is working ? How to do it ?
I never use coroutines for fade in /out. Too big a chance of tangling yourself, having to rely on Stop Coroutine, getting two going at once, etc. Edge case nightmare.
Instead, keep two variables:
current fade alpha
desired fade alpha
Every update, if they are different, move the current towards the desired, usually with a small amount multiplied by Time.deltaTime.
Use the current to set the fade out graphics, whatever those are.
NOW… when you want to fade out, set the desired fade alpha to 1, when it’s time to fade in, set it to 0.
No way no matter how many different places all over your code say fade/unfade, whatever, as long as the last one is what you want, then the fading just happens. No coroutines, no statefullness, no edge cases, etc.
I tried this but the problem is that the transition from 0 to 1 or 1 to 0 is not smooth.
It’s just changing to 0 for example then jump to 1 and again change to 0 slowly but it’s jumping to the other value it’s not making smooth transition between the two values.
What’s wrong with this ? If the start alpha is 0 then it’s moving slowly to 1 but then from 1 it’s jumping nack to 0 and not moving slowly from 1 to 0 same if the start alpha is 1.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FadeInOutSaveGameText : MonoBehaviour
{
public Canvas canvas;
public float fadeDuration = 5;
private float maxAlpha = 1;
private float lerpParam;
private float startAlpha;
private float canvasGroupAlpha;
void Start()
{
canvasGroupAlpha = canvas.GetComponent<CanvasGroup>().alpha;
startAlpha = canvas.GetComponent<CanvasGroup>().alpha;
}
void Update()
{
lerpParam += Time.deltaTime;
canvasGroupAlpha = Mathf.Lerp(startAlpha, maxAlpha, lerpParam / fadeDuration);
canvas.GetComponent<CanvasGroup>().alpha = canvasGroupAlpha;
if (canvasGroupAlpha >= 1)
{
FadeTo(0);
}
if (canvasGroupAlpha <= 0)
{
FadeTo(1);
}
}
public void FadeTo(float alpha)
{
maxAlpha = alpha;
lerpParam = 0;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Helper class to fade a canvas group for forum.unity.com by Zer0Cool
/// - assign this script for instance to the gameobject that holds the canvas
/// - assign canvas object to this script (if not set it uses the canvas on the same gameobject)
/// - attach a canvas group to the gameobject that holds the canvas in your scene
/// - set the animation curve to what you want (if not set it will use a default curve)
/// - set a fading speed
/// - choose which coroutine to execute (line 33)
/// </summary>
public class FadeEffect : MonoBehaviour
{
public Canvas canvas;
public AnimationCurve animationCurve;
public float fadingSpeed = 5f;
public enum Direction { FadeIn, FadeOut};
void Start()
{
if (canvas == null) canvas = GetComponent<Canvas>();
CanvasGroup canvasGroup = canvas.GetComponent<CanvasGroup>();
if (canvasGroup == null) Debug.LogError("Please assign a canvas group to the canvas!");
if (animationCurve.length == 0)
{
Debug.Log("Animation curve not assigned: Create a default animation curve");
animationCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
}
StartCoroutine(FadeCanvas(canvasGroup, Direction.FadeIn, fadingSpeed));
//StartCoroutine(FadeCanvas(canvasGroup, Direction.FadeOut, fadingSpeed));
}
public IEnumerator FadeCanvas(CanvasGroup canvasGroup, Direction direction, float duration)
{
// keep track of when the fading started, when it should finish, and how long it has been running
var startTime = Time.time;
var endTime = Time.time + duration;
var elapsedTime = 0f;
// set the canvas to the start alpha – this ensures that the canvas is ‘reset’ if you fade it multiple times
if (direction == Direction.FadeIn) canvasGroup.alpha = animationCurve.Evaluate(0f);
else canvasGroup.alpha = animationCurve.Evaluate(1f);
// loop repeatedly until the previously calculated end time
while (Time.time <= endTime)
{
elapsedTime = Time.time - startTime; // update the elapsed time
var percentage = 1 / (duration / elapsedTime); // calculate how far along the timeline we are
if ((direction == Direction.FadeOut)) // if we are fading out
{
canvasGroup.alpha = animationCurve.Evaluate(1f - percentage);
}
else // if we are fading in/up
{
canvasGroup.alpha = animationCurve.Evaluate(percentage);
}
yield return new WaitForEndOfFrame(); // wait for the next frame before continuing the loop
}
// force the alpha to the end alpha before finishing – this is here to mitigate any rounding errors, e.g. leaving the alpha at 0.01 instead of 0
if (direction == Direction.FadeIn) canvasGroup.alpha = animationCurve.Evaluate(1f);
else canvasGroup.alpha = animationCurve.Evaluate(0f);
}
}