targetTransparency

Hi all,

When we return targetTransparency and startValue from the CoRoutine, I don’t see where in the code these are defined.
The other two items the CoRoutine is returning (spriteRenderer and fadeTime) are defined in the code, and I was curious about this seeming inconsistency. Does Unity already “know” what startValue and targetTransparency are?

Thanks!

The code attached for those reading without context:

public class TransparentDetection : MonoBehaviour
{
    [Range(0,1)]
    [SerializeField] private float transparencyAmount = 0.8f;
    [SerializeField] private float fadeTime = 0.4f;

    private SpriteRenderer spriteRenderer;
    private Tilemap tileMap;

    private void Awake()
    {
       spriteRenderer = GetComponent<SpriteRenderer>();
       tileMap = GetComponent<Tilemap>();
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.GetComponent<PlayerController>())
        {
            if (spriteRenderer)
            {
                StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, transparencyAmount));
            }
            else if (tileMap)
            {
                StartCoroutine(FadeRoutine(tileMap, fadeTime, tileMap.color.a, transparencyAmount));
            }

        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.GetComponent <PlayerController>())
            if (spriteRenderer)     
                {
            StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, 1f));
                }
            else if (tileMap)
            {
                StartCoroutine(FadeRoutine(tileMap, fadeTime, tileMap.color.a, 1f));
            }
        
    }

    private IEnumerator FadeRoutine(SpriteRenderer spriteRenderer, float fadeTime, float startValue, float targetTransparency)
    {
        float elapsedTime = 0;
        while (elapsedTime < fadeTime)
        {
            elapsedTime += Time.deltaTime;
            float newAlpha = Mathf.Lerp(startValue, targetTransparency, elapsedTime / fadeTime);
            spriteRenderer.color = new Color(spriteRenderer.color.r, spriteRenderer.color.g, spriteRenderer.color.b, newAlpha);
            yield return null;
        }
    }

    private IEnumerator FadeRoutine(Tilemap tileMap, float fadeTime, float startValue, float targetTransparency)
    {
        float elapsedTime = 0;
        while (elapsedTime < fadeTime)
        {
            elapsedTime += Time.deltaTime;
            float newAlpha = Mathf.Lerp(startValue, targetTransparency, elapsedTime / fadeTime);
            tileMap.color = new Color(tileMap.color.r, tileMap.color.g, tileMap.color.b, newAlpha);
            yield return null;
        }
    }
}

You’re not returning anything from the CoRoutine, you’re passing the arguments into it.

When you declare your CoRoutine method you also declare the variables that you want it to take in

private IEnumerator FadeRoutine(SpriteRenderer spriteRenderer, float fadeTime, float startValue, float targetTransparency)

in this case you want it to take in four arguments and then do something with them inside the CoRoutine.

When you call the CoRoutine method earlier in your code you entered these parameters.

StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, transparencyAmount));

It’s a bit confusing since you named the SpriteRenderer in your TransparentDetection class spriteRenderer
and then you named it the same thing in the CoRoutine declaration

 private SpriteRenderer spriteRenderer;

and

 private IEnumerator FadeRoutine(SpriteRenderer spriteRenderer...

are not the same variable, but they share the same name and type.
So when you pass in the spriteRenderer variable in

StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, 1f));

you’re using a variable of the same name as the CoRoutine method is expecting but you’re actually passing in the variable declared at the top your your class, however what’s important is the Data Type not the variable name.

You don’t have a separately declared variable for startValue in your TransparentDetection class, you’re passing it in from the spriteRenderer variable that you declared but you do have a variable declared for transparencyAmount which you then pass into the targetTransparency field.

Perhaps changing

private IEnumerator FadeRoutine(SpriteRenderer spriteRenderer, float fadeTime, float startValue, float targetTransparency)

to

private IEnumerator FadeRoutine(SpriteRenderer renderer, float fadeTime, float startValue, float targetTransparency)

would help? All you care about is that a SpriteRendrer type makes it’s way into the first argument in your CoRoutine, it doesn’t matter what its label is in either the CoRoutine declaration or in your class.


To clarify about returning,
we return values from methods by using return and the method can only return one type of value, the one it’s been declared as.
for example

[SerializeField] int valueOfB;
int a = 20;
int c;

public int ClaculateAB(int b)
{
     return a*b;
}

void Start()
{
    c = CalculateAB(valueOfB)
}

In this case we have a method that’s declared as an int which calculated the value of a times b, a being a variable declared in our class while b being an argument taken in by the method.
When we call the method in Start() we assign the outcome of a*b to c but notice that b in this case is a variable declared in our class as valueOfB that we can change on the fly. We’re passing it into the method to act as b.

Because the method is declared as an int it can only return an int, it cannot return anything else.

I’m not completely familiar with CoRoutines yet but by programming logic, it should be impossible for a CoRoutine to return anything other then IEnumarator since the method is declared as an IEnumerator.


I hope this helps, but if it’s too confusing let me know and I’ll try to explain it better.

@Geth

This is the second post of mine that you’ve replied to with very helpful information, and I really appreciate it.

I think I understand what you are saying mostly. What I’m still wondering is where targetTransparency gets its information. Is it a property of the Unity SpriteRenderer, as well as startValue? Or is it implied in the code in a way I’m not seeing?

In your OnTriggerEnter2D when you call the FadeRoutine() the targetTransparency gets its value from transparencyAmount which is a variable you declared at the top of your class. It’s being set to 0.8f

StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, transparencyAmount));
//                                                                              ^^^^^^^^^^^^

In OnTriggerExit2d you hardcoded that value to be 1f

StartCoroutine(FadeRoutine(spriteRenderer, fadeTime, spriteRenderer.color.a, 1f));
//                                                                          ^^^^

The fact that you’re asking this makes me not convinced you actually understand tbh.

I did come up with what I think is a pretty good analogy when thinking about how to best explain this but I’m not sure I should use it since it’s almost insulting.

Don’t worry about insulting analogies. I’ve got pretty thick skin when I’m trying to learn something :slight_smile:

So when we declare “transparencyAmount” at the top of the class, we are not bound to only use the word “Amount” when addressing transparency? When we declare transparencyAmount, that enables transparency to also be a “target” as well as an “amount”?

Yeah, you still don’t understand… :sweat_smile:
We don’t care about what the name is in either declaration we only care about the Data Type, which is float

Here comes the borderline insulting analogy, we’re going back to baby days.
Take a look at this picture:

Summary

The box represents our method, the cutouts are the arguments it can take in, the blocks are different variables and the shapes are different Data Types.
Now we can name the box whatever we want, and we can name the holes and the blocks what we want, but ultimately all we care about is that the shapes match.

If we assume that a circle is type SpriteRenderer and triangle is type float your CoRoutine method would look something like this:

Summary

It doesn’t matter what the blocks are called or what color they are, so long as the shapes match they will go into the box.
You could put in any float type value or variable in those fields and it will still accept it, though you’d not get the desired result if you put in a value that doen’t make sense.
Similarly, it doesn’t matter what the holes are named, you could name them a,b,c,d and they would still function the same, as holes. The names are there just for us to understand what kind of value you should put it.

So if your Corutine looked like this:

private IEnumerator FadeRoutine(SpriteRenderer a, float b, float c, float d)
    {
        float elapsedTime = 0;
        while (elapsedTime < b)
        {
            elapsedTime += Time.deltaTime;
            float newAlpha = Mathf.Lerp(c, d, elapsedTime / b);
            a.color = new Color(a.color.r, a.color.g, a.color.b, newAlpha);
            yield return null;
        }
    }

it would function exactly the same, but it would be more confusing for us to see what it does.

There is no link between transparencyAmount and targetTransparency

The shape sorter is the gift that keeps on giving throughout life!

Thank you Geth, your explanations are really helpful. Thanks for taking the time (and for photoshopping an extra hole on the shape sorter)!

1 Like

Glad I could help. Ironically enough this is a concept I also struggled with when I first started programming but it’s so essential that I really wanted to make sure it clicked for you.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms