首页 > 解决方案 > 使用导出变量进行实例化不起作用,因此,无法通过将其他场景添加为 Main 的子场景来克隆场景

问题描述

我正在用 Godot 编写一个明星收集游戏,但是在尝试添加一个场景作为主要的子场景(首先开始的场景,以及我正在进行实例化的场景)时,它不起作用,而是调试屏幕滞后如此之多以至于它显示“不响应”。我正在用 GDScript 编码。这是我在主场景中编写的用于实例化的代码:

extends Node2D

export (PackedScene) var Star

func _ready():
    pass

func _on_Timer_timeout():
    var star = Star.instance()
    add_child(star)

我还在脚本变量部分插入了我想要实例化的所需场景(对不起,因为我是 Godot 的新手,我无法很好地解释这些术语): 脚本变量部分

这是我正在实例化的场景代码:

extends Area2D

export var done = 0
export var speed = 43
export var spinVal = 0
export var dir = 0

func _ready():
    done=0
    dir=5-(randf()*10)
    spinVal = 5-(randf()*10)
    position.x=randf()*10
    position.y=-20
    while done==0:
        position.y+=speed
        rotation_degrees=0+dir
        rotate(spinVal)
    print(position)


func _on_VisibilityNotifier2D_screen_exited():
    if (position.y<720):
            done=1
            queue_free()

之前,我在使用 PackedScene 方法之前尝试过简单的实例化方法,但我遇到了同样的问题。现在我正在尝试这种方式,但没有任何改进......

标签: instancegodotgdscript

解决方案


你的实例很好。你的场景是错误的。

一旦你添加了实例化的场景add_child,它_ready就会运行。和这个:

func _ready():
    done=0
    dir=5-(randf()*10)
    spinVal = 5-(randf()*10)
    position.x=randf()*10
    position.y=-20
    while done==0:
        position.y+=speed
        rotation_degrees=0+dir
        rotate(spinVal)

嗯,这是一个无限循环。第一行确保done为 0。其中的任何内容都不会设置done为其他内容。游戏卡在那里。


我看到你设置在done其他地方:

func _on_VisibilityNotifier2D_screen_exited():
    if (position.y<720):
            done=1
            queue_free()

然而,该代码从未有机会运行。


如果你真的,真的,想把你的动作写在_ready. 你可以这样做:

func _ready():
    done=0
    dir=5-(randf()*10)
    spinVal = 5-(randf()*10)
    position.x=randf()*10
    position.y=-20
    while done==0:
        yield(get_tree(), "physics_frame") # <--
        position.y+=speed
        rotation_degrees=0+dir
        rotate(spinVal)

当代码到达yield时,它将暂停,直到指定的信号发生,然后继续。在这种情况下, 的"physics_frame"信号SceneTree我正在使用"physics_frame"而不是"idle_frame"考虑到这是一个Area2D.


当然,更惯用的写法是:

extends Area2D

export var done = 0
export var speed = 43
export var spinVal = 0
export var dir = 0

func _ready():
    done=0
    dir=5-(randf()*10)
    spinVal = 5-(randf()*10)
    position.x=randf()*10
    position.y=-20

func _physics_process(_delta):
    if done != 0:
        return

    position.y+=speed
    rotation_degrees=0+dir
    rotate(spinVal)

func _on_VisibilityNotifier2D_screen_exited():
    if (position.y<720):
            done=1
            queue_free()

老实说,我认为你根本不需要done。但是,鉴于它是一个导出变量,我没有删除它。

我也不确定你的轮换。但这是一个单独的问题。


推荐阅读