Good evening. 1) I want to load texture via UnityWebRequestTexture 2) Add texture to variable 3) Use texture from other scripts What am I doing. I have a LoaderTextures script a texture loader with url In this script, I load the texture Сoncrete_1.png and add the value to the public variable Сoncrete Code (CSharp): using UnityEngine; using System.Collections; using UnityEngine.Networking; public class LoaderTextures : MonoBehaviour { public Texture concrete; void Start() { StartCoroutine(LoadTexture()); } IEnumerator LoadTexture() { using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture("file:///C:/Games/Textures/Concrete_1.png")) { yield return uwr.SendWebRequest(); if(uwr.isNetworkError || uwr.isHttpError) { Debug.Log(uwr.error); } else { concrete = DownloadHandlerTexture.GetContent(uwr); } } } } Next, from another script, I refer to the concrete variable and it gives me null Code (CSharp): using UnityEngine; using System.Collections; public class LoaderObjects : MonoBehaviour { private LoaderTextures tex; void Start() { tex= GameObject.Find("LoaderTextures").GetComponent<LoaderTextures>(); Debug.Log(tex.сoncrete); } } How can I load a texture and then use it in a scene? In the inspector, the concrete variable has a value with a loaded texture, but I can't take it, what am I doing wrong
First thing I would investigate is that URL. Give it a "normal" URL out on the internet somewhere, or just use a local http server and load it. We know that texture loading works (see examples in UnityWebRequest docs) so start with a "normal" URL and then work up to whether Windows will even know how to handle all that file:///c:/ magic. That URL might be correct, but it might not. Isolate if what you're seeing is the mechanism, or just the bad URL.
There is an example of how to use UnityWebrequestTexture here: https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequestTexture.GetTexture.html Note that this is a network request, which is why the example is starting a coroutine which waits for the image to be downloaded from the URL. It will not be available immediately. I notice you are trying to read the texture from Start() in another script. The issue is that you aren't waiting for the texture to finish downloading and be assigned. So most likely, it is simply not ready yet. A couple ways to deal with this off the top of my head: Keep checking if the texture is loaded each frame in Update Have your LoaderTextures class expose a C# event to notify other classes when the texture is finished loading.
Coroutine runs during Update, so if both scripts are in the same scene and both are enabled, the texture will be null during Start.
I understood you, yesterday I tried for a long time options on how this can be done, everything worked out for me thanks to your help. But now I decided to combine 3 scripts together in one file to optimize the process. I have 3 IEnumerators. How can I make it so that LoadTexture () is executed first; then LoaderNormal (); and LoaderObject (); 1) LoadTexture (); // Done completely goes to LoaderNormal (); 2) LoaderNormal (); // Done completely jumps to LoaderObject (); 3) LoaderObject (); Code (CSharp): void Start() { StartCoroutine(LoadTexture();// Done completely goes to LoaderNormal (); StartCoroutine(LoaderNormal();// Done completely jumps to LoaderObject (); StartCoroutine(LoaderObject(); } IEnumerator LoadTexture() { Debug.Log(0); } IEnumerator LoaderNormal() { Debug.Log(1); } IEnumerator LoaderObject() { Debug.Log(2); } I am not very good at C # and its features as it is not my native language, but I can read it. I really like Unity3D, I am learning more and more and it is very exciting. For the code with an example in C #, I would like to separately thank you.
The way you wrote you ask them to execute at the same time. If you want LoaderNormal to execute after LoadTexture, then put StartCoroutine(LoaderNormal()); into LoadTexture() at the point where texture is already loaded. Solve the third one likewise.
I am very sorry to Aurimas-Cernius that this does not work for me I very carelessly wrote the code, cutting down all the unnecessary previously written by me. I didn't think that for(); will be important. Here's a sample code where it doesn't work as expected. It won't be right. There will be repetitions Code (CSharp): private string[] nameTexture = {"Texture_1","Texture_2"}; private string[] nameNormal = {"Normal_1","Normal_2"}; private string[] nameObject = {"Object_1","Object_2"}; void Start() { for(int i = 0; i < nameTexture.Length; i++) { StartCoroutine(LoadTexture(nameTexture[i])); } for(int i = 0; i < nameNormal.Length; i++) { StartCoroutine(LoaderNormal(nameNormal[i])); } for(int i = 0; i < nameObject.Length; i++) { StartCoroutine(LoaderObject(nameObject[i])); } }
This code create a lot of coroutines which then all run at the same time. Like I said, your Start should only start coroutines which have no dependencies. The dependencies have to started from inside the coroutines when everything is already loaded.
The point is that if I put LoadTexture in nameNormal. LoadTexture will be executed twice as there are 2 values in the nameNormal array Code (CSharp): private string[] nameTexture = {"Texture_1","Texture_2"}; private string[] nameNormal = {"Normal_1","Normal_2"}; private string[] nameObject = {"Object_1","Object_2"}; void Start() { for(int i = 0; i < nameTexture.Length; i++) { StartCoroutine(LoadTexture(nameTexture[i])); } } IEnumerator LoadTexture(string nameTexture) { // First run code nameTexture for(int i = 0; i < nameNormal.Length; i++) { StartCoroutine(LoaderNormal(nameNormal[i])); } } IEnumerator LoaderNormal(string nameObject) { // Second run code nameNormal for(int i = 0; i < nameObject.Length; i++) { StartCoroutine(LoaderObject(nameObject[i])); } } IEnumerator LoaderObject(string nameObject) { // Third execution code nameObject }