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

Bug GetOrAddComponent return null, Unity 2022.3.6f1

Discussion in 'Scripting' started by Magnilum, Sep 17, 2023.

  1. Magnilum

    Magnilum

    Joined:
    Jul 1, 2019
    Posts:
    143
    Hello,

    I am trying to get a component from a game object and if it does not exist so create it. To do so, I am using the GetOrAddComponent method but it returns a null value:

    Code (CSharp):
    1. gameObject.GetOrAddComponent<MeshFilter>().sharedMesh = mesh;
    I have a null instance error.

    Code (CSharp):
    1. Debug.Log(gameObject.GetOrAddComponent<MeshFilter>());
    2.  
    3. // Debug:
    4. // Null
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    This does not seem to be an official Unity API method according to the scripting manual for 2022.3.
    I did write a method with that exact name as an extension method for my own purposes. So I assume yours is also an extension method but one with a bug.

    Check the code for that method, the IDE should have something like "Go to Definition" when you right-click on the method name. Feel free to post the method here if you don't see any issues with it.
     
    SisusCo likes this.
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    I've seen this exact extension method name in a few modding API's when modding Unity games, namely Subnautica. Are you modding games here?

    If so you should talk to the communities behind these API's.
     
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    To be fair, this extension method exists probably countless of times. Here's one gist :) I think I even made a similar one some time ago. Though since we don't know what implementation he's actually dealing with it just makes things more complicated. So maybe this extension method has some issues or it's a timing issue. For example destroying an old MeshFilter instance and using that method within the same frame might return that dead instance. It's hard to tell without more information.
     
  5. Magnilum

    Magnilum

    Joined:
    Jul 1, 2019
    Posts:
    143
    Hello thank you for your answers.

    Here is the code of the method:

    Code (CSharp):
    1. public static T GetOrAddComponent<T>(this UnityObject uo) where T : Component
    2. {
    3.     return uo.GetComponent<T>() ?? uo.AddComponent<T>();
    4. }
    This is taking part of the following file:

    upload_2023-9-17_15-59-27.png

    I did my own function too:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.VisualScripting;
    3.  
    4. public static class ObjectExtensions {
    5.  
    6.     public static T GetComponentOrAdd<T>(this Object obj) where T : Component
    7.     {
    8.         T component = obj.GetComponent<T>();
    9.         if (component != null)
    10.             return component;
    11.         else
    12.             return obj.AddComponent<T>();
    13.     }
    14. }
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    Well, this wrong implementation IS the actual issue. Where do you got that from? This doesn't work when testing in the editor because GetComponent will return a fake null object in case the component doesn't exist. Fake null objects are not true null therefore the ?? operator can't detect it. However Unity's overloaded == operator could. Though in this case it makes much more sense to use TryGetComponent.

    This should work:
    Code (CSharp):
    1.     return uo.TryGetComponent(out T val)?val:uo.AddComponent<T>();