Health Bar Not Working Correctly

Godot Version

4.3

Question

Godot health bar not working

I was following this tutorial https://youtu.be/n8D3vEx7NAE?t=2372 and at 39:29 I tested the health bar and it went from 100% to 63% to 0% then it would reset the player and health bar back to 100.

Video of issue

code for world:

extends Node3D

@onready var main_menu = $CanvasLayer/MainMenu
@onready var address_entry  = $CanvasLayer/MainMenu/MarginContainer/VBoxContainer/AdressEntry
@onready var hud = $CanvasLayer/Hud
@onready var health_bar = $CanvasLayer/Hud/HealthBar

const PORT = 9999
var enet_peer = ENetMultiplayerPeer.new()
const Player = preload(“res://player.tscn”)

func _unhandled_input(event: InputEvent) → void:
if Input.is_action_just_pressed(“quit”):
get_tree().quit()

func _on_host_button_pressed() → void:
main_menu.hide()
hud.show()

enet_peer.create_server(PORT)
multiplayer.multiplayer_peer = enet_peer
multiplayer.peer_connected.connect(add_player)

add_player(multiplayer.get_unique_id())

func _on_join_button_pressed() → void:
main_menu.hide()
hud.show()

enet_peer.create_client("localhost", PORT)
multiplayer.multiplayer_peer = enet_peer

func add_player(peer_id):
var player = Player.instantiate()
player.name = str(peer_id)
add_child(player)
if player.is_multiplayer_authority():
player.health_changed.connect(update_health_bar)

func update_health_bar(health_value):
health_bar.max_value = 3
health_bar.value = health_value

func _on_multiplayer_spawner_spawned(node: Node) → void:
if node.is_multiplayer_authority():
node.health_changed.connect(update_health_bar)

code for player:

extends CharacterBody3D

signal health_changed(health_value)

@onready var camera = $Camera3D
@onready var anim_player = $AnimationPlayer
@onready var muzzle_flash = $"Camera3D/357/MuzzleFlash"
@onready var raycast = $Camera3D/RayCast3D

var health = 3

const SPEED = 10
const JUMP_VELOCITY = 7

func _enter_tree():
	set_multiplayer_authority(str(name).to_int())


func _ready() -> void:
	if not is_multiplayer_authority(): return
	
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	camera.current = true
	
func _unhandled_input(event):
	if not is_multiplayer_authority(): return
	
	if event is InputEventMouseMotion:
		rotate_y(-event.relative.x * .005)
		camera.rotate_x(-event.relative.y * .005)
		camera.rotation.x = clamp(camera.rotation.x, -PI/2, PI/2)
		
	if Input.is_action_just_pressed("shoot") and anim_player.current_animation != "shoot":
		play_shoot_effects.rpc()
		if raycast.is_colliding():
			var hit_player = raycast.get_collider()
			hit_player.receive_damage.rpc_id(hit_player.get_multiplayer_authority())
	
func _physics_process(delta: float) -> void:
	if not is_multiplayer_authority(): return
	
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("left", "right", "up", "down")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)
	
	if anim_player.current_animation == "shoot":
		pass
	elif input_dir != Vector2.ZERO and is_on_floor():
		anim_player.play("move")
	else:
		anim_player.play("idle")

	move_and_slide()

@rpc("call_local")
func play_shoot_effects():
	anim_player.stop()
	anim_player.play("shoot")
	muzzle_flash.restart()
	muzzle_flash.emitting = true
	
@rpc("any_peer")
func receive_damage():
	health -= 1
	if health <= 0:
		health = 3
		position = Vector3(0, 5, 0,)
	health_changed.emit(health)

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
	if anim_name == "shoot":
		anim_player.play("idle")

so far the code it works fine, shoot a player 3 times and they die, its probably some simple error that I don’t know about. But if you figure it out please let me know.

It seems like at the bottom of the player script this If statement is causing the player to regain health

if health <= 0:
   health = 3

I’m not sure if this reset of the health is intentional or not, nor do I quite understand what your issue seems to be, if this didn’t help I’d like more context about what you’re trying to get working.

2 Likes

I added a video showing the issue with the health bars

You have a multiplayer game, and your code update_health_bar() is not tagged as an @rpc call. So it’s most likely just getting another player’s health bar value passed to it.