Error!!! NullReferenceException: Object reference not set to an instance of an object
Hello everybody! I want to instantiate a button which it change a path. I create this script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.IO;
using VRStandardAssets.Utils;
public class ButtonSelector : MonoBehaviour {
[SerializeField] private VRInteractiveItem m_VRInteractiveitem;
void OnEnable()
{
m_VRInteractiveitem.OnClick += CambiaPath;
}
void OnDisable()
{
m_VRInteractiveitem.OnClick -= CambiaPath;
}
//Cambia il path del textureloader
public void CambiaPath()
{
TextureLoader txtloader = (TextureLoader)this.GetComponent (typeof(TextureLoader));
Debug.Log(txtloader.mLocalStorageDirPath);
txtloader.mLocalStorageDirPath = txtloader.GetOrigin() + "\\" + this.GetComponentInChildren<Text> ().text + "\\";
txtloader.InizioFoto ();
}
}
The problem is when i click the button there is a error written above. what's wrong?
You should always include the line number where the error occurs. Also, we don't know much about the TextureLoader class. However, these could be possible:
The 'txtLoader' variable can not be initialized, because the GetComponent function can not find the TextureLoader component. Are you sure, that the component is on the gameobject?
The 'mLocalStorageDirPath' field of the 'txtLoader' variable can also be null, so the Debug.Log function can not print it.
Last possibilities are the GetOrigin() and the InizioFoto() functions. Since we do not know what this class holds, we can not see more options.
If you could not figure out the problem from this, you should include the line number where the error occurs, and the TextureLoader class.
Answer by Gianluca90 · Jan 16, 2017 at 08:49 AM
I think i've fixed the error but the script don't work fine... now the script is:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.IO;
using VRStandardAssets.Utils;
public class ButtonSelector : MonoBehaviour {
public TextureLoader txtloader;
[SerializeField] private VRInteractiveItem m_VRInteractiveitem;
void OnEnable()
{
m_VRInteractiveitem.OnClick += CambiaPath;
}
void OnDisable()
{
m_VRInteractiveitem.OnClick -= CambiaPath;
}
//Cambia il path del textureloader
public void CambiaPath()
{
Debug.Log(txtloader.mLocalStorageDirPath);
txtloader.mLocalStorageDirPath = txtloader.GetOrigin() + "\\" + this.GetComponentInChildren<Text> ().text + "\\";
txtloader.InizioFoto ();
}
}
TextureLoader class:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class TextureLoader : SingletonMonoBehaviour<TextureLoader> {
public Texture2D[] mStartingTextures = new Texture2D[1];
public string mLocalStorageDirPath = "";
private string origin = "";
private List<string> mTextureFileNames = new List<string>();
private Texture2D mCurrTexture = null;
private int mCurrTextureIndex = 0;
private bool mFinishedFirstTexture = false;
private bool mAndroidEnvironment = false;
void setTextureLoader(string path)
{
this.mLocalStorageDirPath = path;
Start ();
}
void Start ()
{
origin = mLocalStorageDirPath;
InizioFoto ();
}
public string GetOrigin()
{
return origin;
}
// Used to read and load a texture2D from an Android device - from a specific folder.
// mCurrTexture is set to null when the index indicates we want to use default textures; in this case
// we just return the mStartingTexture[mCurrentTextureIndex]. Otherwise, if we are loading a texture from
// the device, mCurrTexture will be set to the texture read.
public IEnumerator LoadTextureAtIndex (int textureIndex, bool firstTime, TextureCycler cyclerToCallback)
{
if (mAndroidEnvironment && !string.IsNullOrEmpty(mLocalStorageDirPath) && System.IO.Directory.Exists (mLocalStorageDirPath) && (textureIndex >= mStartingTextures.Length && textureIndex < (mTextureFileNames.Count + mStartingTextures.Length)))
{
// Append each texture name (as the name appears inside mLocalStoragePath) before each load.
int startingTextureOffset = mStartingTextures == null ? 0 : mStartingTextures.Length;
string currTexturePath = mLocalStorageDirPath + "\\" + mTextureFileNames[textureIndex - startingTextureOffset];
// Add "file:///" to the beginning of the absolute path so the WWW object knows its a file protocol.
WWW textureWWW = new WWW ("file:///" + currTexturePath);
if (textureWWW.error != null)
{
Debug.Log (name + textureWWW.url + " error: " + textureWWW.error);
} else {
// Yield return from the coroutine while the texture is loading.
while(!textureWWW.isDone)
{
yield return null;
}
// Destroy the old texture member variable before creating a new one to save memory.
if(mCurrTexture != null)
{
Texture2D.Destroy(mCurrTexture);
}
// Create a new texture2D and load the WWW contents into it
// Note: this call is blocking on the UI thread, so we fade in and out to mask load times.
mCurrTexture = new Texture2D (4, 4, TextureFormat.DXT1, false);
mCurrTexture.wrapMode = TextureWrapMode.Repeat;
textureWWW.LoadImageIntoTexture (mCurrTexture);
// Clean up the WWW object and call the GC each time we load a texture from device.
// This is to avoid memory allocation issues.
textureWWW.Dispose();
textureWWW = null;
System.GC.Collect();
if(cyclerToCallback != null)
{
cyclerToCallback.applyReadyTexture();
if (ScreenFaderSphere.getInstance ())
{
ScreenFaderSphere.getInstance ().fadeToTransparent ();
}
// Check if this is the first texture loaded, if so set this flag so that
// the texture cycler can know when it's ready.
if(firstTime)
{
mFinishedFirstTexture = true;
}
}
}
}else {
mCurrTextureIndex = textureIndex;
mCurrTexture = null;
cyclerToCallback.applyReadyTexture();
if(ScreenFaderSphere.getInstance())
{
ScreenFaderSphere.getInstance().fadeToTransparent();
}
}
}
public void readTextureFileNames()
{
if(!string.IsNullOrEmpty(mLocalStorageDirPath) && System.IO.Directory.Exists (mLocalStorageDirPath))
{
Debug.Log ("mLocalStorageDirPath: " + mLocalStorageDirPath);
foreach(FileInfo file in GetFilesWithExtensions(new DirectoryInfo(mLocalStorageDirPath), new string[]{ WorkshopUtils.PNG_EXTENSION, WorkshopUtils.JPEG_EXTENSION }))
{
Debug.Log (file.Name);
// Add each file name to the list of names, which we store.
mTextureFileNames.Add(file.Name);
}
}else {
Debug.Log("mLocalStorageDirPath doesn't exist or the string is empty or null");
}
}
// Gets the list of files in the directory by extention and filters for our specified ones (images)
public IEnumerable<FileInfo> GetFilesWithExtensions (DirectoryInfo dir, params string[] extensions)
{
Debug.Log ("Chiamo il metodo GetFilesWithExtensions con dir che vale: " + dir);
IEnumerable<FileInfo> files = dir.GetFiles();
/*
Debug.Log ("Ci sono " + files.Count().ToString() + " files");
foreach (FileInfo file in files) {
Debug.Log (file.Name + " " + file.Extension);
}
*/
return files.Where(f => extensions.Contains(f.Extension.ToLower()));
}
public bool isFinishedLoadingFirstTexture()
{
return mFinishedFirstTexture;
}
// Returns the current texture to set on the sphere.. If we are setting a texture from the default list, mCurrTexture
// will be null.
public Texture2D getCurrentTexture()
{
return mCurrTexture == null ? mStartingTextures[mCurrTextureIndex] : mCurrTexture;
}
// Returns the total number of textures available between the default mStartingTextures array + the number of
// textures on the device (use file names to get count).
public int getTextureCount()
{
return mStartingTextures.Length + mTextureFileNames.Count;
}
// Returns just the count/size of the array of Starting textures (excluding the device textures)
public int getStartingTextureCount()
{
return mStartingTextures.Count();
}
public void InizioFoto()
{
//#if UNITY_ANDROID && !UNITY_EDITOR
mAndroidEnvironment = true;
readTextureFileNames();
//#endif
// Check if there are starting textures i.e. pre-loaded textures set on the TextureLoader instance.
// Otherwise, if not, we load from the device (or try to).
if(mStartingTextures != null && mStartingTextures.Length > 0) {
mFinishedFirstTexture = true;
}
else {
StartCoroutine(LoadTextureAtIndex(0, true, GameObject.Find("Sphere_Inv").GetComponent<TextureCycler>()));
}
}
}
Now the console write two debug:
\Foto360Demo2\ UnityEngine.Debug:Log(Object) ButtonSelector:CambiaPath() (at Assets/Cartelle/Scripts/ButtonSelector.cs:26) VRStandardAssets.Utils.VRInteractiveItem:Click() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInteractiveItem.cs:52) VRStandardAssets.Utils.VREyeRaycaster:HandleClick() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VREyeRaycaster.cs:136) VRStandardAssets.Utils.VRInput:CheckInput() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInput.cs:104) VRStandardAssets.Utils.VRInput:Update() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInput.cs:47)
mLocalStorageDirPath doesn't exist or the string is empty or null UnityEngine.Debug:Log(Object) TextureLoader:readTextureFileNames() (at Assets/Cartelle/Scripts/ScriptNonMiei/TextureLoader.cs:122) TextureLoader:InizioFoto() (at Assets/Cartelle/Scripts/ScriptNonMiei/TextureLoader.cs:172) ButtonSelector:CambiaPath() (at Assets/Cartelle/Scripts/ButtonSelector.cs:28) VRStandardAssets.Utils.VRInteractiveItem:Click() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInteractiveItem.cs:52) VRStandardAssets.Utils.VREyeRaycaster:HandleClick() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VREyeRaycaster.cs:136) VRStandardAssets.Utils.VRInput:CheckInput() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInput.cs:104) VRStandardAssets.Utils.VRInput:Update() (at Assets/Cartelle/Scripts/Scriptsiindispensabili/VRInput.cs:47)
It's strange because i've put the path.
Answer by KoenigX3 · Jan 17, 2017 at 09:40 AM
Are you sure that you have assigned a path before starting the game?
When you start the game, it will call the InizioFoto() function, which will call the readTextureFileNames() function, which needs the mLocalStorageDirPath to be filled.
Also, when you click the button, it will print the mLocalStorageDirPath variable, then it will modify it. Are you sure that this is the right execution order?
Yes, i'm sure that i've assigned a path...The problem is how to connect a gameobject containing a script TextureLoader, already insered in hierarchy, with a gameobject that will enter only in runtime(This prefab contain buttonselector).(Sorry for my english)
Your answer
Follow this Question
Related Questions
Editing other object's animator parameter... NullReferenceException? (VR) 0 Answers
Google cardboard XR plugin stopped working 0 Answers
Referencing a function in a C# script 1 Answer
My game script is fine but I'm still getting unexpected class error 0 Answers
Survival Shooter Error CS0120 1 Answer