Invalid get index 'receive_damage' (on base: 'staticbody3d')

Godot Version

4.2

Question

hi, so I am making an fps game. then i started on the kill part, but now it is giving me an error for invalid get index 'receive_damage' (on base: 'staticbody3d'). , eventhough I am using an playerbody3d. can someone help me.

Here is the code:

extends CharacterBody3D


const BASE_FOV = 100.0
const FOV_CHANGE = 3.5

var speed
var CROUCH_SPEED = 3
var crouch_speed = 3
const WALK_SPEED = 6.2
const SPRINT_SPEED = 8.0
const JUMP_VELOCITY = 5.5
const sensitvity = 0.01
const SPEED_SPRINT = 10.0
var default_height = 1.5
var crouch_height = 0.3
const bob_freq = 2.3
const bob_amp = 0.08
var t_bob = 0.0
var health = 200

#fov DONT TOUCH UNLESS NECCESARY
#load bullets
var instance


@onready var head = $Neck
@onready var camera = $Neck/Camera3D
@onready var collision = $CollisionShape3D
@onready var headbonker = $HeadBonker
@onready var Aimcast = $Neck/Camera3D/hand/AimCast
@onready var animshoot = $AnimationPlayer


# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = 9.8

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



func _ready():
	var player_controlled := is_multiplayer_authority()
	camera.current = player_controlled
	set_process_unhandled_input(player_controlled)
	set_physics_process(player_controlled)


func _unhandled_input(event):
	if event is InputEventMouseMotion:
		head.rotate_y(-event.relative.x * sensitvity)
		camera.rotate_x(-event.relative.y * sensitvity)
		camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40),deg_to_rad(60) )
		
		
	if event is InputEventMouseButton:
		Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	elif event.is_action_pressed("ui_cancel"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)


func fire():
		if Input.is_action_pressed("fire"):
			if not animshoot.is_playing():
				if Aimcast.is_colliding():
					var hit_player = Aimcast.get_collider()
					hit_player.receive_damage.rpc_id(hit_player.get_multiplayer_authority)
			animshoot.play("Shoot")
		else:
			animshoot.stop()

		

func _physics_process(delta):
	fire()
	
	

				
	if Input.is_action_just_pressed("quit"):
		$"../".exit_game(name.to_int())
		get_tree().quit()


	
	#print(stanima)
	if not is_on_floor():
		velocity.y -= gravity * delta

	if headbonker.is_colliding():
		collision.shape.height -= crouch_speed * delta 
		collision.shape.height = clamp(collision.shape.height, crouch_height, default_height)

	# Handle jump.
	if is_on_floor() or is_on_wall():			
		if Input.is_action_just_pressed("Jump"):
			velocity.y = JUMP_VELOCITY
		
	

	if Input.is_action_pressed("sprint"):
		speed = SPRINT_SPEED
	elif headbonker.is_colliding():
		speed = CROUCH_SPEED
	else:
		speed = WALK_SPEED

	if Input.is_action_pressed("crouch"):
		speed = CROUCH_SPEED
		collision.shape.height -= crouch_speed * delta 
	else:
		collision.shape.height += crouch_speed * delta
		
	collision.shape.height = clamp(collision.shape.height, crouch_height, default_height)



	# 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", "forward", "back")
	var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if is_on_floor():
		if direction:
			velocity.x = direction.x * speed
			velocity.z = direction.z * speed
		else:
			velocity.x = lerp(velocity.x, direction.x * speed, delta * 7.0)
			velocity.z = lerp(velocity.z, direction.z * speed, delta * 7.0)
		
	else:
		velocity.x = lerp(velocity.x, direction.x * speed, delta * 2.0)
		velocity.z = lerp(velocity.z, direction.z * speed, delta * 2.0)
	
	t_bob += delta * velocity.length() * float(is_on_floor())
	camera.transform.origin = _headbob(t_bob)


	#fov
	var velocity_clamped = clamp(velocity.length(), 0.5, SPRINT_SPEED * 2)
	var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
	camera.fov = lerp(camera.fov, target_fov, delta * 8)



	move_and_slide()



func _headbob(time) -> Vector3:
	var pos = Vector3.ZERO
	
	pos.y = sin(time * bob_freq) * bob_amp 
	pos.x = cos(time * bob_freq / 2) * bob_amp
	return pos
	
@rpc("any_peer")
func receive_damage():
	health -= 100
	if health <= 0:
		health = 200
		position = Vector3.ZERO

Aimcast collides with a StaticBody not a CharacerBody. I guess you’re hitting the floor or wall instaed of a player?

You can check if the hit object actually has a recieve_damage function before you try to call it, to avoid errors like this:

if hit_player.has_method("receive_damage"):
    hit_player.receive_damage.rpc_id(hit_player.get_multiplayer_authority)
2 Likes

ok now it does not crash. But it does not kill the other player

Because you’re not hitting the other player, you’re hitting a StaticBody. If you’re aiming at the other player but not hitting it then either there’s an issue with your raycast that checks what you’re aiming at, or it’s some multiplayer issue, but I don’t know anything about that…

1 Like

well I will see if i can figure it out
thanks though

get_multiplayer_authority is missing parenthesis, I feel like this should give an error so maybe you have not hit this yet.

hit_player.receive_damage.rpc_id(hit_player.get_multiplayer_authority())

what do you mean by parenthesis?

() used to call a function, instead of calling the function to find which player is the authority you are passing the function itself which is useless.

func get_authority() -> int:
    return 1337

print(get_authority()) # 1337
print(get_authority) # CharacterBody3D(player.gd)::get_authority

hi I fixed the issue, my raycast was on a different collision mask than the player