Optimize my script

Hi, sometimes i think i write my code not in the right way.
For example, i want one of the object to appear slowly:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectAppear : MonoBehaviour {
    private float Alpha;


    // Use this for initialization
    void Start () {
        Alpha = 0;
       

    }
   
    // Update is called once per frame
    void Update () {
        GetComponent<SpriteRenderer>().color = new Color(1, 1, 1, Alpha);
        if(Alpha < 1)
        {
            Alpha += 0.9f * Time.deltaTime;
        }
     
    }
}

So this is the code and its working, But the thing is the code keep repeating himself.
There is any other way to prevent that code from repeating? Any function that destroy the script and not the object.
Thanks!

Don’t use “GetComponent” every frame, cache it in Awake and then reference to it.
You can simply use Destroy(this); to remove just script if you won’t use it again…

My script would probably look something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectAppear : MonoBehaviour
{
    // Alpha to start with
    private float Alpha = 0;

    // Reference to our SpriteRenderer, fetched once with GetComponent in Awake
    private SpriteRenderer spriteRenderer;

    // bool so this script knows if it still needs to update the alpha of the sprite
    private bool isTransitioningAlpha = true;

    void Awake()
    {
        // Get the SpriteRenderer attached to this GameObject
        spriteRenderer = GetComponent<SpriteRenderer>();

        if(spriteRenderer == null)
            Debug.LogError("GameObject does not have a SpriteRenderer component!", this);
    }

    void Update ()
    {
        // If we are at max alpha, we do not need to continue to assign a new Color.
        // Its not changing
        if(isTransitioningAlpha == false)
            return;

        // Alpha is not max yet, increment it some amount and assign it to the spriterenderer
        if(Alpha < 1)
        {
            Alpha += 0.9f * Time.deltaTime;
            spriteRenderer.color = new Color(1, 1, 1, Alpha);
        }
        else
        {
            // Alpha is greater than or equal to 1. Transition is finished
            isTransitioningAlpha = false;

            // ALTERNATIVELY:
            // This could be where you destroy this component. Which would probably be better.
        }    
    }
}

This is so we are not continually assigning a new color to the spriterenderer unless the alpha has changed

1 Like

And just to be contrary, mine would look like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpriteVisibility : MonoBehaviour
{
    public enum Visibility
    {
        Opaque,
        Transparent
    };

    [SerializeField]
    [Range(.01f, 10f)]
    private float _transitionTime = 1f;

    [SerializeField]
    private bool _automaticStart = true;

    [SerializeField]
    private Visibility _startingVisibility = Visibility.Opaque;

    [SerializeField]
    private Visibility _targetVisibility = Visibility.Transparent;


    private bool _transitioning;
    private float _currentAlpha;
    private float _targetAlpha;
    private SpriteRenderer _spriteRenderer;


    private void Awake()
    {
        _spriteRenderer = GetComponent<SpriteRenderer>();

        _currentAlpha = _startingVisibility == Visibility.Opaque ? 1f : 0f;
        _spriteRenderer.color = new Color(_spriteRenderer.color.r, _spriteRenderer.color.g, _spriteRenderer.color.b, _currentAlpha);
    }

    private void Start()
    {
        if (_automaticStart && !_transitioning && _targetVisibility != _startingVisibility)
            StartCoroutine(Transition());
    }


    public void ChangeVisibility(Visibility newVisibility, float transitionTime)
    {
        if (_transitionTime > 0f)
            _transitionTime = transitionTime;

        ChangeVisibility(newVisibility);
    }

    public void ChangeVisibility(Visibility newVisibility)
    {
        if (_targetVisibility != newVisibility)
        {
            _targetVisibility = newVisibility;

            if (!_transitioning)
                StartCoroutine(Transition());
        }
    }

    private IEnumerator Transition()
    {
        _transitioning = true;

        _targetAlpha = _targetVisibility == Visibility.Opaque ? 1 : 0;
        _currentAlpha = _spriteRenderer.color.a;

        while (_currentAlpha != _targetAlpha)
        {
            yield return null;

            _targetAlpha = _targetVisibility == Visibility.Opaque ? 1 : 0;
            _currentAlpha = Mathf.MoveTowards(_currentAlpha, _targetAlpha, Time.deltaTime / _transitionTime);

            _spriteRenderer.color = new Color(_spriteRenderer.color.r, _spriteRenderer.color.g, _spriteRenderer.color.b, _currentAlpha);
        }
        _transitioning = false;
    }
}
1 Like

Why the boolean at all? It’s redundant. :stuck_out_tongue:

When it reaches your target alpha, you could set enabled to false. Just another option.

1 Like

I think the answer was to use IEnumerator ?
I just want my game to run faster, i need to avoid all those codes that i dont need.
I needed the Function just once, but as you see the script ask the question again and again until the object destroyed.
What i wanted is to remove just the Script Component.
Destroy(this) is destroying also the object no?

Edit:
this was the answer

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectAppear : MonoBehaviour {
    private float Alpha;


    // Use this for initialization
    void Start () {
        Alpha = 0;
       

    }
   
    // Update is called once per frame
    void Update () {
        GetComponent<SpriteRenderer>().color = new Color(1, 1, 1, Alpha);
        if (Alpha < 1)
        {
            Alpha += 0.9f * Time.deltaTime;
        }
        else Destroy(GetComponent<ObjectAppear>());
    }
}

Nope. ‘this’ refers to the script instance, so only that will get Destroyed. Destroy(gameObject) is what destroys the GameObject the script is attached to.

Nope, it’s “this” - script, If you would destroy gameobject u would write Destroy((this.)gameObject);

I get the impression your guessing… don’t guess. Find out what elements are causing any slow down you have, then work on those elements. Since this is a really simple script I doubt it causing you that much bother.

https://docs.unity3d.com/Manual/ProfilerWindow.html
https://unity3d.com/learn/tutorials/temas/performance-optimization/profiler-window

1 Like

Of course not, it was an example.

You are still calling GetComponent every frame, dont. Call it once in Awake and cache it. This is the single most intense part in the script. (Relative of course, theres not a lot else going on)