How to access an Instance of a non-MonoBehaviour object from C# script?

I’m new to Unity and have a very basic question.

I have created a MapData class which holds a 2D array of a map, along with other variables like height, width, player spawn point. This class doesn’t extend MonoBehaviour.

public class MapData {
//holds terrain data in 2D array, has GetTile(x, y) accessor.
}

The MapData object is created from my MapGraphics class, which renders the MapData to a texture and attaches it to a plane GameObject.

public class MapGraphics : MonoBehaviour {
MapData map = new MapData(sizeX, sizeZ);
{

The PlayerController moves the player around the map. I want to detect collisions by accessing the MapData (comparing current position with current position + 1 and blocking if that is a wall tile).

public class PlayerController : MonoBehaviour {
//If moving right, block if MapData.GetTile(current position + 1, y) = wall;…etc
}

However, I don’t know how to access the instances of the MapData object which I created in the MapGraphics class, from the PlayerController class? I’ve tried GetComponent but then I need to extend Component or MonoBehaviour from MapData which I don’t really want to do.

2274613--152543--cellular-automata-screen-shot.png

Well MapGraphics owns the MapData object that it created, so the best way to make that MapData available to PlayerController depends on your code architecture. The two main approaches are either access MapData through MapGraphics (ie. PlayerController’s code makes a call like mapGraphics.mapData) or move MapData out of MapGraphics to some other location that both MapGraphics and PlayerController reference.

Which approach is more appropriate in your specific situation depends on what MapGraphics does; I would recommend making your data modeling objects separate from your graphics visualization objects.

Thanks for your prompt reply.

If I do this (perhaps put MapData creation into a LevelSetup class), how can I access the correct MapData object from the other scripts?

The other scripts need access to LevelSetup (be it dependency injection, a service locator, etc etc there are lots of options) and then make a public property to reference like levelSetup.mapData

The pattern I normally use for cases like this is to have a “World” class which derives from MonoBehavior, and which is easily accessible using something like Singleton pattern.

Then, either have your data directly in World, or (if you prefer to have that stuff encapsulated in a non-MonoBehaviour class) have World expose an accessor for WorldData.

Note that MapGraphics should not own this data. Its job is drawing the map, which is great, but it should get that data via the World instance like everybody else.

Then when your player class needs to know if it can move right, it can just call World.instance.mapData.IsBlocked(x,y) or whatever.

As @jhocking said, there are lots of options, but this is one way to do it that has worked for me.

Best,

  • Joe