My problem is that depending where the unit is on the screen the Healthbar is not on the right spot.
I added 2 pictures which show how i want the healthbar and 2 pictures which show how the healthbar is at the moment.
So on the 2. picture the character is at the bottom of the screen and the healthbar is not above the character. it is on the character. can someone point me in the right direction how to solve this? or is the a blog post which anyone knows which shows how to solve this problem?
#3D Unit Healthbar
1 messages · Page 1 of 1 (latest)
First of all, how did you make your health bar?
It it a world-space canvas with a billboard effect, or a screen-space UI element that follows a position on screen?
i made it with world space canvas with billboard effect. like the brackeys tutorial...
but i have no feelings at the current solution since it dosnt work like i want it to work.
You can attach the healthbar to a parent empty gameobject that is at the center of your character model.
That way, when the billboard effect kicks in, the UI rotates around your character (and thus will always "float above" when viewed in the camera), instead of rotating itself.
the rotation is not the problem. the problem is the position on the screen
If you rotate an object around an outside axis, then the position of said object changes…
the healthbar is at the center of the character model
In that case, I would suggest you move the health bar upwards (relative to its looking direction), by an amount determined by its angle to the camera's forward direction.
@crystal haven you mean this angle?
I mean the return value of Vector3.Angle((target.position - camera.position), camera.forward).
target would be the healthbar where the billaboard script is on?
No, target is the object that the health bar floats over.
On further though, you may or may not need to use SignedAngle with camera.right as 2nd parameter. But that depends on the specific behaviour you need.
@crystal haven so you would put the script on the unit object. and then control the position of the canvas with it?
I would put it in the same script that manages the billboard mechanic.
this is atm on the canvas element. so i would reference the unit object from there as "target"
I guess.
the angle kinda works.
when the unit is in the center its close to 0 (guess kinda hard how the control works that its right on 0)
but there is no diffrence when player is left and right or top and bottom of the screen.
That's where the signed angle I described comes in.
Just remember to clamp the value you get from that to stay above 0.
Angle = Vector3.SignedAngle((Target.position - CameraMain.transform.position), CameraMain.transform.forward, CameraMain.transform.right);
atm i have this. but same problem
the angle goes up when player is left or right side of the screen
It's not though? From your screenshot, it's still above your model
You're currently doing the left side.
I said just change the pivot (red dot) to the center, so when it rotates, it will always look "above" the character in the camera view.
Literally no math needed.
red point is position of canvas?
The lower the Canvas (and the higher the healthbar is inside canvas), the further it looks from the model
i think i dont know what you mean. sorry. because i know i need a dynamic healthbar ui element. and doing it without code i dont see how i can solve this problem...
Weird 
SignedAngle should only care about the angle that "rotates" around the axis you give it. So moving the player across the screen horizontally should not change the angle.
@crystal haven this is what it does atm
Could you send your entire billboard code?
@crystal havenits this: https://github.com/Wenish/vland-client-demo/blob/main/Assets/Scripts/Billboard.cs
basicly line 22 its the billboard effect
the function CalculateAngle on line 26 is the angle calculation you proposed
but dosnt get used for more atm
Huh
That really looks like it should work for calculating the angle.
Another possible approach would be to use the Unit's viewport position to extrapolate an offset from.
(use CameraMain.WorldToViewportPoint(Target.position) to get the point, then offset by the point's y component).
will try that one
@crystal haven with that it places the healthbar somewhere off the screen
Are you sure you are using the Unit as your target here, and not the health bar itself?
And how are you adjusting the position, in particular?
private void CalculatePosition()
{
Vector3 screenPos = cameraToLookAt.WorldToViewportPoint(unit.position);
transform.position = screenPos + offset;
}
you probably want to use something like transform.position = unit.position + offset + (transform.up * screenPos.y);
still kinda not right :/
the dont have the same distance to the units
Okay, so:
Right now, health bars will move up and down perpendicular to the camera, by an amount dictated by their units' positions on the screen. the lower the Unit is on the screen, the lower the health bar will be perpendicular to the camera.
Since you want to change this effect, you will need to manipulate screenPos.y before applying it to the position.
That could look somewhat like this: ```cs
Vector3 screenPos = cameraToLookAt.WorldToViewportPoint(unit.position);
screenPos.y = Mathf.Abs(screenPos.y * 2 - 1);
transform.position = unit.position + offset + (transform.up * screenPos.y);
@crystal haven
it still moves relative to the unit
i wish i knew 3d math better 😄
no exactly. at one point of the video (at 0:02) the healthbar is on the unit. so the unit is behind the healthbar. i dont want this behaviour. the healthbar should always have a fixed distance to the unit.
Those are literally not relevant?
oke the healthbar is always on top. the problem with the diffrent distances are still here...
Just play around with the height more I guess.
The difference will be less noticeable once you use an actual model anyway I hope 
i know the diffrence between production and demo is not much but i try to learn production ready code...
Well, game dev 101 is if there’s a simple way, don’t choose the complicated way.