0

I'm producing a SRPG which is based on hexagonal grids. The frontend UI and the backend data of chess and the map are separated.Every times I move a chess,the button on chess invoke backend methods to run the results which are updated in backend data.Then the frontend method load the data and repaint the UI by destroying all the chesses and the map and then instantiate new chesses and map with the data. In the Game,when I selecte a chess,I could select the nearby blocks to move it.At that time,the buttons on all the chesses should not be interactable.So I got a method to disable all chesses.

public void DisableAllChessman()
{
    foreach (int id in chessmanPDic.Keys)
    {
        Chessman tempCm = chessmanPDic[id];
        GameObject obj = objectPool.mapPanel.transform.Find("Chessman" + id).gameObject;
        Button tempButton = obj.GetComponentInChildren<Button>();
        tempButton.interactable = false;
    }
}

And every times the backend data updated,I use follow methods to repaint all the chesses.

private void ClearChessman()
{
    foreach (int id in chessmanPDic.Keys)
    {
        GameObject.Destroy(objectPool.mapPanel.transform.Find("Chessman" + id).gameObject);
    }
}

private void InitChessman()
{
    chessmanPDic.Clear();
    List<Chessman> tempPData = BlockTest.Instance.blockManager.ChessmanPPrinter();
    foreach (Chessman cm in tempPData)
    {
        chessmanPDic.Add(cm.ID, cm);
    }

    foreach (int id in chessmanPDic.Keys) 
    {
        Chessman tempCm = chessmanPDic[id];
        GameObject obj = GameObject.Instantiate<GameObject>(objectPool.chessman, objectPool.mapPanel.transform);
        obj.AddComponent<Chessman_mono>();
        Vector2 tempPos = GetWorldPosition(tempCm.Q, tempCm.R);
        obj.GetComponent<RectTransform>().anchoredPosition = tempPos;
        obj.name = "Chessman" + tempCm.ID;

        GameObject part = GameObject.Instantiate<GameObject>(objectPool.chessmanPart, obj.transform);
        part.GetComponent<RectTransform>().anchoredPosition = GetWorldPosition(tempCm.Q, tempCm.R) - tempPos;
        part.GetComponent<RectTransform>().sizeDelta = new Vector2(1.5f * chessBlockLength, 1.5f * chessBlockLength);
        obj.GetComponent<Chessman_mono>().UpdateChessman_mono(tempCm);
    }
    DisableAllChessman();
}

The problem is that,the first time I invoke DisableAllChessman();,the m_interactable on button component can be set false correctlly.But after I ClearChessman(); InitChessman();,invokeDisableAllChessman();cant set the m_interactable false.It's always true.

Maybe I could solve the problem by not repainting UI every single times the backend data updated.But use a objectPool to register all chesses at the first time they are created.And update UI by moving gameobjects in the objectPool. But I really wonder that where went wrong in the case I use above.Sorry that I cant find it out as a noob developer.Could anyone point out the problem.

burnsi
  • 6,194
  • 13
  • 17
  • 27
  • The main problem I see is you using `Find` at all .. why not rather store all the instances of your `Chessman_mono` in a second dictionary/list and directly iterate over them? – derHugo Feb 14 '23 at 15:00

0 Answers0