I have a GameObject named Player, and a Canvas. The HealthBar GameObject is a child of the Canvas (Canvas>HealthBar). I have the HP bar following the player with a script. It is supposed to follow the player at a fixed position above it, so it sits near the top of the sprite. Here is the 'follow' part of the HP Follow Script.
void Update ()
{
Vector3 currentPos = transform.position;
Vector3 playerPos = Camera.main.WorldToViewportPoint (Player.transform.position);
transform.position = playerPos;
The problem is that the HP bar moves with the character, but at a very small fraction of the speed of which the player is moving. For example, if the player moves one unit, the bar moves 0.1 units.
Video of error: https://streamable.com/vaz7h
Set the Canvas to World SpaceSelect your Canvas and change the Render Mode to World Space. Now your Canvas is already positioned in the World and can be seen by all cameras if they are pointed at it, but it is probably huge compared to other objects in your Scene.
For a non-stretching Rect Transform, the position is set most easily by setting the anchoredPosition and the sizeDelta properties. The anchoredPosition specifies the position of the pivot relative to the anchors. The sizeDelta is just the same as the size when there's no stretching. Save this answer.
The Canvas is the basic component of Unity UI. It generates meshes that represent the UI Elements placed on it, regenerates the meshes when UI Elements change, and issues draw calls to the GPU so that the UI is actually displayed.
You want to make a UI Object(Image) follow a GameObject is a SpriteRenderer or MeshRenderer.
In another way, this can be described as converting world point to UI point.
This simple function below converts world position to UI space. It takes a the Canvas
of the UI as parameter then the position you want to convert to UI position which in your case is the Player.transform.position
variable.
The key for moving a UI object is the RectTransformUtility.ScreenPointToLocalPointInRectangle
function which converts the screen point to ui rectangle local point.
public Vector3 worldToUISpace(Canvas parentCanvas, Vector3 worldPos)
{
//Convert the world for screen point so that it can be used with ScreenPointToLocalPointInRectangle function
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
Vector2 movePos;
//Convert the screenpoint to ui rectangle local point
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvas.transform as RectTransform, screenPos, parentCanvas.worldCamera, out movePos);
//Convert the local point to world point
return parentCanvas.transform.TransformPoint(movePos);
}
Usage:
public GameObject Player;
public Canvas canvas;
void Update()
{
//Convert the player's position to the UI space then apply the offset
transform.position = worldToUISpace(canvas, Player.transform.position);
}
Now, let's say that you have already positioned the UI to be where it is supposed to be and you now want it to follow another Object(Player), you need to implement a simple offset with the code above. This is really easy. Below is what it is supposed to look like:
public GameObject Player;
public Canvas canvas;
Vector3 Offset = Vector3.zero;
void Start()
{
Offset = transform.position - worldToUISpace(canvas, Player.transform.position);
}
void Update()
{
//Convert the player's position to the UI space then apply the offset
transform.position = worldToUISpace(canvas, Player.transform.position) + Offset;
}
public Vector3 worldToUISpace(Canvas parentCanvas, Vector3 worldPos)
{
//Convert the world for screen point so that it can be used with ScreenPointToLocalPointInRectangle function
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
Vector2 movePos;
//Convert the screenpoint to ui rectangle local point
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvas.transform as RectTransform, screenPos, parentCanvas.worldCamera, out movePos);
//Convert the local point to world point
return parentCanvas.transform.TransformPoint(movePos);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With