#godot #gdscript
Вопрос:
Ладно, я действительно плохо разбираюсь в кодировании. Я особенно новичок в ГОДО и пытаюсь создать 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 lt; 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 gt;= 0: Global.npc1.done = true else: queue_free() done = true dialog_index = 1 func _on_Tween_tween_completed(object, key): finished = true
Ответ №1:
Если я правильно понимаю, вы открываете пользовательский интерфейс с помощью этого кода:
var dialog = DIALOG.instance() get_parent().add_child(dialog) dialog.position = $Position2D.global_position
Поэтому добавьте туда инструкцию сделать can_move
false ( Global.player.can_move = false
).
И, по-видимому, все это делается здесь:
queue_free()
То есть пользовательский интерфейс удаляет его самостоятельно. Когда пользовательский интерфейс удалится, он выйдет из дерева сцен, мы собираемся воспользоваться этим преимуществом. Подключите 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() -gt; void: Global.player.can_move = true
Этого должно хватить.
В качестве альтернативы вы можете создать и подать сигнал, чтобы уведомить, когда игрок сможет снова двигаться. Обратитесь к документации по сигналам.
Дополнение
Я думаю, что у меня есть то, что еще не работает. Смотреть на load_dialog
:
func load_dialog(): if dialog_index lt; dialog.size(): # ... some code ... if dialog_index gt;= 0: Global.npc1.done = true else: queue_free() done = true dialog_index = 1
Первая проверка ( dialog_index lt; dialog.size()
) заключается в том, есть ли еще текст диалогового окна. Если нет, то это сделано. Так что измените его на этот:
func load_dialog(): if dialog_index lt; 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
Комментарии:
1. похоже, у меня это не работает. Он удаляет движение, когда игрок взаимодействует, но он все равно не будет двигаться, когда диалог будет завершен. Я добавил именно то, что вы мне сказали добавить, но когда диалог будет завершен, он все равно не позволит мне снова двигаться
2. я получаю ошибку
Invalid set index 'can_move' (on base: 'Nil') with value of type 'bool'.
, которую я не знаю, почему я получаю, потому что я тупой и не знаю кода так хорошо3. @JacobWhisenand см. добавление.
4. Спасибо! У меня это работает
Ответ №2:
У меня недостаточно репутации, чтобы комментировать, но я просто хочу добавить, что у вас есть две разные done
переменные. Один в NPC, а другой в диалоге. Вы установили их истинными здесь:
if dialog_index gt;= 0: Global.npc1.done = true else: queue_free() done = true
Я думаю, что проблема также может заключаться в том, что диалог done
больше никогда не будет установлен. Но я тоже нуб, и Тераот всегда дает хорошие советы, так что проверьте его ответ еще раз.
На самом деле он уже решил эту проблему:
if dialog_index lt; dialog.size(): # … some code … else: Global.npc1.done = true queue_free() done = true dialog_index = 1
Для ясности я бы попытался использовать только одну done
переменную, вероятно, связывая скрипты с сигналами также, как сказал Тераот.