Как предотвратить уничтожение ребенка в Unity - PullRequest
0 голосов
/ 16 марта 2020

Я готовлю игру-головоломку. Я могу перетащить вниз сгенерированные палочки вверх места. Допустим, на первом узле есть две палочки, а у нас еще две палочки внизу. Мы можем перетащить его в нужное место и сделать их снова одним из родителей. Я могу сделать их одним родителем, но второй жезл со стороны разрушает, когда я падаю на первый узел. На этом изображении цвет воды:

до падения

before drop photo

после падения

after drop photo


Как решить эту проблему?

if(nodes[smallestId].transform.childCount > 0)
{
  for (int i = 0; i < rayhit.transform.childCount; i++)
  {
    nodes[smallestId].transform.GetChild(0).GetComponent<Node>().sticks.Add(rayhit.transform.GetChild(i).GetComponent<Stick>());
    rayhit.transform.GetChild(i).transform.SetParent(nodes[smallestId].transform.GetChild(0));
  }
  Destroy(rayhit.transform.gameObject);
}
else
{ 
  rayhit.transform.SetParent(nodes[smallestId].transform);
  Debug.Log("Stick : " + nodes[smallestId].transform);
}

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

ребята, вот решение :)

rayhit.transform.position = nodes[smallestId].transform.position;
                    if (rayhit.transform.parent != nodes[smallestId].transform)
                    { 
                        if (nodes[smallestId].transform.childCount > 0 && nodes[smallestId].transform != rayhit.transform.parent)
                        {
                            if (currNode != null)
                            {
                                for (int i = 0; i < currNode.sticks.Count; i++)
                                {
                                    nodes[smallestId].transform.GetChild(0).GetComponent<Node>().sticks.Add(currNode.sticks[i]);
                                    currNode.sticks[i].transform.SetParent(nodes[smallestId].transform.GetChild(0));
                                }
                                Destroy(rayhit.transform.gameObject);
                            }
                        }
                        else
                        {
                            if (currNode != null)
                            {
                                currNode.isMoved = true;
                            }
                            rayhit.transform.SetParent(nodes[smallestId].transform);
                        }
                    }

Спасибо за вашу помощь.

0 голосов
/ 16 марта 2020

Проблема в том, что вы перебираете rayhit.transform.childCount.

При удалении дочернего элемента из-за rayhit.transform.GetChild(i).transform.SetParent значение rayhit.transform.childCount уже уменьшается на единицу.

Поэтому в следующей итерации i может быть уже больше rayhit.transform.childCount, поэтому, например, второй объект не перемещен в нового родителя!

Вместо этого вы можете использовать

// do this only once
var targetParent = nodes[smallestId].transform;

if(targetParent > 0)
{
    targetParent = targetParent.GetChild(0);
    // do also this only once
    var node = targetParent.GetComponent<Node>();

    var toMove = new List<Transform>();
    foreach (Transform child in rayhit.transform)
    {
        node.sticks.Add(child.GetComponent<Stick>());
        toMove.Add(child);
    }
    foreach(var child in toMove)
    {
        child.SetParent(targetParent);
    }

    Destroy(rayhit.transform.gameObject);
}
else
{ 
    rayhit.transform.SetParent(targetParent);
    Debug.Log("Stick : " + targetParent);
}

Который сначала сохраняет их все в списке, так что вы не зависите от того, перенесены ли они уже к новому родителю или нет.


В качестве альтернативы, я думаю, вы могли бы даже использовать GetComponentsInChildren здесь, что полностью избавит вас от неприятностей, и вам вообще не нужно будет использовать две петли:

var targetParent = nodes[smallestId].transform;

if(targetParent > 0)
{
    targetParent = targetParent.GetChild(0);
    // do also this only once
    var node = targetParent.GetComponent<Node>();

    // These references now don't depend on their parent object
    // so you can safely iterate on them without any issues
    foreach (var stick in rayhit.transform.GetComponentsInChildren<Stick>(true))
    {
        node.sticks.Add(stick);
        stick.transform.SetParent(targetParent);
    }

    Destroy(rayhit.transform.gameObject);
}
else
{ 
    rayhit.transform.SetParent(targetParent);
    Debug.Log("Stick : " + targetParent);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...