如何从父级中的另一个脚本管理子脚本中的变量?

时间:2016-11-12 12:00:00

标签: c# unity3d

我正在尝试在TileScript中管理一些变量,比如TileGroupID,从父级的TilesManager脚本中选择TileIsSelected但我无法找到方法。例如,我想搜索所有Tiles,如果其中一个TileIsSelected为True,然后在所有TileGroupID为1的Tiles中做一些事情。我创建了tilesArray以跟踪所有游戏对象,但我不知道如何使用那就是我刚才所说的。

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.
}

1 个答案:

答案 0 :(得分:2)

OnMouseDown函数应该从TilesManager脚本移动到TileScript脚本。单击每个Tile时将调用它。发生这种情况时,您可以调用TilesManager函数上的函数并将其传递给被点击的当前GameObject。

TileScript脚本中:

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

TilesManager脚本中:

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

当我点击瓷砖TileIsSelected变为true时,改变他的   材料并更改所有其他相同的瓷砖材料   TileGroupID是我点击的那个。

现在您只需要一个基本的for循环。循环遍历tilesArray数组,并检查哪一个与被点击的GameObject具有相同的tileGroupID

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;
            }
        }
    }
}

最后我说的全部内容放在一起:

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;
                }
            }
        }
    }
}