basically when I spawn a bullet node in my multiplayer godot game I get these errors:get_node: Node not found and get_cached_object: Failed to get cached path: /root/main/607851477/Bullet/MultiplayerSynchronizer. my bullets code is:
@onready var sprite2d = $Sprite2D
@onready var deathtimer = %deathtimer
var speed = -560
# Called when the node enters the scene tree for the first time.
func _ready():
sprite2d.show()
deathtimer.start()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
position += transform.x * speed * delta
func _on_body_entered(body):
if not body.is_in_group("player"):
queue_free()
func _on_deathtimer_timeout():
sprite2d.hide()
queue_free()```
**PLAYER CODE**
extends CharacterBody2D
var health = 10
@onready var cooldown = %Cooldown
var canshoot = true
func _enter_tree():
set_multiplayer_authority(str(name).to_int())
@onready var camera = %Camera2D
const SPEED = 330.0
const JUMP_VELOCITY = -400.0
@onready var main = $"."
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
func _physics_process(delta):
if not is_multiplayer_authority(): camera.enabled = false
if is_multiplayer_authority():
if Input.is_action_pressed("use_shoot") && canshoot == true:
rpc("shoot")
canshoot = false
cooldown.start()
#if not is_multiplayer_authority(): return
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle jump.
if is_multiplayer_authority():
if Input.is_action_pressed("i_up") 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 direction = Input.get_axis("i_left", "i_right")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
func take_damage(amount):
print("YOUCH")
print("YOUCH")
health -= amount
if health <= 0:
queue_free()
@rpc("any_peer", "call_local", "reliable")
func shoot():
var bullet = preload("res://scenes/bullet.tscn").instantiate()
add_child(bullet)
bullet.position = self.global_position
bullet.rotation = bullet.global_position.angle_to_point(get_global_mouse_position())
bullet.rotation_degrees += -90
func _on_area_2d_body_entered(body):
if body.is_in_group("Arbullet"):
queue_free()
func _on_cooldown_timeout():
canshoot = true
Are the errors always immediate or does it ever work normally? My guess is that maybe it’s trying to synchronize something that’s been deleted already.
That’s how I handled spawning in a recent multiplayer project:
You might not need to worry about it if using a MultiplayerSpawner but I ran into issues related to the automatic Node-naming Godot performs. Basically the names of Nodes created in-game would sometimes become out of sync for some clients which would cause errors calling RPC methods. I was able to fix it by just manually naming any Nodes with scripts containing RPC methods.
If you’re manually spawning the bullets, you’d need some kind of authority (such as on the server) that just assigns a number as an id. It can be incremented for each bullet spawned. A lot more annoying than using the MultiplayerSpawner so I’d exhaust that option first but is something you could try.
If you don’t need to sync the bullet position exactly, you could also just send out an event that a bullet was spawned at some position, angle, and speed. Kind of just depends on the use case.
Ok, I think I can make this work, this may be my solution, thanks so much, ok so I kinda do what you did for meatball games? your thing installs a different ID for every player?
Well making even simple games in general can be tricky and adding multiplayer complicates things quite a bit so don’t beat yourself up too much. There’s nothing wrong with you.
@rpc("authority", "call_local", "reliable")
func shoot():
if multiplayer.is_server():
A couple of things here: Declaring the variable bullet_id in this function will happen each time the function is called. This means that it will always equal 1. Second, it checks if the game is the server before creating the bullet so noone but the server will ever create any bullets.
Here’s a basic example that can hopefully help out. The bullets positions aren’t synced constantly, only when they are created but they still sync pretty well.