I am trying to copy the Zelda health system. The code looks really fine and works fine.
But the heart containers are placed wrong. They get instantiated below the canvas.
This is the important code, the heart containers are correct, just at the wrong position.
The calculation of x and y is correct, but on the canvas it is not.
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
}
}
I added the transform settings for the healthBar, the healthContainer / backgroundImage and the heart ("healthfill").
On all 3 elements I pressed Strg+Alt and Shift for anchoring them.
The heartcontainter should be added to the healthbar, the heart is a child of the heartcontainer and is set to stretch (it should be the same size as its parent)
Why are the UI prefab Objects instantiated below the canvas?
See Question&Answers more detail:os