non-static variable behaving like static (C#). Very confused.

So I have a prefab item in Unity called GameFrame with the script GameFrame attached to it. I have 2 instances of this prefab in my scene and for some reason the variable firstSelectedBlock is behaving as if it was static. The code swaps two blocks when you click on two that are right next to each other. When you click a block that ISN’T right next door it selects that block instead. Everything works fine. happy fun times.

HOWEVER, if I create 2,3,4 instances of the GameFrame prefab if I click a block in ANY of them it sets the firstSelectedBlock variable in all of them. The variable was originally private but I switched it to public just so I could watch it at run time easily and sure enough they are all synchronized at all times.

Am I missing something silly? I’m really lost on this one.

Thanks in advance for any help… code below.

using UnityEngine;
using System.Collections;

public class GameFrame : MonoBehaviour {

	public GameObject blockLifter;
	public GameObject[] basicBlocks;
	public LayerMask gameBlockMask;
	private Vector2 blockSpacing = new Vector2(21,20);
	private int levelHeight=5;
	private int gameWidth=6;
	private float xStartPosition;
	private GameObject currentLifter;
	private int liftSpeed=2;
	private bool liftPaused=true;
	private GameObject trackThisOne;
	public GameObject firstSelectedBlock;
	private bool canSelectBlocks=false;

	void Start () {
		xStartPosition=-((gameWidth / 2) * blockSpacing.x);
	// Update is called once per frame
	void Update () {
		//if we have a click
		if(Input.GetMouseButtonDown(0) && canSelectBlocks){
			//lets cast a ray and see if they clicked a block
		    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;
			//if they did lets see which one
		    if(Physics.Raycast(ray, out hit, 1000f, gameBlockMask)){
		        GameObject hitObj = hit.collider.gameObject;
				//if they already have a block selected lets swap them
				//and that block is compatible for swapping (on same line AND right next door)
				if(firstSelectedBlock && hitObj &&
					Mathf.Abs(firstSelectedBlock.transform.position.y - hitObj.transform.position.y) < 1 &&
					Mathf.Abs(firstSelectedBlock.transform.position.x - hitObj.transform.position.x) < blockSpacing.x + 1){
						firstSelectedBlock.transform.position = new Vector3(firstSelectedBlock.transform.position.x,firstSelectedBlock.transform.position.y,0);

					//otherwise lets select a block
					hitObj.transform.position = new Vector3(hitObj.transform.position.x,hitObj.transform.position.y,blockSpacing.y * 0.75f);

Solved… thanks to everyone that offered advise.

The solution was that the individual instances of GameFrame was setting the firstSelectedBlock variable to any block that was clicked even if it was in another GameFrame object. A simple test to see if the object clicked is a child of the game frame solved it.

I used the following…


Then changed it to the following as I think it’s more proper…


thanks again for the help.

I suppose that the problem is caused by this script being run in all GameFrame objects: when you click one of them, all GameFrame objects do the raycast in the same frame, setting firstSelectedBlock in each script.

Actually, many variables in this script apparently should be unique and common to all GameFrame objects, like blockSpacing, firstSelectedBlock, canSelectBlocks etc. If this is the case, moving the common code to a single script attached to the camera (or other unique object) would be the wiser solution - keep in the prefab script only the variables that affect that particular instance.