Local variable looses its values

Hi all,

I’m having problems displaying a variable in my OnCollsionEnter() function.
I have created a datamanager class to hold all my variables so I can retrieve them from any script:

using UnityEngine;
using System.Collections;

// This script holds any data that is to be passed from script to script

public class dataManager 
{
	private Vector3 d_lightPos, d_cubePos;
	private GameObject d_Grid;
	private short d_Count;
	private int d_Lights;
	private ArrayList obsPos = new ArrayList();
	private ArrayList lgtPos = new ArrayList();
	
	public void setCubePosition(Vector3 cubePos)
	{
		d_cubePos = cubePos;
	}
	
	public Vector3 getCubePosition()
	{
		return d_cubePos;
	}
	
	public void setLightPosition(Vector3 lightPos)
	{
		d_lightPos = lightPos;
	}
	
	public Vector3 getLightPosition()
	{
		return d_lightPos;
	}
	
	public void setGridPiece(GameObject p_Grid)
	{
		if (p_Grid == null)
		{
			p_Grid = new GameObject();	
		}
		else
		{
			d_Grid = p_Grid;
		}
	}
	
	public GameObject getGridPiece()
	{
		return d_Grid;
	}
	
	public void setObstacleCount(short p_Count)
	{
		d_Count = p_Count;
	}
	
	public short getObstacleCount()
	{
		return d_Count;
	}
	
	public void setLightsOnCount(int p_Count)
	{
		d_Lights = p_Count;	
	}
	
	public int getLightsOnCount()
	{
		return d_Lights;
	}
	
	public void setObstaclePosition(Vector3 d_Pos)
	{
		if (d_Pos == Vector3.zero)
		{
			d_Pos = new Vector3(0,0,0);
			obsPos.Add(d_Pos);
		}
		else
		{
			obsPos.Add(d_Pos);
		}
	}
	
	public Vector3 getObstaclePosition(short index)
	{
		return (Vector3)obsPos[index];
	}
	
	public void setLightPositionList(Vector3 d_Pos)
	{
		if (d_Pos == Vector3.zero)
		{
			d_Pos = new Vector3(0,0,0);
			lgtPos.Add(d_Pos);
		}
		else
		{
			lgtPos.Add(d_Pos);
		}
	}
	
	public Vector3 getLightPositionList(short index)
	{
		return (Vector3)lgtPos[index];	
	}
}

And in my cubecollider class I call the functions I need:

using UnityEngine;
using System.Collections;

public class cubeCollider : MonoBehaviour
{
	private enum sides{down, up, back, front, left, right};
	Vector3 cubePos, lightPos;
	Transform temp;
	sides checkSides;
	dataManager m_DataManager;
	
	void Start()
	{
		m_DataManager = new dataManager();
		cubePos = m_DataManager.getCubePosition();
		lightPos = m_DataManager.getLightPosition();
	}
	
	void OnCollisionEnter(Collision collision)
	{
		Debug.Log("Cube:" + cubePos);
		Debug.Log("Light: " + lightPos);
	}
}

They are being correctly set in other scripts. Im completely confused as to how these variables only show (0,0,0), yet if I Debug them in the datamanager class before they are returned I get the correct values. What am I doing wrong?

Each of your cubeCollider scripts have their own instances of dataManager classes. Is that intentional? Where is the data written to these variables?

private Vector3 d_lightPos, d_cubePos;

In the start function
void Start()

{

m_DataManager = new dataManager();

cubePos = m_DataManager.getCubePosition();

lightPos = m_DataManager.getLightPosition();

}

Also it is intentional to have an instance of the datamanager class as I cant see another way of getting that information from that class.

Well you could be setting the classes fields before the dataManager’s are being set in another script?

OK…could you give an example for that please?

What i mean is, your probably setting cubePos and lightPos before another script is setting d_cubePos and d_lightPos.
This can happen, because each script is executed before another, so theres a chance your cubecollider is being run before the on thats seting the values. :slight_smile:
Better?

I understand. Thanks :P, I was just wondering if having a datamanager class was the right way to go if i should just store my variables within each class that uses them…

Tbh, if alot of classes want to access your dataManager you could just make it a singleton.
Singleton : Singleton pattern - Wikipedia

Heres some code for using a singleton

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
   protected static T instance;
 
   /**
      Returns the instance of this singleton.
   */
   public static T Instance
   {
      get
      {
         if(instance == null)
         {
            instance = (T) FindObjectOfType(typeof(T));
 
            if (instance == null)
            {
               Debug.LogError("An instance of " + typeof(T) + 
                  " could not be found!");
            }
         }
 
         return instance;
      }
   }
}

Now to use this, all you need to do is :

DataManager d = Singleton<DataManager>.Instance;

Hope this helps! :slight_smile:

So rather than passing an instance of the class around in parameters, I can use:

DataManager d = Singleton.Instance;

on any script that needs it?

Indeed you can :slight_smile:

Excellent, ill give it a go! :smile:

OK Ive implemented the Singleton class and I get this error:

UnityException: You are not allowed to call this function when declaring a variable.
Move it to the line after without a variable declaration.
If you are using C# don’t use this function in the constructor or field initializers, Instead move initialization to the Awake or Start function.

Should there be a Start or Awake function there?

It refers to this line:

instance = (T) FindObjectOfType(typeof(T));