Disable Rotation for a RigidBody2D's child

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jarlowrey
:warning: Old Version Published before Godot 3 was released.

My rigid bodies have a health bar, which should track the body’s position without rotating with it. I have it instanced as a child of the Rigid Body, but rotations are applied to children as well. Should I reset the rotation on every frame (ie inside of _process), or is there a more elegant and efficient way to do this?

I don’t think that there is any significant performance impact when you rotate back the progress bar every frame. But do it in _fixed_process because the progress bar may not be in sync with the player otherwise.

timoschwarzer | 2017-06-03 05:13

:bust_in_silhouette: Reply From: BertiRean

I think a better option, is have a reference node of the progress bar, in the script of your RigidBody and send a signal from one node to another, when necessary a change in the life bar.

Is there a signal for position change?

jarlowrey | 2017-06-01 14:33

:bust_in_silhouette: Reply From: Santiago

Hi, I’m kinda new to godot but I’d like to help.

You could use a Sprite3D, set it as a child of your rigid body, and set the material of the sprite to billboard, then in material override - material flags you may need to turn on certain flags like “on top”, “unshaded” and “invert faces”; “on top” will render the Sprite3D over everything else, “unshaded” for ignoring light sources and “invert faces” may be needed if the normal is pointing backwards.

The key element is Billboard flag on your Sprite3D-Geometry Instance-Geometry settings in the inspector.

Other thing: I don’t really know why but you have to set textures both on your Sprite3D and it’s Material override diffuse, don’t know why but it seems to not render at all if I don’t set textures on both.

[EDIT]
this is the code for your health bar script

extends Sprite

func _ready():
    set_process(true)

func _process(delta):
    var parent = get_node("../Node2D")  # put here your player's node path
    var offset = Vector2(0, -100) # simple offset for the health bar, 
    self.set_pos(parent.get_pos()+offset)

just make sure your health bar is a brother node of your player node

Sounds interesting, but I’m trying to work in 2D with progress bars. Would using 3D somehow disable rotation?

jarlowrey | 2017-06-01 14:34

I’m really sorry, Don’t know how but I thought you were working on 3d.

In that case you would parent the health bar to the player’s parent, to make it a brother node let’s say, and put this script on the health bar:

extends Sprite

func _ready():
	set_process(true)

func _process(delta):
	var parent = get_node("../Node2D")  # put here your player's node path
	var offset = Vector2(0, -100) # simple offset for the health bar, 
	self.set_pos(parent.get_pos()+offset)

I’m assuming your health bar is a simple 2d sprite, and in that case, you can set the offset from the inspector, if it’s a node2D you can use the offset from the script.

Hope this helps, and sorry for my misunderstanding :smiley:

Santiago | 2017-06-02 11:48

:bust_in_silhouette: Reply From: jarlowrey

What I ended up doing:

First I had my node be a child of the Rigid Body and reset the rotation every physics step using _fixed_process. Then I decided to make it a sibling of the RigidBody2D and set the position every _fixed_process instead.

This should be a little bit faster (flattens RigidBody2D’s children a bit, saves rotating then resetting it), but more importantly is simpler and easier to work with in my current game’s architecture. Thanks for the answers everyone.

:bust_in_silhouette: Reply From: lvknd

Simple, no code approach: Draw health bar over enemies - Archive - Godot Forum