Im using META Datas to to assign picked up items to the one holding it, after you pick it up, the owner Meta of the objekt sets to the peer id
@rpc("any_peer", "call_local")
func pick_up_item(item_name: String, texture: Texture):
var slots = [item_name_slot_1, item_name_slot_2, item_name_slot_3, item_name_slot_4]
var free_slot = -1
var base_name = get_base_item_name(item_name)
if base_name in item_scenes:
var new_item = item_scenes[base_name].instantiate()
new_item.set_meta("original_name", item_name)
new_item.set_meta("owner_id", multiplayer.get_unique_id())
for i in range(slots.size()):
if slots[i] == null:
free_slot = i
break
if free_slot == -1:
print("❌")
return
match free_slot:
0:
item_name_slot_1 = item_name
$Hotbar/HBoxContainer/item_slot_1.texture = texture
1:
item_name_slot_2 = item_name
$Hotbar/HBoxContainer/item_slot_2.texture = texture
2:
item_name_slot_3 = item_name
$Hotbar/HBoxContainer/item_slot_3.texture = texture
3:
item_name_slot_4 = item_name
$Hotbar/HBoxContainer/item_slot_4.texture = texture
if is_instance_valid(pick_up_object):
var object_path = pick_up_object.get_path()
rpc("remove_object", object_path)
else:
print("❌")
func instantiate_item(item_name: String, player_id: int):
print("📌 instantiate_item called by Player:", player_id, " Item:", item_name)
var base_name = get_base_item_name(item_name)
if base_name in item_scenes and item_scenes[base_name] != null:
var item_scene = item_scenes[base_name]
var new_item = item_scene.instantiate()
if new_item == null:
print("❌")
return
new_item.set_meta("original_name", item_name)
new_item.set_meta("owner_id", player_id)
new_item.name = item_name
$nek/head/eyes/Camera3D.add_child(new_item)
adjust_item_position(new_item)
player_held_items[player_id] = new_item
print("✅ Item instantiated for:", player_id, " Besitzer:", new_item.get_meta("owner_id"))
else:
print("⚠️")
Ok so I’ve changed it to Multiplayer Authority instead of working with owner_id in Meta data…but the error is the same.
func receive_damage_pre_function(player_id):
print("receive_damage_pre_function called by: ",multiplayer.get_unique_id())
print("local ID: ",multiplayer.get_unique_id(), " received player_id from pistol script: ", player_id)
rpc_id(player_id,"receive_damage", player_id)
@rpc
func receive_damage(player_id):
print("receive_damage was called by peer: ", multiplayer.get_unique_id())
var local_id = multiplayer.get_unique_id()
print(player_id, " reached receive_damage")
print(local_id, " is the peer ID")
if player_id == local_id:
print(multiplayer.get_unique_id(), " is the correct peer in which this function should happen locally")
health -= 1
_damage_sprite()
print(player_id)
print("Player: ", player_id, " has left: ", health)
if health <= 0:
print(player_id, " died")
position = Vector3.ZERO
rpc("spawn_ghost", player_id)
func _damage_sprite():
print("damage sprite is called locally on client: ", multiplayer.get_unique_id())
damage_sprite.show()
if Input.is_action_just_pressed("debug"):
_damage_sprite()
ive also added a debug key to just test the function locally
And it works as intended, just not in the RTP case.
Pistol Script:
extends StaticBody3D
@onready var pistol_shoot_sound = $Pistol/AudioStreamPlayer3D_Pistol
@onready var pistol_animations: AnimationPlayer = $Pistol/Pistol_Animation
@onready var muzzle_flash: GPUParticles3D = $Pistol/Muzzleflash
var bullet_raycast = null
var pistol_equipped = false
func _input(event):
if event.is_action_pressed("shoot"):
var owner_id = get_multiplayer_authority()
if owner_id == multiplayer.get_unique_id():
rpc("fire")
@rpc("any_peer", "call_local")
func fire():
if pistol_animations.current_animation == "shoot":
return
print("🔥", self.name, "FEUERT!")
rpc("play_shoot_effects_rpc")
# Hole die Multiplayer-ID des Schützen
var owner_id = get_multiplayer_authority()
# Hol den richtigen Raycast für diesen Spieler aus dem SignalBus
var raycast = SignalBus.get_bullet_raycast(owner_id)
if raycast and raycast.is_colliding():
var hit_object = raycast.get_collider()
if hit_object != null:
print("🎯", hit_object.name, "getroffen")
if hit_object.is_in_group("Players"):
var player_id = hit_object.get_multiplayer_authority()
SignalBus.emit_signal("player_hit", player_id)
else:
print("❌ Kein Treffer!")
else:
print("❌ Kein Treffer! (Raycast hat nichts getroffen)")
@rpc("any_peer", "call_local")
func play_shoot_effects_rpc():
pistol_shoot_sound.play()
pistol_animations.play("shoot")
muzzle_flash.restart()
muzzle_flash.emitting = true
Im really confused right now lol
Honestly if you like to I can upload this whole project and you can have a look into it. Im struggeling to fix this since 2 weeks.
EDIT: So I think it has something to do with how the authority is handled. When I press
if Input.is_action_just_pressed("debug"):
_damage_sprite()
when a client presses _damage_sprite(), it shows the damage sprite to all players at least from the clients perspective, from the other’s perspective its not there. so I think slowly i get the hang of the problem. Its kinda like a client tries to change a node from the other clients/hosts but isnt allowed to. So basically everyone is using the same player scene, and if you change a node at least locally it is synchronized to the others but only visible to the one changing it. Ive managed to solve this one by adding the visibility to the multiplayersynchronizer. but im still unable to do it in the rtp function