我在統一中創建了一個函式,它需要一個 Binode - 并將其制作成 a2d 樹,但這里的問題是:我所謂的顯示樹的想法是這樣的:
做一個遞回函式,每次層級會上升1,它還會向函式發送一個bool(是舊節點的右邊或左邊),然后如果它為真,它將獲得根樹和 - y 乘以 level * 55,那么它將是 x = level * 55,如果它是正確的,如果它是左邊,x = level * -55。
現在的問題是假設我有一棵有 3 個級別的樹,那么如果我將一個右節點放在左樹上,它只會把它放在最右邊的節點上并且它會重疊,在文本中很難解釋但是我希望你明白。
這里是存盤庫:

代碼:
public void GenrateTreeUI(BinNode<int> t, bool right, int Level)
{
if (Level == 0)
{
cir = Instantiate(CirclePrefab, new Vector2(0, 0), Quaternion.identity);
t.SetGO(cir);
cir.transform.SetParent(canvas.transform);
cir.GetComponent<Image>().color = Color.black;
roottr = cir.GetComponent<RectTransform>();
Value = cir.GetComponentInChildren<TMP_Text>();
roottr.anchoredPosition = new Vector2(-11, 213);
Value.text = t.GetValue().ToString();
Value.color = Color.white;
}
else
{
if (!right)
{
cir = Instantiate(CirclePrefab, new Vector2(0, 0), Quaternion.identity);
cir.transform.SetParent(canvas.transform);
t.SetGO(cir);
cir.GetComponentInChildren<TMP_Text>().text = t.GetValue().ToString();
cir.GetComponent<RectTransform>().anchoredPosition = new Vector2(roottr.anchoredPosition.x - Level * 55,
roottr.anchoredPosition.y - (Level * 55));
}
else
{
cir = Instantiate(CirclePrefab, new Vector2(0, 0), Quaternion.identity);
cir.transform.SetParent(canvas.transform);
t.SetGO(cir);
cir.GetComponentInChildren<TMP_Text>().text = t.GetValue().ToString();
cir.GetComponent<RectTransform>().anchoredPosition = new Vector2(roottr.anchoredPosition.x Level * 55,
roottr.anchoredPosition.y - Level * 55);
}
}
if (t.HasLeft())
{
GenrateTreeUI(t.GetLeft(), false, Level 1);
GenrateWire(cir.GetComponent<RectTransform>().anchoredPosition, GetFutreNode(t.GetLeft(), Level, false));
}
if (t.HasRight())
{
GenrateTreeUI(t.GetRight(), true, Level 1);
GenrateWire(cir.GetComponent<RectTransform>().anchoredPosition, GetFutreNode(t.GetRight(), Level, true));
}
}
謝謝您的幫助!
uj5u.com熱心網友回復:
在這里給出答案之前,我將再次首先建議一些重構和修復:
首先你CreateRndTree錯了;)
public void CrateRndTree(int levels, BinNode<int> save_node)
{
BinNode<int> newNode = null;
for (int i = 0; i < levels; i )
{
newNode = new BinNode<int>(Random.Range(1, 20));
save_node.SetLeft(newNode);
newNode = new BinNode<int>(Random.Range(1, 20));
save_node.SetRight(newNode);
save_node = newNode;
}
}
您創建了兩個新的子節點,但只在最后一個創建的(右)上設定了 left 和 right => 左樹永遠不會有任何子子節點。
我會像這樣遞回地做
private static void CreateRndTree(int levels, BinNode<int> rootNode)
{
if (levels <= 0)
{
return;
}
var leftNode = new BinNode<int>(Random.Range(1, 20), rootNode);
var rightNode = new BinNode<int>(Random.Range(1, 20), rootNode);
rootNode.SetChildren(leftNode, rightNode);
CreateRndTree(levels - 1, leftNode);
CreateRndTree(levels - 1, rightNode);
}
然后作為最后一次我將Circle在圓形預制件上進行適當的課程,例如
public class Circle : MonoBehaviour
{
[SerializeField] private Image image;
[SerializeField] private RectTransform rectTransform;
[SerializeField] private TMP_Text text;
public Image Image
{
get
{
if (image) return image;
image = GetComponent<Image>();
return image;
}
}
public RectTransform RectTransform
{
get
{
if (rectTransform) return rectTransform;
rectTransform = GetComponent<RectTransform>();
return rectTransform;
}
}
public TMP_Text Text
{
get
{
if (text) return text;
text = GetComponentInChildren<TMP_Text>();
return text;
}
}
}
在你的BinNode商店里,而不是GameObject為了擺脫重復的GetComponent電話。
然后對于定位,我寧愿在節點本身中實作一個getter,以計算它們的子級別。
我還將存盤父節點,而是將新節點相對于父節點定位,而不必總是從根節點計算
public class BinNode<T>
{
...
private BinNode<T> parent;
public BinNode<T> Parent => parent;
// proper class that will be sitting on your circle prefab
public Circle circle;
public BinNode(T value, BinNode<T> parent = null)
{
this.value = value;
this.parent = parent;
}
public int GetChildLevels()
{
var rightChildLevels = right == null ? 0 : 1 right.GetChildLevels();
var leftChildLevels = left == null ? 0 : 1 left.GetChildLevels();
return Mathf.Max(rightChildLevels, leftChildLevels);
}
...
}
然后在獲得節點位置時
public float spacing = 55;
public Vector2 GetNodePosition(BinNode<int> node, bool right)
{
var subLevels = node.GetChildLevels();
// simply get the position relative to the parent node
// otherwise you would need to sum them up all the time
var parentRectTransform = node.Parent.Cirlce.RectTransform;
return parentRectTransform.anchoredPosition new Vector2(spacing * (Mathf.Pow(2, subLevels)) * (right ? 1 : -1), -spacing);
}
對于 3 級

對于 4 級

對于 5 級

作為我最后一次對此提出拉取請求;)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/435346.html
上一篇:Vector3.Lerp不會移動我的物件,盡管我的除錯說它應該
下一篇:我想用游標移動一個物件
