Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

[SOLVED] How to stop health bar from rotating weirdly?

Discussion in 'Scripting' started by PlazmaInteractive, Sep 10, 2016.

  1. PlazmaInteractive

    PlazmaInteractive

    Joined:
    Aug 8, 2016
    Posts:
    114
    Hello guys, I've got a health bar system set up from Brackey's tutorial. Apparently, in his one, the enemy doesn't rotate so he doesn't have to worry about health bar's rotation but my one rotates weirdly. Even when I force it to stop rotating through script, it still rotates in a weird way. Another weird thing about this is that, in other enemies, the rotation isn't happening. Only when I tried to create a new one in different size, this problem occur although every thing is set up the same. Basically, the only thing I can do right now is to duplicate an existing enemy that has a non-buggy health bar and change its colour and script to make a different enemy but that's not what I want.

    Here's the code that stops it from rotating:
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class StatusIndicator : MonoBehaviour
    6. {
    7.     public RectTransform healthBarRect;
    8.  
    9.     private Quaternion rotation;
    10.     private Vector3 position;
    11.  
    12.     void Awake()
    13.     {
    14.         rotation = transform.rotation;
    15.         position = transform.parent.position - transform.position;
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         transform.rotation = rotation;
    21.         transform.position = transform.parent.position - position;
    22.     }
    23.  
    24.     public void SetHealth(float _cur, float _max)
    25.     {
    26.         float value = _cur / _max;
    27.  
    28.         healthBarRect.localScale = new Vector3(value, healthBarRect.localScale.y, healthBarRect.localScale.z);
    29.     }
    30. }
    A GIF showing the weird rotation (edit: bugged enemy is orange one if you don't know, health bar is at the top of the enemy):
    giphy.gif
    And a screenshot of the StatusIndicator (the canvas where the HealthBar image is located in):
    Capture.PNG
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I assume the helathbar is a child of the ship. Your code isn't working because the Healthbar's rotation is never changing. In its local space its rotation is always 0,0,0. However, since its a child of some other transform, unity changes HealthBar's position / rotation into its parent's local space (which is rotated) before moving onto worldspace.

    You have two options:
    • Make the healthbar a root level object, and get a handle on the ship its suppose to be associated with. Then each update just move it directly above the ship
    • Every update make its rotation a negative value of the parent's rotation. This is slightly more complicated if the parent's rotation isn't 0 to start with. You need to make the healthbar's rotation a negative of the parent's (currentRotation-OriginalRotation).
     
  3. Lethn

    Lethn

    Joined:
    May 18, 2015
    Posts:
    1,583
    Am I wrong in thinking you could just do a trigger rigidbody ( Or have some other way of disabling the collision ) and still keep the healthbar as a child? You could then freeze the rotation so it doesn't do that anymore, that should work to keep it the same rotation the whole way without any coding needed.
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I don't think collision have anything to do with why the child of an object rotates with its parent.

    Lets say I have some Game Object SomeGuy. He has a position and a rotation. He's a root level Object, so if I change his transforms position or rotation, I"m moving and rotating him in the world.

    I now attach a Game Object Gun as a child of SomeGuy. I set its rotation to 0,0,0.
    If in an Update call I rotate my SomeGuy object 45 degrees right, I want my gun to rotate the same amount. If you look at Guy his Y rotation will be 45, but the Gun's rotation will still be 0,0,0. This is because the Gun's position and rotation are always relative to his parent, not the world.

    This is good and intended behaviour. If I rotate SomeGuy, I don't want to have to go through all of SomeGuy's Children and rotate them as well. So unity transforms any child's localspace into its parent's localspace, thus getting all the poistion and rotational changes you made to the parent. That way you can attach all kinds of things to your guy and they will move and rotate with him.

    However, since the HealthBar is a child of the ship it will rotate just like the ship does. (which we don't want). Imagine the Helathbar was a gun mount pointing forward.. we would want it to rotate with the ship. So overall Unity does what we need it to do for children. Just in this case if you make HealthBar a child of the ship, rather than an overlay you have to compensate for that.
     
  5. PlazmaInteractive

    PlazmaInteractive

    Joined:
    Aug 8, 2016
    Posts:
    114
    Alright, so what you meant by option 1 was this right?
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Test : MonoBehaviour
    5. {
    6.     public Transform ship;
    7.  
    8.     void Update()
    9.     {
    10.         if(ship == null)
    11.         {
    12.             Destroy(gameObject);
    13.         }
    14.         else
    15.         {
    16.             transform.position = ship.position + transform.up * 0.8f;
    17.         }
    18.     }
    19. }
    I had to look up what root level object is because I'm unfamiliar with that terminology. So anyways, option 1 seems to work if I make an empty gameobject to place my health bar and enemy ship in. The empty gameobject stays static, while the enemy ship moves around normally and the health bar moves above the ship through the script.
     
    hassonhamo3 likes this.
  6. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Yep thats exactly what i meant. When I said root Level, i just meant a GameObject that wasn't the child of anything.
     
  7. hassonhamo3

    hassonhamo3

    Joined:
    May 25, 2018
    Posts:
    38
    you helped me alot ! thanks brother