- Edited
Hi everyone, this is my first post here so forgive me if I'm not clear enough on my question!
In short, I am working on a multiplayer project that uses P2P multiplayer. I have got it setup and working fine and am able to spawn players to the server as well as have their animations play according to their inputs. I've been working on implementing a "pickup/drop" weapon system where if a player's ray-cast is close enough to a weapon they can pick it up and it attaches to their hand.
What I'm having an issue with is actually having the weapon attach to the players hand and the weapon be replicated for all players.
My scripts for the weapons are a slightly modified version of StayAtHomeDev's modular weapon script. Basically the weapons take the values from a 'Weapons' resource (such as the mesh) and apply it on ready.
On the weapon, there is an attached script 'InteractableWeapon.gd' that handles the picking up:
class_name InteractableWeapon
extends Interactable
#weapon scene that gets instantiated on player's hand
const NEW_WEAPON = preload("res://packed scenes/weapon_equip.tscn")
#returns the weapon type that was picked up
func get_weapon_type() -> Weapons:
print("Picked up " + owner.WEAPON_TYPE.name)
var weapon_type = owner.WEAPON_TYPE
return weapon_type
#called when player uses interaction button
@rpc("any_peer", "call_local")
func pickup_weapon(hand):
var new_weap = NEW_WEAPON.instantiate()
hand.add_child(new_weap, true) #adds weapon to player's hand
new_weap.WEAPON_TYPE = get_weapon_type() #assigns weapon type from weapon that was picked up
new_weap.name = str(new_weap.WEAPON_TYPE) + str(hand.owner.name) + str(randi_range(0,1000))
new_weap.load_weapon()
remove_weapon()
This script works with the players interaction ray cast script:
extends RayCast3D
@onready var prompt = $"../../../UserInterface/InteractionPrompt"
func _ready():
add_exception(owner)
func _physics_process(_delta):
if is_colliding():
var interactable_collider = get_collider()
if interactable_collider is Interactable:
if !is_multiplayer_authority(): return
prompt.text = interactable_collider.get_prompt()
if Input.is_action_just_pressed(interactable_collider.prompt_action):
interactable_collider.interact.rpc(owner)
if interactable_collider is InteractableWeapon:
interactable_collider.pickup_weapon.rpc(owner.right_hand)
else:
prompt.text = ""
As it is now, when the player picks up the weapon it correctly adds it to the player's right hand. However, the other players don't see the instantiated weapon in the player's hand and their game crashes.
I get the error: Invalid call. Nonexistent function 'add_child' in base 'EncodedObjectAsID'.
I've tried many different things, and was able to replicate the picked up weapon for all players using a MultiplayerSpawner, but only when I add it to the world using get_tree().root.add_child(new_weap, true)
. When doing this, I've attempted to reparent it, but with no luck.
Any help would be greatly appreciated.