[英]UI prefabs are instantiated below the canvas
我正在嘗試復制Zelda衛生系統。 該代碼看起來真的很好並且可以正常工作。
但是心臟容器放置錯誤。 它們在畫布下實例化。
這是重要的代碼,心臟容器正確,只是位置錯誤。
x和y的計算是正確的,但在畫布上是不正確的。
private Transform healthBar = GameObject.FindGameObjectWithTag("HealthController").transform; // container for the heartContainers
private GameObject healthWrapperObject = Resources.Load("HealthContainer") as GameObject; // the backgroundImage and parent of the heart
private List<Image> healthContainers = new List<Image>(); // list of hearts for later usages
private int maxHealth = 6;
private int currentHealth;
private int healthPerHealthContainer = 4; // 4 lifepoints per heart
private int healthContainersPerRow = 5; // 5 hearts per row
private int healthContainerStartPositionX = 0; // Healthbar starts at 0 on x
private int healthContainerStartPositionY = 0; // Healthbar starts at 0 on y
private int healthContainerSpacingX = 10; // horizontal spacing
private int healthContainerSpacingY = -10; // vertical spacing
private void Start()
{
currentHealth = maxHealth;
InitializeHealthBar();
}
public void InitializeHealthBar()
{
int neededHealthContainers = maxHealth % healthPerHealthContainer == 0 ? maxHealth / healthPerHealthContainer : maxHealth / healthPerHealthContainer + 1; // Calculate the needed container count
int counter = 0; // counts the hearts per row
int x = healthContainerStartPositionX; // horizontal position of the heartContainer
int y = healthContainerStartPositionY; // vertical position of the heartContainer
for (int i = 0; i < neededHealthContainers; i++)
{
counter++;
if (counter >= healthContainersPerRow) // start a new line after 5 hearts per row
{
x = healthContainerStartPositionX; // move back to the left
y += healthContainerSpacingY; // go for the next line
counter = 0; // reset the counter
}
else
x += healthContainerSpacingX; // place the new container right next to the previous
Transform newHealthContainerTransform = Instantiate(healthWrapperObject, new Vector2(x, y), healthWrapperObject.transform.rotation).transform; // create the healthContainer parent / backgroundImage
newHealthContainerTransform.SetParent(healthBar); // take the container and make it a child of the healthBar
healthContainers.Add(newHealthContainerTransform.GetChild(0).GetComponent<Image>()); // get the heart of the heartContainer and add it to the heartList
}
}
我添加了healthBar,healthContainer / backgroundImage和心臟(“ healthfill”)的轉換設置。
在所有三個元素上,我按下了Strg + Alt和Shift鍵來錨定它們。
心臟容器應添加到健康欄上,心臟是心臟容器的子對象,並設置為可拉伸(其大小應與其父對象相同)
為什么UI預制對象在畫布下方實例化?
我認為您得到的是這樣的:
您可以通過將false
傳遞給SetParent
函數的第二個參數來解決此問題。 這樣,您將使“變換”保持其局部方向而不是其整體方向。
只需替換:
newHealthContainerTransform.SetParent(healthBar);
與:
newHealthContainerTransform.SetParent(healthBar, false)
您還可以設置父對象,並使實例化對象的“變換”在“ Instantiate
函數中保持其局部方向。 這樣做的唯一缺點是,您現在必須在另一行代碼中設置對象的位置,而不是像以前那樣設置Instantiate
函數。
Transform newHealthContainerTransform = Instantiate(healthWrapperObject, healthBar, false).transform;
newHealthContainerTransform.GetComponent<RectTransform>().anchoredPosition3D = new Vector2(x, y);
移動UI對象時,您應該修改它的RectTransform
變量而不是Transform
變量。
以下是確定UI放置位置的其他有用變量:
這些是anchoredPosition
, anchoredPosition3D
, anchorMax
和anchorMin
可以與被修飾:
yourUIObj.GetComponent<RectTransform>().anchoredPosition = ...
yourUIObj.GetComponent<RectTransform>().anchoredPosition3D = ...
yourUIObj.GetComponent<RectTransform>().anchorMax = ...
yourUIObj.GetComponent<RectTransform>().anchorMin = ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.