I encountered some difficulties while studying Godot.
I'm trying to add a shotgun class (Shotgun.gd). I have a function in the class that creates several RayCasts, a function that checks what they encounter and a function that calls these functions one by one. If I call these functions from the class where they are declared in the _process() function, everything works fine, but if I call these functions in another script, like Player.gd, it finds nothing when checking for RayCasts.
P.S Sorry for the sloppy translation, English is not my native language
Part of the code from the shotgun class (Shotgun.gd)
# Gen RayCast-ы
func gen_raycasts(player):
# Очистка списка
raycasts.clear()
var temp
for number in PELLETS_COUNT:
# Создание RayCast
temp = RayCast.new()
# Установка настроек
temp.set_cast_to(Vector3(LENGHT, 0, 0))
temp.set_enabled(true)
# Добавляет RayCast на сцену
player.add_child(temp)
# Установка положения
temp.transform.basis = Basis(Vector3(-0, 0, 0.1), Vector3(-0, 0, 0.1), Vector3(0.1, 0, -0))
temp.global_translate(Vector3(0, 1.65, 0))
temp.set_scale(Vector3(0.1, 0.1, -0.1))
# Рандомный разброс дробовика
randomize()
temp.rotate_y(deg2rad((-50 + randi() % 100) / 10))
temp.rotate_x(deg2rad((-50 + randi() % 100) / 10))
raycasts.append(temp)
#print(raycasts)
# Check Rayasts
func chech_raycasts():
in_raycast.clear()
for number in PELLETS_COUNT:
in_raycast.append(raycasts[number].get_collider())
#print(raycasts[number].is_enabled())
print(in_raycast)
I'll venture to say that it is probably correct they collide with nothing.
Enable "Visible Collision Shapes" in the "Debug" menu, so Godot shows colliders in runtime (including enabled RayCast
s), and check they are being positioned correctly.
I can think of a couple possible problems:
RayCast
before positioning it. This is not always a problem, and it is probably not a problem in your case. However, it might register a collision when added, before moved.RayCast
. This should not be a problem. However, there have been bugs related applying a scaling directly on collision shapes… So, I will avoid this, just to be safe.A suggestion: Add a Position
node, child of your Shotgun, marking the origin for the RayCast
s. Then you can copy the global transform of the Position
to the global transform of the RayCast
s - and then apply the random rotation - before adding them as children. This should make it easier to update the position if you need to (e.g. if you changed the shotgun model, you can mode the Position
node accordingly). It should avoid any typos when writing the coordinates in the code. And it should avoid the pitfalls mentioned above.
I'll remind you you are supposed to check is_colliding
. I guess you are not doing it for demonstration purposes.
I'll also remind you that the RayCast
s update with the physics frame. So, when calling the RayCast
from somewhere other than _physics_process
you are getting what they registered last physics frame (i.e. just before _physics_process
ran last). You can make Godot update the RayCast
by calling force_raycast_update
on them.
If you don't need the RayCast
s often, having them update every physics frame might be overkill. In that case, you might be interested in checking like this: get_world().direct_space_state.intersect_ray(start, end)
. See PhysicsDirectSpaceState
. However, using RayCast
should work. Using intersect_ray
is only an optimization.
Unrelated: if you want to guarantee an uniform probability distribution distribution from the random functions, call randomize
once at the start, instead of once per iteration. This is probably not noticeable anyway.