UI预制件在canvas下方实例化

我正在尝试复制塞尔达卫生系统。 代码看起来很好,工作正常。

但心脏容器放错了。 它们在canvas下面实例化。

这是重要的代码,心脏容器是正确的,只是处于错误的位置。

x和y的计算是正确的,但在canvas上却没有。

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 healthContainers = new List(); // 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 = 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()); // get the heart of the heartContainer and add it to the heartList } } 

我添加了healthBar,healthContainer / backgroundImage和heart(“healthfill”)的转换设置。

在所有3个元素上,我按下了Strg + Alt和Shift来锚定它们。

应该将heartcontainter添加到healthbar,心脏是heartcontainer的一个孩子,并设置为伸展(它应该与其父级相同)

为什么UI预制对象在canvas下面实例化?

在游戏中

HealthBar

HealthContainer

HealthObjekt

我假设你得到这样的东西:

在此处输入图像描述

您可以通过将false传递给SetParent函数的第二个参数来解决此问题。 通过这样做,您将使变换保持其本地方向而不是其全局方向。

简单地替换:

 newHealthContainerTransform.SetParent(healthBar); 

有:

 newHealthContainerTransform.SetParent(healthBar, false) 

您还可以设置父对象,并使实例化的Object的Transform在Instantiate函数中保持其本地方向。 这样做的唯一缺点是你现在必须在另一行代码中设置对象的位置而不是像之前那样设置Instantiate函数。

 Transform newHealthContainerTransform = Instantiate(healthWrapperObject, healthBar, false).transform; newHealthContainerTransform.GetComponent().anchoredPosition3D = new Vector2(x, y); 

移动UI对象时,您应该修改它的RectTransform变量而不是Transform变量。

以下是确定UI位置的其他有用变量:

这些是anchorMaxanchorMinanchorMaxanchorMin ,可以修改为:

 yourUIObj.GetComponent().anchoredPosition = ... yourUIObj.GetComponent().anchoredPosition3D = ... yourUIObj.GetComponent().anchorMax = ... yourUIObj.GetComponent().anchorMin = ...