Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by fmielke · Nov 09, 2016 at 08:30 AM · c#gameobjectspritewww

NullReferenceException UnityEngine.MonoBehaviour.StartCoroutine

Hello,

I want to change the Sprite of a GameObject via C# script. The picture URL I get successfully from a REST API Call. With WWW I want to create the new Sprite for the GameObject. But now I don't have no idea what i am doing wrong. I read to solve the problem by using https://docs.unity3d.com/ScriptReference/GameObject.AddComponent.html but how in detail?

This is the OnClick event script of a button:

     ApiClient apiclient = new ApiClient();
     string imageurl = apiclient.callSearchApiWithCSharp(realEstateType, preisText.text, zimmerText.text);
     Debug.Log(imageurl);
     apiclient.loadPic(imageurl);


methods to get the picture and create a sprite of it:

 public void loadPic(string url)
 {
     WWW www = new WWW(url);
     StartCoroutine(WaitForRequest(www));
 }

 IEnumerator WaitForRequest(WWW www)
 {
     yield return www;

     // check for errors
     if (www.error == null)
     {
         Debug.Log("WWW Ok!: " + www.text);
         image.GetComponent<Image>().overrideSprite = Sprite.Create(www.texture, new Rect(0, 0, 438, 441), new Vector2(0.5f, 0.5f));
     }
     else
     {
         Debug.Log("WWW Error: " + www.error);
     }
 }

Output is:

 https://s@sandboxpicis24-a.akamaihd.net/pic/orig02/L/106/539/941/106539941-0.png

 NullReferenceException
 UnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineMonoBehaviourBindings.gen.cs:61)
 ApiClient.loadPic (System.String url) (at Assets/ApiClient.cs:89)
 ObjectTypeListener.callObjectType () (at Assets/ObjectTypeListener.cs:59)
 UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153)
 UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:634)
 UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:769)
 UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
 UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
 UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
 UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
 UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
 UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
 ControllerTrack2:ProcessTrigger(PointerEventData, GameObject) (at Assets/ControllerTrack2.cs:77)
 ControllerTrack2:Process() (at Assets/ControllerTrack2.cs:49)
 UnityEngine.EventSystems.EventSystem:Update()
Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aditya007 · Nov 09, 2016 at 10:08 AM 0
Share

What line of code is your error pointing to?

avatar image fmielke aditya007 · Nov 09, 2016 at 10:22 AM 0
Share

It is pointing to StartCoroutine(WaitForRequest(www));, this is line 89 in my code. But maybe there is a problem with WWW www = new WWW(url);

avatar image aditya007 fmielke · Nov 09, 2016 at 10:26 AM 0
Share

If it 's pointing to StartCoroutine(WaitForRequest(www));, then there's some problem inside WaitForRequest Coroutine. Do you get the debug value from Debug.Log("WWW Ok!: " + www.text);

Show more comments
Show more comments

3 Replies

· Add your reply
  • Sort: 
avatar image
8
Best Answer

Answer by Bunny83 · Nov 09, 2016 at 11:22 AM

Your problem is a common gotcha for Unity beginners. The "reason-chain" for this is:

  • Coroutines are run by the coroutine scheduler and are bound to the MonoBehaviour that has been used to start the coroutine. StartCoroutine is an instance member of MonoBehaviour.

  • All Components must not be created with "new". Components always need to be created with AddComponent. Components can only "live" on GameObjects.

  • Wrongly initialized Components (i.e. created with "new") will turn into "fake null objects".

"Fake null objects" are true C# managed classes but they are lacking the native C++ equivalent in the engine's core. They could still be used as "normal" managed classes, but nothing related to Untiy will work, Furthermore the "UnityEngine.Object" baseclass overloads the == operator and "fakes" that the object is null when it's lacking the native part. That happens when you create a Component class with new or when you Destroy such an object.

So the solution is you have to attach your "ApiClient" component to a GameObject. Unlike Components GameObjects can be created with "new". So you can simply replace

 ApiClient apiclient = new ApiClient();

with

 ApiClient apiclient = (new GameObject("SomeObjName")).AddComponent<ApiClient>();

This will create a new GameObject with the name "SomeObjName" and add your ApiClient component to it.

Keep in mind that the GameObject (and it's components) will now be present in the scene until you destroy it.

As alternative you could attach your ApiClient component to the same gameobject that the calling script is attached to by using:

 ApiClient apiclient = gameObject.AddComponent<ApiClient>();

Every component (so MonoBehaviour as well) has the gameObject property which can be used to access the GameObject that this component is attached to.

edit
A quick note on "Destroy". When you destroy a component, only that component will be destroyed and removed. If you call Destroy on a GameObject reference it will destroy the gameobject including all attached components (since they can't exist without GameObject) as well as all child GameObjects of the GameObject.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by sh_code · Nov 09, 2016 at 11:16 AM

my psychic debugging powers are telling me that either your "GameObject image" variable is not set, or it doesn't have Image component attached to it, at the time when this line is called:

 image.GetComponent<Image>().overrideSprite = Sprite.Create(www.texture, new Rect(0, 0, 438, 441), new Vector2(0.5f, 0.5f));

To check if this is the case (as well as automatically handle if it is), replace the line with

 if(image != null){
 Image imgComponent = image.GetComponent<Image>();
 if(imgComponent == null){
    Debug.Log("image object doesn't contain Image component. Adding it.");
    imgComponent = (Image)image.AddComponent<Image>();
  }
 
 imgComponent.overrideSprite = Sprite.Create(www.texture, new Rect(0, 0, 438, 441), new Vector2(0.5f, 0.5f));
 
 } else Debug.Log("image GameObject is not set to anything");


Also "thank you very much", now the word "image" looks and sounds extremely weird to me, after so many repetitions :-D Get back to tell us how the replacement code I gave you behaves.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aditya007 · Nov 09, 2016 at 11:21 AM 0
Share

This "could" be the reason. But i think if this is the reason for NRE then the Debug should've been called, wouldn't it?

avatar image sh_code aditya007 · Nov 09, 2016 at 11:35 AM 0
Share

he's got no nullchecks or debugs in his code, except "if(www.error == null)", so no, there's no Debug in his original code that would be called on any of the objects being null.

my code remedies exactly that, throws debug messages on each point along the way where objects can be null...

...except the ApiClient being null, because, being created with "new", I automatically assumed it's not $$anonymous$$onoBehavior (despite its code in the next snippet in OP suggesting it is)

avatar image aditya007 sh_code · Nov 09, 2016 at 11:44 AM 1
Share

I was talking about this statement Debug.Log("WWW Ok!: " + www.text); which should be called if there's no error in www call. Acc to your suggestion, the image component might be null, that means the NRE has to occur at

  image.GetComponent<Image>().overrideSprite = Sprite.Create(www.texture, new Rect(0, 0, 438, 441), new Vector2(0.5f, 0.5f));

And thus, the Debug call should have been called printing the result from www variable, that's what i'm saying.

Show more comments
avatar image fmielke · Nov 09, 2016 at 08:18 PM 0
Share

Thank you all! The code form @Bunny83 solved the problem, but another occured. I used the code from @sh_code and that helped, too. @aditya007 is also right. :)

But I have to change another thing: my gameobjects were created in the script of loadPic, so the image were alsways null. I put them to the script where apiclient is called and it works!

avatar image
0

Answer by sirshelley · Feb 10, 2021 at 02:46 AM

I've been using unity for 7 + years and this type of behavior sometimes still stumps me.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

WWW loading not working on Windows, working on Mac 1 Answer

Distribute terrain in zones 3 Answers

Assigning a Sprite to a Script and creating a Gameobject out of that sprite 1 Answer

Multiple Cars not working 1 Answer

Unity streching sprite gameobject to fit two positions. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges