GODOT - 如何在对话框处于活动状态时禁用播放器移动并在其处于非活动状态时重新启用它

GODOT - how to disable player movement when dialog box is active and reenable it when its inactive

好吧,我真的不擅长编码。我对 GODOT 特别陌生,正在尝试制作 2d 游戏。我已经能够在播放对话框时将 cant_move 设置为 false,我遇到的问题是再次使 cant_move 为真。我什至不知道将 done = true 放在对话框脚本的什么位置(我只是把它放在一个随机的地方并希望它能起作用)。这是我的狗屎代码。 (解决方案可能很简单,我真的很笨)

npc脚本

`extends Area2D
var done = true


func _ready(): 
    Global.npc1 = self
func _exit_tree():
    Global.npc1 = null


var can_interact = false
const DIALOG = preload("res://dialoguebox.tscn")

func _physics_process(delta):
    $AnimatedSprite.play()

func diaplay():
    if done == false:
        Global.player.can_move = false
        print("test")

    if done == true:
        print("test2")
        can_interact = false
        Global.player.can_move = true

func _on_Area2D_body_entered(body):
    if body.name == "player":
        $Label.visible = true
        can_interact = true

func _on_Area2D_body_exited(body):
    if body.name == "player":
        $Label.visible = false
        can_interact = false

func _input(event):
    if Input.is_key_pressed(KEY_E) and can_interact == true:
        done = false
        diaplay()
        $Label.visible = false
        var dialog = DIALOG.instance()
        get_parent().add_child(dialog)
        dialog.position = $Position2D.global_position

对话脚本

extends Control
var dialog = [
    'sampletext',
    'sampletext2',
]
var done = false
var dialog_index = 0
var finished = false


func _ready():
    load_dialog() 
    Global.DialogBox = self
    
func _exit_tree():
    Global.DialogBox = null

func _physics_process(delta):
    $"Ind".visible = finished
    if Input.is_action_just_pressed("ui_accept"):
        load_dialog()

func load_dialog():
    if dialog_index < dialog.size():
        finished = false
        $RichTextLabel.bbcode_text = dialog[dialog_index]
        $RichTextLabel.percent_visible = 0
        $Tween.interpolate_property(
            $RichTextLabel, "percent_visible",  0, 1, 1,
            Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
        )
        $Tween.start()
    if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true
    dialog_index += 1
    
func _on_Tween_tween_completed(object, key):
    finished = true

如果我没理解错的话,你打开 UI 的代码是:

var dialog = DIALOG.instance()
get_parent().add_child(dialog)
dialog.position = $Position2D.global_position

所以添加指令使 can_move 为 false (Global.player.can_move = false).

显然这一切都在这里完成了:

queue_free()

也就是说,UI 正在自行删除它。当 UI 移除自身时,它会退出场景树,我们将利用这一点。将 UI 的 tree_exited 连接到再次设置 can_move true 的函数:

    Global.player.can_move = false
    var dialog = DIALOG.instance()
    dialog.position = $Position2D.global_position
    dialog.connect("tree_exited", self, "dialog_exited")
    get_parent().add_child(dialog)

func dialog_exited() -> void:
    Global.player.can_move = true

应该可以。

或者,您可以创建并发出信号以通知玩家何时可以再次移动。请参阅有关信号的文档。


附录

我想我还有什么不起作用。看看 load_dialog:

func load_dialog():
    if dialog_index < dialog.size():
        # ... some code ...
    if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true
    dialog_index += 1

第一个检查 (dialog_index < dialog.size()) 是是否有更多对话框文本。如果没有,那么就完成了。所以把它改成这样:

func load_dialog():
    if dialog_index < dialog.size():
        # … some code …
    else:
        Global.npc1.done = true
        queue_free()
        done = true
    dialog_index += 1

我希望这是有道理的。


你还提到你在 Global.player.can_move = true 中遇到了错误,我想这是在关闭游戏时发生的,代码 运行 并且 Global.player 不再有效。

无论什么情况,都可以检查播放器是否有效:

    var player = Global.player
    if is_instance_valid(player):
        player.can_move = true

我没有足够的代表发表评论,但我只想补充一点,您有两个不同的 done 变量。一个在 NPC 中,另一个在对话中。您在这里将它们设置为真:

if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true

我认为问题也可能是对话框的 done 再也没有设置为真。但我也是菜鸟,Theraot 总是给出很好的建议,所以请再次检查他的回答。

其实他已经解决了这个问题:

if dialog_index < dialog.size():
    # … some code …
else:
    Global.npc1.done = true
    queue_free()
    done = true
dialog_index += 1

为了清楚起见,我会尝试只使用一个 done 变量,可能也像 Theraot 所说的那样将 scrips 与信号连接起来。