从 class [GDScript] 访问节点时出现问题

Problem accessing a node from a class [GDScript]

我在学习戈多的过程中遇到了一些困难

我正在尝试添加霰弹枪 class (Shotgun.gd)。我在 class 中有一个创建多个 RayCasts 的函数,一个检查它们遇到什么的函数和一个一个一个地调用这些函数的函数。如果我从 class 调用这些函数,它们在 _process() 函数中声明,一切正常,但如果我在另一个脚本中调用这些函数,比如 Player.gd,它在检查光线投射。

P.S抱歉翻译的草率,英语不是我的母语

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)

Godot tree picture

Call from func _process()

Call from Player.gd

我敢说他们没有碰撞可能是正确的。

在“调试”菜单中启用“可见碰撞形状”,以便 Godot 在运行时显示碰撞器(包括启用的 RayCasts),并检查它们是否正确定位。


我能想到几个可能的问题:

  • 您在定位之前添加 RayCast这并不总是问题,在您的情况下可能不是问题。但是,在移动之前添加时可能会发生冲突。
  • 您正在缩放 RayCast这应该不是问题。但是,存在与直接在碰撞形状上应用缩放相关的错误……所以,为了安全起见,我会避免这种情况。

建议:添加 Shotgun 的 Position 节点 child,标记 RayCast 的原点。然后你可以将 Position 的全局 t运行sform 复制到 RayCasts 的全局 t运行sform - 然后应用 运行dom 旋转- 在将它们添加为 children 之前。 这将使您在需要时更容易更新位置(例如,如果您更改了霰弹枪模型,则可以相应地调整 Position 节点)。在代码中编写坐标时应避免任何错别字。而且应该避免上面提到的陷阱。


我会提醒你,你应该检查一下 is_colliding我猜你这样做不是为了演示。

我还会提醒您 RayCasts 更新了物理框架。因此,当从 _physics_process 以外的其他地方调用 RayCast 时,您将获得他们最后注册的物理帧(即最后 _physics_process 运行 之前)。您可以通过调用 force_raycast_update 让 Godot 更新 RayCast


如果您不经常需要 RayCast,让它们更新每个物理帧可能有点矫枉过正。在这种情况下,您可能有兴趣像这样检查:get_world().direct_space_state.intersect_ray(start, end)。参见 PhysicsDirectSpaceState但是,使用 RayCast 应该可以。使用intersect_ray只是一种优化。


无关:如果你想从 运行dom 函数中得到一个均匀的概率分布分布,请在开始时调用一次 randomize,而不是每次迭代一次。无论如何,这可能不会引起注意。