|
|
|
 |
Reply From: |
code |
in your code
you disabled your collison using
"collisionShape".disabled = true
You will have to change that to
"collisionShape.set_deffered("disabled",false)
Deferred has one f and two rs. I don’t usually correct people’s spelling but in this case it matters.
It is not sure he has that in code. I remember getting that error on queuing bodies free. I guess shape disabling happens automatically on deparenting, so remove child and add child might need to be calles deferred ?
thank you Inces, that was it! i changed remove_child
and add_child
in call deferred and now it works without crashes, however it still prints errors sometimes, saying that some random projectile cannot be removed as they are not child of the node, and not added as they already are child of the node.
here the modified code (in the server)
func stick(obj):
$Hit.set_deferred("monitoring",false)
set_process(false)
var pos=global_position-obj.global_position
Spt.rpc_list(self, match_node.match_list.keys(), false,false, "puppet_stick", str(obj.get_path()), pos)
get_parent().call_deferred("remove_child",self)
obj.call_deferred("add_child", self)
position=pos
and these are the 2 new errors (on projectile 88):
E 0:01:35.766 remove_child: Cannot remove child node 88 as it is not a child of this node.
E 0:01:35.768 add_child: Can’t add child ‘88’ to ‘Obstacle’, already has a parent ‘Obstacle’.
it only happens sometimes, so i guess it is due to some “internal” lag caused by the call deferred, but i dont really understand why since the call is only executed once, i even added the set_deferred("monitoring", false)
on the area2D to be sure not to emit additional area_entered signals that would result in a second stick()
call
Andrea | 2021-03-14 21:49
Nice 
It seems there are situations in your code that allow to run stick() twice in a row, or stick() function is triggered again when the arrow is already settled. Are You sure arrows don’t collide with each other, for example when several arrows hit one place ?
Generally call deferred yields the function until idle frame. It is possible, that during this yield some additional influence happens on this function, what results in doubled command of add or remove child after this idle frame. Try to examine code having that in mind
no, the projectile only have a collision mask, no collision layer, so they cannot collide with each other.
Maybe it is called when the arrow re-appears as the child of the collider, but by then monitoring
should already be disabled (and even if it was the case, why only some projectile and not all of them?)
i honestly dont know why stick is called multiple times, but i worked around the issue by adding a simple active=true
func _on_Hit_area_entered(area):
if is_network_master() and active:
active=false
if area.get_parent().has_method("receive_damage"):
area.get_parent().receive_damage(damage*Spt.base_prj_damage)
if sticky:
call_deferred("stick", area.get_parent())
this will also prevent multiple damages.
it’s a lazy fix, but it works for now
(ps: if you wanna turn the comment into an answer i’ll select it
)
Andrea | 2021-03-15 10:11
This may be good fix
I think I see why the previous code did that. $Hit was setting deferred the monitoring before process was turned to false, it is possible that monitoring was still active during waiting for idle frame, thus activated twice. Maybe :). Deferring calls can become a hindrance when it come to timing multiple calls 
Now You have put whole stick function into deferred call, so this should do better 
sadly, i put stick() in call deferred just for the sake of elegance, but without checking the active property it still prints the same errors sometimes 
Andrea | 2021-03-15 15:05