N1ckGreek N1ckGreek - 28 days ago 8
C# Question

How to manage variables in child script from another script in parent?

I am trying to manage some variables in TileScript like TileGroupID, TileIsSelected from the TilesManager script in parent but i cant find a way to do it. For example i want to search all the Tiles if one of them have TileIsSelected True and then do something in all Tiles that have TileGroupID 1. I created tilesArray to keep track all the game objects but i don't know how i can use that to do what i said earlier.





TileScript:

//Public
public int tileGroupID = 0; //Indicates the Tile Group ID.
public bool tileIsSelected = false; //If this Tile is Selected.
public GameObject[] tilesArray; //Reference to Tiles Array.

//Private
private Rigidbody myRigidbody;
private Renderer myRenderer;
private Material tileDefaultMaterial;
private Material tileSelectedMaterial;
private Material tileSameGroupMaterial;

void Start () {
tilesArray = GetComponentInParent<TilesManager> ().tilesArray;
myRigidbody = GetComponent<Rigidbody> ();
myRenderer = GetComponent<Renderer> ();
tileDefaultMaterial = Resources.Load ("TileDefault", typeof(Material)) as Material;
tileSelectedMaterial = Resources.Load ("TileSelected", typeof(Material)) as Material;
tileSameGroupMaterial = Resources.Load ("TileSameGroup", typeof(Material)) as Material;
}


TilesManager:

//Public
public GameObject[] tilesArray; //Aray of all Tiles GameObject.

//Private


void Start () {
tilesArray = new GameObject[transform.childCount];
for(int i = 0; i < transform.childCount; i++){
tilesArray [i] = transform.GetChild (i).gameObject;
}
}

void OnMouseDown (){

//Do stuff with each tile.
}

Answer

The OnMouseDown function should be moved from the TilesManager script to the TileScript script. It will be called when each Tile is clicked on. When this happens, you can call a function on the TilesManager function and pass it the current GameObject that was clicked on.

In your TileScript script:

void OnMouseDown()
{
    //Let Tiles Manager know that there was a press on (this) Tile
    tileManagerInstance.OnObjectSelection(this.gameObject);
}

In your TilesManager script:

public void OnObjectSelection(GameObject selectedObj)
{
//Change Material of the Selected GameObject
    selectedObj.GetComponent<MeshRenderer>().material = tileSelectedMaterial;
}

when i click on a tile TileIsSelected change to true, change his material and change all the other tile material that have same TileGroupID as the one i clicked.

All you need now is a basic for loop. Loop through the tilesArray array and check which one has the-same tileGroupID as the GameObject that was clicked.

void findTheSameTileGroupIDAndChangeColor(GameObject selectedObj)
{
    //Get the TileScript attached to the selectedObj
    TileScript selectedTileScript = selectedObj.GetComponent<TileScript>();

    //Loop through all GameObject in the array
    for (int i = 0; i < tilesArray.Length; i++)
    {
        /* 
           Make sure this is NOT selectedObj since we've arleady 
           changed its Material in OnObjectSelection function
        */
        if (selectedObj != tilesArray[i])
        {
            //Get TileScript attached to the current Tile loop
            TileScript tileLoop = tilesArray[i].GetComponent<TileScript>();
            //Check if selectedObj and the current loop tileGroupID matches
            if (selectedTileScript.tileGroupID == tileLoop.tileGroupID)
            {
                //It matches! Now, change it's color
                tileLoop.GetComponent<MeshRenderer>().material = tileSelectedMaterial;
            }
        }
    }
}

Finally the Whole thing I said put together:

TileScript:

public class TileScript : MonoBehaviour
{
    public int tileGroupID = 0; //Indicates the Tile Group ID.
    public bool tileIsSelected = false; //If this Tile is Selected.
    public GameObject[] tilesArray; //Reference to Tiles Array.

    //Private
    private Rigidbody myRigidbody;
    private Renderer myRenderer;
    private Material tileDefaultMaterial;
    private Material tileSelectedMaterial;
    private Material tileSameGroupMaterial;

    private TilesManager tileManager;

    void Start()
    {
        tilesArray = GetComponentInParent<TilesManager>().tilesArray;
        myRigidbody = GetComponent<Rigidbody>();
        myRenderer = GetComponent<Renderer>();
        tileDefaultMaterial = Resources.Load("TileDefault", typeof(Material)) as Material;
        tileSelectedMaterial = Resources.Load("TileSelected", typeof(Material)) as Material;
        tileSameGroupMaterial = Resources.Load("TileSameGroup", typeof(Material)) as Material;

        //Get Tiles Manager
        GameObject tileManagerObj = GameObject.Find("Tiles");
        tileManager = tileManagerObj.GetComponent<TilesManager>();
    }

    void OnMouseDown()
    {
        //Let Tiles Manager know that there was a press on (this) Tile
        tileManager.OnObjectSelection(this.gameObject);
    }
}

TilesManager:

public class TilesManager : MonoBehaviour
{
    public GameObject[] tilesArray; //Aray of all Tiles GameObject.
    public Material tileSelectedMaterial;

    void Start()
    {
        tilesArray = new GameObject[transform.childCount];
        for (int i = 0; i < transform.childCount; i++)
        {
            tilesArray[i] = transform.GetChild(i).gameObject;
        }
    }

    //Will be called from  the TileScript(Receives any tile that is selected)
    public void OnObjectSelection(GameObject selectedObj)
    {
        //Change Material of the Selected GameObject
        selectedObj.GetComponent<MeshRenderer>().material = tileSelectedMaterial;

        //Change Mateial of other GameObjects that matches the  tileGroupID of the selectedObj
        findTheSameTileGroupIDAndChangeColor(selectedObj);
    }

    void findTheSameTileGroupIDAndChangeColor(GameObject selectedObj)
    {
        //Get the TileScript attached to the selectedObj
        TileScript selectedTileScript = selectedObj.GetComponent<TileScript>();

        //Loop through all GameObject in the array
        for (int i = 0; i < tilesArray.Length; i++)
        {
            /* 
               Make sure this is NOT selectedObj since we've arleady 
               changed its Material in OnObjectSelection function
            */
            if (selectedObj != tilesArray[i])
            {
                //Get TileScript attached to the current Tile loop
                TileScript tileLoop = tilesArray[i].GetComponent<TileScript>();
                //Check if selectedObj and the current loop tileGroupID matches
                if (selectedTileScript.tileGroupID == tileLoop.tileGroupID)
                {
                    //It matches! Now, change it's color
                    tileLoop.GetComponent<MeshRenderer>().material = tileSelectedMaterial;
                }
            }
        }
    }
}