How do I link an image to a player ?

Hello, how do I link an image, I have a player’s hp bar implemented with it, to the player? I wrote the code where the hp bar is created in the canvas, but the position of the hp bar does not change for the player and the hp bar itself is created at some coordinates that are incomprehensible to me.

    public Image HealthImage;
    public GameObject Canvas;

    private void Start()
    {
        Canvas = GameObject.Find("Canvas");
        Instantiate(HealthImage, Canvas.transform);
    }

    void Update()
    {
        HealthImage.transform.position = new Vector2(gameObject.transform.position.x, gameObject.transform.position.y);
    }

There’s really not enough info here.

  • If the UI is static, put the image next to the health bar and swap out what the player looks like

  • If the UI follows the player, make a single construct including both image and healthbar and move that construct with the player.

  • something else?

For the first two, there are plenty of tutorials for doing those.

For the record, moving individual UI elements at runtime is ALWAYS going to be an ultra-super-crazy hard thing to get right, as it is utterly dependent on canvas render mode, canvas scaling, anchoring and just about 27 other things that all need to be precisely correct in order to manipulate individual UI elements.

As a point of reference, this is what it takes simply to move the anchors to the corners of a RectTransform. It is NOT an easy task. Stick with pre-configured chunks of UI.

// example UI manipulation nightmare code found at:
// http://forum.unity3d.com/threads/script-simple-script-that-automatically-adjust-anchor-to-gui-object-size-rect-transform.269690/
    [MenuItem ("UI/Anchor Around Object")]
    static void AnchorAroundObject() {
        for (int i = 0; i < Selection.gameObjects.Length; i++) {
            GameObject obj = Selection.gameObjects [i];
            if (obj != null && obj.GetComponent<RectTransform> () != null) {
                var rectTransform = obj.GetComponent<RectTransform> ();
                var parentTransform = obj.transform.parent.GetComponent<RectTransform> ();
                var offsetMin = rectTransform.offsetMin;
                var offsetMax = rectTransform.offsetMax;
                var oldAnchorMin = rectTransform.anchorMin;
                var oldAnchorMax = rectTransform.anchorMax;
                var parentWidth = parentTransform.rect.width;
                var parentHeight = parentTransform.rect.height;
                var anchorMin = new Vector2 (oldAnchorMin.x + (offsetMin.x / parentWidth),
                                             oldAnchorMin.y + (offsetMin.y / parentHeight));
                var anchorMax = new Vector2 (oldAnchorMax.x + (offsetMax.x / parentWidth),
                                             oldAnchorMax.y + (offsetMax.y / parentHeight));
                rectTransform.anchorMin = anchorMin;
                rectTransform.anchorMax = anchorMax;
                rectTransform.offsetMin = new Vector2 (0, 0);
                rectTransform.offsetMax = new Vector2 (0, 0);
                rectTransform.pivot = new Vector2 (0.5f, 0.5f);
            }
        }
    }
1 Like

Thanks for the answer, but there is another question:
If the HP bar is made a child for the player, then the HP bar will be outside the canvos and it just won’t be displayed, won’t it? or did I misunderstand you ?

Correct. I did not say make it a child. I said “move that construct with the player.”

Eg, get the screen position of the player and put the health bar there.

Or use world space canvases and put it as a child of the player I suppose… many ways to do this stuff.

1 Like