How to communicate between two classes - C#

Hello. I appreciate this is a pretty basic question, but my knowledge of C# is pretty basic, and I have searched around the internet before coming here and cannot think of what I’m doing wrong.

So a quick example.

Lets say I have a class that has a int value (Class A). I also have another class with an int value (Class B). These scripts are both attached to in game objects and if they were to interact through them touching, or some other trigger how would I allow Class A to know what int value Class B has, and then add it to its own, or to change the value of class B purely through some simple interaction which acts as a trigger.

The reason my example is fairly vague on the details is because I want to be able to apply it to a number of things rather than something specific.

I am more familiar in Uscript and in that I would create a variable of the class I want to access or send data across

var ShooterWeapon ShootWeap;

then do something like

foreach WorldInfo.AllActors(class’ShooterWeapon’, ShootWeap)
{
ShootWeap.FunctionInShootWeap(DataIWantToSendAcross);
}

Hopefully that example will allow anyone who has knowledge of uscript and c# in unity to know exactly the function I’m looking for, if not the description of my problem will hopefully be enough.

Thanks

Hi Ovredon,

My programming skills are a bit sucky, but here’s what I would do:

//Attached script variables
private ScriptA myScriptA;
private ScriptB myScriptB;
private int aInt;
private int bInt;

void start{
//Set local private variables to the attached components
myScriptA = transform.gameObject.getComponent();
myScriptB = transform.gameObject.getComponent();
}

void DoThings{
if(…)
{

//Get/Set methods must be defined in your scripts
aInt = myScriptA.getInt();
bInt = myScriptB.getInt();
myScriptA.setInt(bInt);
myScriptB.getInt(aInt);
}
}

Give that a try.
If it doesn’t work, hopefully a more skillful programmer could provide clarity.

Regards,
Ezro

Thanks for the suggestions I’ll try that now.

the getInt and setInt - I thought they were going to be in built functions, or do I make them as a return function myself?

You can call any method or variable this way as long as there public :slight_smile:

I’m sorry I’m going to have to ask someone to elaborate further as I’m not able to get this working :frowning:

You would have to write those functions yourself, inside of the two scripts.

Also, the code that I wrote was from a 3rd script perspective.
You can easily incorporate the code into your existing scripts, though, by using the getComponent approach.

Regards,
Ezro

I’ve made a function in the other class (class B) and trying to call it from class A and trying to send the variable over with it but I keep getting the error that says “object reference is not set to an instance of object”.

Ovredon,

Could you please post snippets of your code?

Regards,
Ezro

Sure thing Ezro…

This is Class A that I was talking about.

public class ClassCommunicationNumbers : MonoBehaviour
{
private ClassCommunication2 cc2;
private int Clickz;

// Use this for initialization
void Start ()
{
Clickz = 1;
cc2 = gameObject.GetComponent();
}

// Update is called once per frame
void Update ()
{

}

void OnMouseDown()
{
//Clickz = cc2.setInt(Clickz);
cc2.SetInt(Clickz);
//Debug.Log (“afdasfadfsdf” + Clickz);

}
}

This is class B

public class ClassCommunication2 : MonoBehaviour
{
public int Clicks;

// Use this for initialization
void Start ()
{
Clicks = 0;
}

// Update is called once per frame
void Update ()
{
Debug.Log (“number of clicks” + Clicks);
}

public int SetInt(int Click)
{
Clicks += Click;
return Clicks;
}
}

it builds fine but when I click the box the script is attached to I get that error. Also script B is attached to a dfiferent box.

Have you added the script to the gameobject you are trying to access it from?

Otherwise, It is most probably caused by the script execution order executing your “class A” before “class B” and since class A depends on knowing about class B you get this error. There are multiple solutions to this but the most simplest is to change the script execution order manually.

To do this, click on a c# script in the editor, on the top right of the inspector tab is a button labelled “Execution Order”, click the “+” sign and browse to your “class B” script and apply.

It has nothing to do with execution order.

gameObject.GetComponent will find a component on the current GameObject. You said the second script is attached to another GameObject so you’ll have to use GetComponent on that one or make the field public and assign it via the Inspector.

Just did as you said Mister-E2 but it didn’t change the error I’m still getting the same message - thanks for the suggestion though.

Would love you to point out where he said they are attached to separate game objects, because I can’t for the life of me. English is not my native so possibly I am missing it

Right here…

I kind of have it working now doing what you said Kelso. but ideally I didn’t want to have to assign it from inspector. I’m just trying a few more things, unless you have more advice?

I would have thought there would be some easy way to gain access to an objects variables and such by using a Tag that it has or its name in the hierarchy. Is there a simple way to do that or?

By the way I do have it working fine now assigning it through the inspecter but I want to try and get it working through script and not having to manually drag and drop the object that the has the other script on.

As long as the object is already created in the scene, you can use the GameObject.Find(“name of object in scene”); to return a game object. This is an expensive function however (depending on how many objects are in your scene) so should only really be used in start or awake so it only affects loading overhead

You can store this in a variable and access the script you need.

There absolutely is.

I was under the assumption that both scripts were on the same gameObject.
If they are on separate GOs, then you can just do something like the following:

Class A
private ClassCommunication2 cc2;
private GameObject classB;

// Use this for initialization
void Start ()
{
classB = gameObject.FindGameObjectWithTag(“ClassB”);
cc2 = classB.GetComponent();
}

Give that a go, and reply back with your results.

Regards,
Ezro

Yes!

It works, Everything is private, and I am able to transmit data from one class to another, and also call a function from one class to another. Thank you for the help and suggestions everyone. I am using the FindGameObjectWithTag at the moment. I will post the code incase someone has a similar problem and stumbles upon this thread requiring an answer.

Last question - FindGameObjectWith Tag is useful but what if I wanted to use the name given to the object which you can enter just above the Tag. For example by default if you created a cube within the world it would have the default name of Cube and this would be shown in the hierarchy. I don’t know if its possible to use THAT instead of a Tag in scripting because objects can have the same name in the hierarchy it seems…

SOLVED USING ################## FindGameObjectWithTag ##################

Class A:

public class ClassCommunicationNumbers : MonoBehaviour
{
private GameObject cc3;
private ClassCommunication2 cc2;
private int Clickz;

void Start ()
{
Clickz = 1;

cc3 = GameObject.FindGameObjectWithTag(“numbertest”);
cc2 = cc3.GetComponent();
}

void OnMouseDown()
{
cc2.SetInt(Clickz);
}
}

Class B

public class ClassCommunication2 : MonoBehaviour
{
public int Clicks;

void Start ()
{
Clicks = 0;
}

void Update ()
{
}

public int SetInt(int Click)
{
Clicks += Click;
Debug.Log (“number of clicks” + Clicks);
return Clicks;

}
}

Thanks again, gonna try some more complicated stuff with what I’ve learned here.