Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to Cache GetComponent in C#

Discussion in 'Scripting' started by LandonF, Aug 5, 2016.

  1. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    I'm trying to avoid putting a GetComponent in my update function, so I don't have to hog up the memory. I keep getting the error "A field initializer cannot reference the nonstatic field, method, or property" please help me find a way on how to do this, thank you.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraTransition : MonoBehaviour
    5. {
    6.  
    7.     public Transform Lerposa;
    8.     public Transform Lerposb;
    9.     public Transform cameraanim;
    10.     public Transform fadeObj;
    11.    
    12.  
    13.     void Start ()
    14.     {
    15.  
    16.         public float fadeAlpha = fadeObj.GetComponent<Renderer>().material.a;
    17.     }
     
  2. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    create a handle: private Render _render;

    Assign the handle to the component in void Start()

    _render = fadeObj.GetComponent<Renderer>();

    _render.material.color = new Color()
     
  3. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    It's now giving me an error saying "The type or namespace "Render" could not be found"

    Code (CSharp):
    1.     public Transform Lerposa;
    2.     public Transform Lerposb;
    3.     public Transform cameraanim;
    4.     public Transform fadeObj;
    5.     private Render _render;
    6.  
    7.  
    8.     void Start ()
    9.     {
    10.         _render = fadeObj.GetComponent<Renderer>();
    11.     }
     
  4. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,381
    What is a Renderer component? You probably want a MeshRenderer component or something.

    To cache the component in a local variable, you'll do this:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraTransition : MonoBehaviour
    5. {
    6.     public Transform Lerposa;
    7.     public Transform Lerposb;
    8.     public Transform cameraanim;
    9.     public Transform fadeObj;
    10.  
    11.     private Renderer _cachedComponent;
    12.     private float _fadeAlpha;
    13.  
    14.     void Start()
    15.     {
    16.         _cachedComponent = fadeObj.GetComponent<Renderer>(); // Get and store the component one time.
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         _fadeAlpha = _cachedComponent.material.color.a; // Reuse it here in update, but without having to GetComponent again.
    22.     }
    23. }
    You have some syntax errors. Do you have a basic grasp on C# and Unity? Make sure you understand what you are trying to code up instead of working aimlessly.
     
  5. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Sorry. Typo.

    Private Renderer _render
     
  6. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    same thing bruh.
     
  7. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,381
    Read my post instead of blindly copy-pasting.
     
  8. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    Odd... Now it's saying "Cannot modify the return value of 'Material.color' because it is not a variable"


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraTransition : MonoBehaviour
    5. {
    6.  
    7.     public Transform Lerposa;
    8.     public Transform Lerposb;
    9.     public Transform cameraanim;
    10.     public Transform fadeObj;
    11.     private Renderer _render;
    12.  
    13.  
    14.     void Start ()
    15.     {
    16.         _render = fadeObj.GetComponent<Renderer>();
    17.     }
    18.  
    19.  
    20.  
    21.     void Update ()
    22.     {
    23.  
    24.           if (!cameraanim.gameObject.GetComponent<Animation>().IsPlaying("wobble"))
    25.           {
    26.             _render.material.color.a += 0.1f;
    27.           }
     
  9. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    If i use..
    Code (CSharp):
    1.         if (fadeObj.GetComponent<Renderer>().material.color.a == 1)
    2.           {
    3.               transform.position = Vector3.Lerp(Lerposa.position, Lerposb.position, 0.1f);
    4.               Lerposb.gameObject.SetActive(true);
    5.           }
    it works.
     
  10. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    "_render.material.color.a+= 0.1f;"

    C# doesn't let you modify a value like that. It requires a temp variable or this:

    _render.material.color = new Color(R, G, B, A(0.1f));


    I have a youtube video on GetComponent. I suggest checking it out.
     
  11. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    Ohhh ok sorry, was going off of a tutorial meant for UnityScript.
    How would I do something like this..
    Code (CSharp):
    1. _render.material.color.a += 0.1f * Time.deltaTime;
    In C#?
     
  12. LandonF

    LandonF

    Joined:
    Mar 1, 2016
    Posts:
    34
    Actually, I'll just look it up. Thanks for all of your help! :D
     
  13. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Code (CSharp):
    1. var renderer = GetComponent<Renderer>();
    2.         var material = renderer.material;
    3.         var color = material.GetColor(materialColorName);
    4.         color.a += 0.1f * Time.deltaTime;
    5.         material.SetColor(materialColorName, color);
    6.         renderer.sharedMaterial = material;
     
  14. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Yuck....

    Color newColor = _render.material.color;
    newColor.a = 0.1f * Time.deltaTime;
    _render.material.color = newColor;
     
  15. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You reference .material which creates a new material instance and then assign that instance back to shared material. Have to agree with @SubZeroGaming that this is hardly ideal.
     
    SubZeroGaming and Timelog like this.