Godot Version
Godot 4.6.2
Question
I create a bullet, and both players see it. It flies, crashes into another player, but the player doesn’t take any damage, and errors occur.
Bullet code:
extends CharacterBody3D
@export var SPEED = 1
@export var target_position = position
@export var attack = 10
@export var attack_type = []
var parent = null
@rpc("any_peer","call_local")
func rpcattack():
if target_position != null:
var look_position = Vector3(target_position.x, target_position.y, target_position.z)
look_at(look_position, Vector3.UP)
target_position.y = position.y
var direction_to_target = target_position - position
direction_to_target = direction_to_target.normalized()
if direction_to_target.length() > 0:
velocity.x = direction_to_target.x * SPEED
velocity.z = direction_to_target.z * SPEED
if position.distance_to(target_position) <= 0.2:
queue_free()
move_and_slide()
# Уничтожаем пулю при столкновении с чем угодно
if get_slide_collision_count() > 0:
var collision = get_slide_collision(0)
var collider = collision.get_collider()
# Урон мобам
if collider.name == "Mob" or collider.name == "Player":
if collider != parent:
collider.HP -= attack
queue_free()
var count = false
func _physics_process(delta):
if !count:
count = true
rpc("rpcattack")
await get_tree().create_timer(0.1).timeout
count = false
Errors (they repeat themselves):
E 0:00:16:099 get_node: Node not found: "Map/Bull" (relative to "/root").
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> scene/main/node.cpp:1963 @ get_node()
E 0:00:16:099 get_cached_object: Failed to get cached node from peer 1 with cache ID 3.
<C++ Error> Parameter "node" is null.
<C++ Source> modules/multiplayer/scene_cache_interface.cpp:291 @ get_cached_object()
E 0:00:16:099 process_rpc: Invalid packet received. Requested node was not found.
<C++ Error> Parameter "node" is null.
<C++ Source> modules/multiplayer/scene_rpc_interface.cpp:209 @ process_rpc()
Is the bullet on the correct physics layer and mask to detect all players?
very very strange control flow you have here. using await in _physics_process is almost always a bad idea, if you want something to fire every 0.1 seconds it should use a timer. But your 0.1 function rpcattack uses move_and_slide which should run every frame in _physics_process, and not through an @rpc. Keep your @rpc as small as possible, do movement in _physics_process and only @rpc when something is hit and the bullet needs to be destroyed/do damage.
Actually you shouldn’t use a Timer or get_tree().create_timer() if you want something to reliably run at an interval of less than half a second. You’ll need to decrement the code in the physics frame by delta and tack the time that way, then fire off you code.
EDIT: Nvm, it’s 0.05 seconds, not 0.5 seconds.
I changed it so that the player dies, but there are errors.
Code:
@rpc("any_peer","call_local")
func rpcattack(collider):
if collider != null:
collider.HP -= attack
var count = false
func _physics_process(delta):
if target_position != null:
var look_position = Vector3(target_position.x, target_position.y, target_position.z)
look_at(look_position, Vector3.UP)
target_position.y = position.y
var direction_to_target = target_position - position
direction_to_target = direction_to_target.normalized()
if direction_to_target.length() > 0:
velocity.x = direction_to_target.x * SPEED
velocity.z = direction_to_target.z * SPEED
if position.distance_to(target_position) <= 0.2:
queue_free()
move_and_slide()
# Уничтожаем пулю при столкновении с чем угодно
if get_slide_collision_count() > 0:
var collision = get_slide_collision(0)
var collider = collision.get_collider()
# Урон мобам
if collider is CharacterBody3D:
if collider != parent:
rpc("rpcattack", collider)
queue_free()
Errors:
E 0:00:15:577 get_node: Node not found: "Map/Bull" (relative to "/root").
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> scene/main/node.cpp:1963 @ get_node()
E 0:00:15:577 process_simplify_path: Parameter "node" is null.
<C++ Source> modules/multiplayer/scene_cache_interface.cpp:116 @ process_simplify_path()
E 0:00:15:577 _process_get_node: Failed to get path from RPC: Map/Bull.
<C++ Source> modules/multiplayer/scene_rpc_interface.cpp:146 @ _process_get_node()
E 0:00:15:577 process_rpc: Invalid packet received. Requested node was not found.
<C++ Error> Parameter "node" is null.
<C++ Source> modules/multiplayer/scene_rpc_interface.cpp:209 @ process_rpc()
E 0:00:15:577 process_simplify_path: Parameter "node" is null.
<C++ Source> modules/multiplayer/scene_cache_interface.cpp:116 @ process_simplify_path()
E 0:00:17:543 rpcattack: Invalid access to property or key 'HP' on a base object of type 'EncodedObjectAsID'.
<GDScript Source>bull.gd:12 @ rpcattack()
<Stack Trace> bull.gd:12 @ rpcattack()
I don’t quite understand what they mean, can you explain them to me?
This error mean one of your players cannot find the bullet (assuming it’s name is “Bull”), how are you spawning bullets? Do you make sure to give them readable names?
This error means the rpc’s collider is null, which will happen if you try to feed Resource and Node types to an RPC. You cannot send the whole collider through the network, and if you could it would be a different collider than the other machines. This is why so much of the High-level Multiplayer is based on paths and keeping them the same, if all players have the exact same scene tree you can pass node paths through the network and clients can discern which nodes to use without sending a ton of data.
@rpc("any_peer","call_local")
func rpcattack(collider_path: NodePath):
var collider: Node = get_node(collider_path)
if collider != null:
collider.HP -= attack
## etc ...
if collider is CharacterBody3D:
if collider != parent:
rpcattack.rpc(collider.get_path())
Even with this approach, the errors remain. Can you suggest a way to get rid of them? I have no idea how to fix this.
P.s. The errors do not affect the execution of the code, so can they be hidden somehow?
I’m trying to figure out where I’m making mistakes, but I’m finding more and more flaws in my game that are related to multiplayer. I’ve come to the conclusion that my knowledge level is still far from online gaming. I’m going to try to redo the project with a focus on multiplayer from the start, but I don’t think it’s going to work out. I’m going to try making small 2D games with multiplayer to get better at it.