Send message to instantiated clone has funny results

There is a prefab with a script attached to it, prefab A. Then prefab A instantiates a clone of itself, prefab B, and sends a message to call a method. The message is sent and received, but the results are not as expected.

Code and results

using UnityEngine;
using System.Collections;

public class TestOfPrefabNonsense : MonoBehaviour {

	public int basePairs;
	public GameObject prefab;
	void Start () {
		basePairs = 0;
	}
	void OnMouseDown(){
		MakePrefabB();         // I am using a button for this
	}
	public void MakePrefabB(){
		Debug.Log(basePairs);  //10  basePairs gets added to by editor to test this
		int half = basePairs/2;
		Debug.Log(half);       // 5
		GameObject prefabB = Instantiate (prefab);
		prefabB.SendMessage("TakeHalf", half);
		basePairs -= half;
	}
	void TakeHalf(int half){
		Debug.Log(half);       // 5
		basePairs += half;
		Debug.Log(basePairs);  // 15
	}
}

##Actual Values (From the Inspector) after creating prefabB

prefabA basePairs = 5

prefabB basePairs = 0

Can anyone explain why this is?

From the inspector, you are setting the value. However, as soon as you hit run, your scripts run their Start function, where you tell it to set basePair to 0. 0/2 is also 0, so when you add it to basePair… yep… 0.

Like @Gnemlock said in his answer you run TakeHalf before Start runs. You might want to use Awake instead. Awake is called before the Instantiate call returns. So Awake is the best place for setting up initial values as it acts like a constructor. Start is only ensured to run before the first Update call on that object. That’s why Start is usually scheduled at the beginning of the frame.

Besides that you have a setup that might cause other problems as well. A prefab can not contain a reference to it’s own prefab. Self-references are replaced with the instance reference when the object is instantiated. That means the “prefab” field of the objectA instance will point to itself and not to the prefab it was made of. See those question for reference:

http://answers.unity3d.com/questions/577888/how-to-instantiate-from-prefab-not-from-instance.html
http://answers.unity3d.com/questions/45079/instantiated-objects-scripts-not-enabled-not-sure.html

In case it doesn’t matter if you simply clone the current object or the prefab this might not be a problem for your. Just be sure you understand what object actually got cloned.

make TakeHalf public and try:

prefabB.GetComponent<TestOfPrefabNonsense>().TakeHalf(half);

instead of:

prefabB.SendMessage("TakeHalf", half); 

I think that will work.