polished
This commit is contained in:
		| @@ -1,223 +0,0 @@ | ||||
| using Godot; | ||||
| using Godot.Collections; | ||||
|  | ||||
| namespace DialogueManagerRuntime | ||||
| { | ||||
|   public partial class ExampleBalloon : CanvasLayer | ||||
|   { | ||||
|     [Export] public string NextAction = "ui_accept"; | ||||
|     [Export] public string SkipAction = "ui_cancel"; | ||||
|  | ||||
|  | ||||
|     Control balloon; | ||||
|     RichTextLabel characterLabel; | ||||
|     RichTextLabel dialogueLabel; | ||||
|     VBoxContainer responsesMenu; | ||||
|  | ||||
|     Resource resource; | ||||
|     Array<Variant> temporaryGameStates = new Array<Variant>(); | ||||
|     bool isWaitingForInput = false; | ||||
|     bool willHideBalloon = false; | ||||
|  | ||||
|     DialogueLine dialogueLine; | ||||
|     DialogueLine DialogueLine | ||||
|     { | ||||
|       get => dialogueLine; | ||||
|       set | ||||
|       { | ||||
|         if (value == null) | ||||
|         { | ||||
|           QueueFree(); | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|         dialogueLine = value; | ||||
|         ApplyDialogueLine(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     Timer MutationCooldown = new Timer(); | ||||
|  | ||||
|  | ||||
|     public override void _Ready() | ||||
|     { | ||||
|       balloon = GetNode<Control>("%Balloon"); | ||||
|       characterLabel = GetNode<RichTextLabel>("%CharacterLabel"); | ||||
|       dialogueLabel = GetNode<RichTextLabel>("%DialogueLabel"); | ||||
|       responsesMenu = GetNode<VBoxContainer>("%ResponsesMenu"); | ||||
|  | ||||
|       balloon.Hide(); | ||||
|  | ||||
|       balloon.GuiInput += (@event) => | ||||
|       { | ||||
|         if ((bool)dialogueLabel.Get("is_typing")) | ||||
|         { | ||||
|           bool mouseWasClicked = @event is InputEventMouseButton && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left && @event.IsPressed(); | ||||
|           bool skipButtonWasPressed = @event.IsActionPressed(SkipAction); | ||||
|           if (mouseWasClicked || skipButtonWasPressed) | ||||
|           { | ||||
|             GetViewport().SetInputAsHandled(); | ||||
|             dialogueLabel.Call("skip_typing"); | ||||
|             return; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         if (!isWaitingForInput) return; | ||||
|         if (dialogueLine.Responses.Count > 0) return; | ||||
|  | ||||
|         GetViewport().SetInputAsHandled(); | ||||
|  | ||||
|         if (@event is InputEventMouseButton && @event.IsPressed() && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left) | ||||
|         { | ||||
|           Next(dialogueLine.NextId); | ||||
|         } | ||||
|         else if (@event.IsActionPressed(NextAction) && GetViewport().GuiGetFocusOwner() == balloon) | ||||
|         { | ||||
|           Next(dialogueLine.NextId); | ||||
|         } | ||||
|       }; | ||||
|  | ||||
|       if (string.IsNullOrEmpty((string)responsesMenu.Get("next_action"))) | ||||
|       { | ||||
|         responsesMenu.Set("next_action", NextAction); | ||||
|       } | ||||
|       responsesMenu.Connect("response_selected", Callable.From((DialogueResponse response) => | ||||
|       { | ||||
|         Next(response.NextId); | ||||
|       })); | ||||
|  | ||||
|  | ||||
|       // Hide the balloon when a mutation is running | ||||
|       MutationCooldown.Timeout += () => | ||||
|       { | ||||
|         if (willHideBalloon) | ||||
|         { | ||||
|           willHideBalloon = false; | ||||
|           balloon.Hide(); | ||||
|         } | ||||
|       }; | ||||
|       AddChild(MutationCooldown); | ||||
|  | ||||
|       DialogueManager.Mutated += OnMutated; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public override void _ExitTree() | ||||
|     { | ||||
|       DialogueManager.Mutated -= OnMutated; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public override void _UnhandledInput(InputEvent @event) | ||||
|     { | ||||
|       // Only the balloon is allowed to handle input while it's showing | ||||
|       GetViewport().SetInputAsHandled(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public override async void _Notification(int what) | ||||
|     { | ||||
|       // Detect a change of locale and update the current dialogue line to show the new language | ||||
|       if (what == NotificationTranslationChanged && IsInstanceValid(dialogueLabel)) | ||||
|       { | ||||
|         float visibleRatio = dialogueLabel.VisibleRatio; | ||||
|         DialogueLine = await DialogueManager.GetNextDialogueLine(resource, DialogueLine.Id, temporaryGameStates); | ||||
|         if (visibleRatio < 1.0f) | ||||
|         { | ||||
|           dialogueLabel.Call("skip_typing"); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public async void Start(Resource dialogueResource, string title, Array<Variant> extraGameStates = null) | ||||
|     { | ||||
|       temporaryGameStates = new Array<Variant> { this } + (extraGameStates ?? new Array<Variant>()); | ||||
|       isWaitingForInput = false; | ||||
|       resource = dialogueResource; | ||||
|  | ||||
|       DialogueLine = await DialogueManager.GetNextDialogueLine(resource, title, temporaryGameStates); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public async void Next(string nextId) | ||||
|     { | ||||
|       DialogueLine = await DialogueManager.GetNextDialogueLine(resource, nextId, temporaryGameStates); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     #region Helpers | ||||
|  | ||||
|  | ||||
|     private async void ApplyDialogueLine() | ||||
|     { | ||||
|       MutationCooldown.Stop(); | ||||
|  | ||||
|       isWaitingForInput = false; | ||||
|       balloon.FocusMode = Control.FocusModeEnum.All; | ||||
|       balloon.GrabFocus(); | ||||
|  | ||||
|       // Set up the character name | ||||
|       characterLabel.Visible = !string.IsNullOrEmpty(dialogueLine.Character); | ||||
|       characterLabel.Text = Tr(dialogueLine.Character, "dialogue"); | ||||
|  | ||||
|       // Set up the dialogue | ||||
|       dialogueLabel.Hide(); | ||||
|       dialogueLabel.Set("dialogue_line", dialogueLine); | ||||
|  | ||||
|       // Set up the responses | ||||
|       responsesMenu.Hide(); | ||||
|       responsesMenu.Set("responses", dialogueLine.Responses); | ||||
|  | ||||
|       // Type out the text | ||||
|       balloon.Show(); | ||||
|       willHideBalloon = false; | ||||
|       dialogueLabel.Show(); | ||||
|       if (!string.IsNullOrEmpty(dialogueLine.Text)) | ||||
|       { | ||||
|         dialogueLabel.Call("type_out"); | ||||
|         await ToSignal(dialogueLabel, "finished_typing"); | ||||
|       } | ||||
|  | ||||
|       // Wait for input | ||||
|       if (dialogueLine.Responses.Count > 0) | ||||
|       { | ||||
|         balloon.FocusMode = Control.FocusModeEnum.None; | ||||
|         responsesMenu.Show(); | ||||
|       } | ||||
|       else if (!string.IsNullOrEmpty(dialogueLine.Time)) | ||||
|       { | ||||
|         float time = 0f; | ||||
|         if (!float.TryParse(dialogueLine.Time, out time)) | ||||
|         { | ||||
|           time = dialogueLine.Text.Length * 0.02f; | ||||
|         } | ||||
|         await ToSignal(GetTree().CreateTimer(time), "timeout"); | ||||
|         Next(dialogueLine.NextId); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         isWaitingForInput = true; | ||||
|         balloon.FocusMode = Control.FocusModeEnum.All; | ||||
|         balloon.GrabFocus(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|  | ||||
|     #region signals | ||||
|  | ||||
|  | ||||
|     private void OnMutated(Dictionary _mutation) | ||||
|     { | ||||
|       isWaitingForInput = false; | ||||
|       willHideBalloon = true; | ||||
|       MutationCooldown.Start(0.1f); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     #endregion | ||||
|   } | ||||
| } | ||||
| @@ -1 +0,0 @@ | ||||
| uid://5b3w40kwakl3 | ||||
| @@ -1,176 +0,0 @@ | ||||
| class_name DialogueManagerExampleBalloon extends CanvasLayer | ||||
| ## A basic dialogue balloon for use with Dialogue Manager. | ||||
|  | ||||
| ## The action to use for advancing the dialogue | ||||
| @export var next_action: StringName = &"ui_accept" | ||||
|  | ||||
| ## The action to use to skip typing the dialogue | ||||
| @export var skip_action: StringName = &"ui_cancel" | ||||
|  | ||||
| ## The dialogue resource | ||||
| var resource: DialogueResource | ||||
|  | ||||
| ## Temporary game states | ||||
| var temporary_game_states: Array = [] | ||||
|  | ||||
| ## See if we are waiting for the player | ||||
| var is_waiting_for_input: bool = false | ||||
|  | ||||
| ## See if we are running a long mutation and should hide the balloon | ||||
| var will_hide_balloon: bool = false | ||||
|  | ||||
| ## A dictionary to store any ephemeral variables | ||||
| var locals: Dictionary = {} | ||||
|  | ||||
| var _locale: String = TranslationServer.get_locale() | ||||
|  | ||||
| ## The current line | ||||
| var dialogue_line: DialogueLine: | ||||
| 	set(value): | ||||
| 		if value: | ||||
| 			dialogue_line = value | ||||
| 			apply_dialogue_line() | ||||
| 		else: | ||||
| 			# The dialogue has finished so close the balloon | ||||
| 			queue_free() | ||||
| 	get: | ||||
| 		return dialogue_line | ||||
|  | ||||
| ## A cooldown timer for delaying the balloon hide when encountering a mutation. | ||||
| var mutation_cooldown: Timer = Timer.new() | ||||
|  | ||||
| ## The base balloon anchor | ||||
| @onready var balloon: Control = %Balloon | ||||
|  | ||||
| ## The label showing the name of the currently speaking character | ||||
| @onready var character_label: RichTextLabel = %CharacterLabel | ||||
|  | ||||
| ## The label showing the currently spoken dialogue | ||||
| @onready var dialogue_label: DialogueLabel = %DialogueLabel | ||||
|  | ||||
| ## The menu of responses | ||||
| @onready var responses_menu: DialogueResponsesMenu = %ResponsesMenu | ||||
|  | ||||
|  | ||||
| func _ready() -> void: | ||||
| 	balloon.hide() | ||||
| 	Engine.get_singleton("DialogueManager").mutated.connect(_on_mutated) | ||||
|  | ||||
| 	# If the responses menu doesn't have a next action set, use this one | ||||
| 	if responses_menu.next_action.is_empty(): | ||||
| 		responses_menu.next_action = next_action | ||||
|  | ||||
| 	mutation_cooldown.timeout.connect(_on_mutation_cooldown_timeout) | ||||
| 	add_child(mutation_cooldown) | ||||
|  | ||||
|  | ||||
| func _unhandled_input(_event: InputEvent) -> void: | ||||
| 	# Only the balloon is allowed to handle input while it's showing | ||||
| 	get_viewport().set_input_as_handled() | ||||
|  | ||||
|  | ||||
| func _notification(what: int) -> void: | ||||
| 	## Detect a change of locale and update the current dialogue line to show the new language | ||||
| 	if what == NOTIFICATION_TRANSLATION_CHANGED and _locale != TranslationServer.get_locale() and is_instance_valid(dialogue_label): | ||||
| 		_locale = TranslationServer.get_locale() | ||||
| 		var visible_ratio = dialogue_label.visible_ratio | ||||
| 		self.dialogue_line = await resource.get_next_dialogue_line(dialogue_line.id) | ||||
| 		if visible_ratio < 1: | ||||
| 			dialogue_label.skip_typing() | ||||
|  | ||||
|  | ||||
| ## Start some dialogue | ||||
| func start(dialogue_resource: DialogueResource, title: String, extra_game_states: Array = []) -> void: | ||||
| 	temporary_game_states = [self] + extra_game_states | ||||
| 	is_waiting_for_input = false | ||||
| 	resource = dialogue_resource | ||||
| 	self.dialogue_line = await resource.get_next_dialogue_line(title, temporary_game_states) | ||||
|  | ||||
|  | ||||
| ## Apply any changes to the balloon given a new [DialogueLine]. | ||||
| func apply_dialogue_line() -> void: | ||||
| 	mutation_cooldown.stop() | ||||
|  | ||||
| 	is_waiting_for_input = false | ||||
| 	balloon.focus_mode = Control.FOCUS_ALL | ||||
| 	balloon.grab_focus() | ||||
|  | ||||
| 	character_label.visible = not dialogue_line.character.is_empty() | ||||
| 	character_label.text = tr(dialogue_line.character, "dialogue") | ||||
|  | ||||
| 	dialogue_label.hide() | ||||
| 	dialogue_label.dialogue_line = dialogue_line | ||||
|  | ||||
| 	responses_menu.hide() | ||||
| 	responses_menu.responses = dialogue_line.responses | ||||
|  | ||||
| 	# Show our balloon | ||||
| 	balloon.show() | ||||
| 	will_hide_balloon = false | ||||
|  | ||||
| 	dialogue_label.show() | ||||
| 	if not dialogue_line.text.is_empty(): | ||||
| 		dialogue_label.type_out() | ||||
| 		await dialogue_label.finished_typing | ||||
|  | ||||
| 	# Wait for input | ||||
| 	if dialogue_line.responses.size() > 0: | ||||
| 		balloon.focus_mode = Control.FOCUS_NONE | ||||
| 		responses_menu.show() | ||||
| 	elif dialogue_line.time != "": | ||||
| 		var time = dialogue_line.text.length() * 0.02 if dialogue_line.time == "auto" else dialogue_line.time.to_float() | ||||
| 		await get_tree().create_timer(time).timeout | ||||
| 		next(dialogue_line.next_id) | ||||
| 	else: | ||||
| 		is_waiting_for_input = true | ||||
| 		balloon.focus_mode = Control.FOCUS_ALL | ||||
| 		balloon.grab_focus() | ||||
|  | ||||
|  | ||||
| ## Go to the next line | ||||
| func next(next_id: String) -> void: | ||||
| 	self.dialogue_line = await resource.get_next_dialogue_line(next_id, temporary_game_states) | ||||
|  | ||||
|  | ||||
| #region Signals | ||||
|  | ||||
|  | ||||
| func _on_mutation_cooldown_timeout() -> void: | ||||
| 	if will_hide_balloon: | ||||
| 		will_hide_balloon = false | ||||
| 		balloon.hide() | ||||
|  | ||||
|  | ||||
| func _on_mutated(_mutation: Dictionary) -> void: | ||||
| 	is_waiting_for_input = false | ||||
| 	will_hide_balloon = true | ||||
| 	mutation_cooldown.start(0.1) | ||||
|  | ||||
|  | ||||
| func _on_balloon_gui_input(event: InputEvent) -> void: | ||||
| 	# See if we need to skip typing of the dialogue | ||||
| 	if dialogue_label.is_typing: | ||||
| 		var mouse_was_clicked: bool = event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed() | ||||
| 		var skip_button_was_pressed: bool = event.is_action_pressed(skip_action) | ||||
| 		if mouse_was_clicked or skip_button_was_pressed: | ||||
| 			get_viewport().set_input_as_handled() | ||||
| 			dialogue_label.skip_typing() | ||||
| 			return | ||||
|  | ||||
| 	if not is_waiting_for_input: return | ||||
| 	if dialogue_line.responses.size() > 0: return | ||||
|  | ||||
| 	# When there are no response options the balloon itself is the clickable thing | ||||
| 	get_viewport().set_input_as_handled() | ||||
|  | ||||
| 	if event is InputEventMouseButton and event.is_pressed() and event.button_index == MOUSE_BUTTON_LEFT: | ||||
| 		next(dialogue_line.next_id) | ||||
| 	elif event.is_action_pressed(next_action) and get_viewport().gui_get_focus_owner() == balloon: | ||||
| 		next(dialogue_line.next_id) | ||||
|  | ||||
|  | ||||
| func _on_responses_menu_response_selected(response: DialogueResponse) -> void: | ||||
| 	next(response.next_id) | ||||
|  | ||||
|  | ||||
| #endregion | ||||
| @@ -1 +0,0 @@ | ||||
| uid://d1wt4ma6055l8 | ||||
| @@ -1,142 +0,0 @@ | ||||
| [gd_scene load_steps=9 format=3 uid="uid://73jm5qjy52vq"] | ||||
|  | ||||
| [ext_resource type="Script" uid="uid://d1wt4ma6055l8" path="res://addons/dialogue_manager/example_balloon/example_balloon.gd" id="1_36de5"] | ||||
| [ext_resource type="PackedScene" uid="uid://ckvgyvclnwggo" path="res://addons/dialogue_manager/dialogue_label.tscn" id="2_a8ve6"] | ||||
| [ext_resource type="Script" uid="uid://bb52rsfwhkxbn" path="res://addons/dialogue_manager/dialogue_responses_menu.gd" id="3_72ixx"] | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_spyqn"] | ||||
| bg_color = Color(0, 0, 0, 1) | ||||
| border_width_left = 3 | ||||
| border_width_top = 3 | ||||
| border_width_right = 3 | ||||
| border_width_bottom = 3 | ||||
| border_color = Color(0.329412, 0.329412, 0.329412, 1) | ||||
| corner_radius_top_left = 5 | ||||
| corner_radius_top_right = 5 | ||||
| corner_radius_bottom_right = 5 | ||||
| corner_radius_bottom_left = 5 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ri4m3"] | ||||
| bg_color = Color(0.121569, 0.121569, 0.121569, 1) | ||||
| border_width_left = 3 | ||||
| border_width_top = 3 | ||||
| border_width_right = 3 | ||||
| border_width_bottom = 3 | ||||
| border_color = Color(1, 1, 1, 1) | ||||
| corner_radius_top_left = 5 | ||||
| corner_radius_top_right = 5 | ||||
| corner_radius_bottom_right = 5 | ||||
| corner_radius_bottom_left = 5 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e0njw"] | ||||
| bg_color = Color(0, 0, 0, 1) | ||||
| border_width_left = 3 | ||||
| border_width_top = 3 | ||||
| border_width_right = 3 | ||||
| border_width_bottom = 3 | ||||
| border_color = Color(0.6, 0.6, 0.6, 1) | ||||
| corner_radius_top_left = 5 | ||||
| corner_radius_top_right = 5 | ||||
| corner_radius_bottom_right = 5 | ||||
| corner_radius_bottom_left = 5 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qkmqt"] | ||||
| bg_color = Color(0, 0, 0, 1) | ||||
| border_width_left = 3 | ||||
| border_width_top = 3 | ||||
| border_width_right = 3 | ||||
| border_width_bottom = 3 | ||||
| corner_radius_top_left = 5 | ||||
| corner_radius_top_right = 5 | ||||
| corner_radius_bottom_right = 5 | ||||
| corner_radius_bottom_left = 5 | ||||
|  | ||||
| [sub_resource type="Theme" id="Theme_qq3yp"] | ||||
| default_font_size = 20 | ||||
| Button/styles/disabled = SubResource("StyleBoxFlat_spyqn") | ||||
| Button/styles/focus = SubResource("StyleBoxFlat_ri4m3") | ||||
| Button/styles/hover = SubResource("StyleBoxFlat_e0njw") | ||||
| Button/styles/normal = SubResource("StyleBoxFlat_e0njw") | ||||
| MarginContainer/constants/margin_bottom = 15 | ||||
| MarginContainer/constants/margin_left = 30 | ||||
| MarginContainer/constants/margin_right = 30 | ||||
| MarginContainer/constants/margin_top = 15 | ||||
| PanelContainer/styles/panel = SubResource("StyleBoxFlat_qkmqt") | ||||
|  | ||||
| [node name="ExampleBalloon" type="CanvasLayer"] | ||||
| layer = 100 | ||||
| script = ExtResource("1_36de5") | ||||
|  | ||||
| [node name="Balloon" type="Control" parent="."] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 3 | ||||
| anchors_preset = 15 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 1.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| theme = SubResource("Theme_qq3yp") | ||||
|  | ||||
| [node name="MarginContainer" type="MarginContainer" parent="Balloon"] | ||||
| layout_mode = 1 | ||||
| anchors_preset = 12 | ||||
| anchor_top = 1.0 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 1.0 | ||||
| offset_top = -219.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 0 | ||||
|  | ||||
| [node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"] | ||||
| clip_children = 2 | ||||
| layout_mode = 2 | ||||
| mouse_filter = 1 | ||||
|  | ||||
| [node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"] | ||||
| layout_mode = 2 | ||||
|  | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"] | ||||
| layout_mode = 2 | ||||
|  | ||||
| [node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"] | ||||
| unique_name_in_owner = true | ||||
| modulate = Color(1, 1, 1, 0.501961) | ||||
| layout_mode = 2 | ||||
| mouse_filter = 1 | ||||
| bbcode_enabled = true | ||||
| text = "Character" | ||||
| fit_content = true | ||||
| scroll_active = false | ||||
|  | ||||
| [node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_a8ve6")] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 3 | ||||
| text = "Dialogue..." | ||||
|  | ||||
| [node name="ResponsesMenu" type="VBoxContainer" parent="Balloon" node_paths=PackedStringArray("response_template")] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 1 | ||||
| anchors_preset = 8 | ||||
| anchor_left = 0.5 | ||||
| anchor_top = 0.5 | ||||
| anchor_right = 0.5 | ||||
| anchor_bottom = 0.5 | ||||
| offset_left = -290.5 | ||||
| offset_top = -35.0 | ||||
| offset_right = 290.5 | ||||
| offset_bottom = 35.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_override_constants/separation = 2 | ||||
| alignment = 1 | ||||
| script = ExtResource("3_72ixx") | ||||
| response_template = NodePath("ResponseExample") | ||||
|  | ||||
| [node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"] | ||||
| layout_mode = 2 | ||||
| text = "Response example" | ||||
|  | ||||
| [connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"] | ||||
| [connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"] | ||||
| @@ -1,166 +0,0 @@ | ||||
| [gd_scene load_steps=10 format=3 uid="uid://13s5spsk34qu"] | ||||
|  | ||||
| [ext_resource type="Script" uid="uid://d1wt4ma6055l8" path="res://addons/dialogue_manager/example_balloon/example_balloon.gd" id="1_s2gbs"] | ||||
| [ext_resource type="PackedScene" uid="uid://ckvgyvclnwggo" path="res://addons/dialogue_manager/dialogue_label.tscn" id="2_hfvdi"] | ||||
| [ext_resource type="Script" uid="uid://bb52rsfwhkxbn" path="res://addons/dialogue_manager/dialogue_responses_menu.gd" id="3_1j1j0"] | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_235ry"] | ||||
| content_margin_left = 6.0 | ||||
| content_margin_top = 3.0 | ||||
| content_margin_right = 6.0 | ||||
| content_margin_bottom = 3.0 | ||||
| bg_color = Color(0.0666667, 0.0666667, 0.0666667, 1) | ||||
| border_width_left = 1 | ||||
| border_width_top = 1 | ||||
| border_width_right = 1 | ||||
| border_width_bottom = 1 | ||||
| border_color = Color(0.345098, 0.345098, 0.345098, 1) | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ufjut"] | ||||
| content_margin_left = 6.0 | ||||
| content_margin_top = 3.0 | ||||
| content_margin_right = 6.0 | ||||
| content_margin_bottom = 3.0 | ||||
| bg_color = Color(0.227451, 0.227451, 0.227451, 1) | ||||
| border_width_left = 1 | ||||
| border_width_top = 1 | ||||
| border_width_right = 1 | ||||
| border_width_bottom = 1 | ||||
| border_color = Color(1, 1, 1, 1) | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fcbqo"] | ||||
| content_margin_left = 6.0 | ||||
| content_margin_top = 3.0 | ||||
| content_margin_right = 6.0 | ||||
| content_margin_bottom = 3.0 | ||||
| bg_color = Color(0.0666667, 0.0666667, 0.0666667, 1) | ||||
| border_width_left = 1 | ||||
| border_width_top = 1 | ||||
| border_width_right = 1 | ||||
| border_width_bottom = 1 | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_t6i7a"] | ||||
| content_margin_left = 6.0 | ||||
| content_margin_top = 3.0 | ||||
| content_margin_right = 6.0 | ||||
| content_margin_bottom = 3.0 | ||||
| bg_color = Color(0.0666667, 0.0666667, 0.0666667, 1) | ||||
| border_width_left = 1 | ||||
| border_width_top = 1 | ||||
| border_width_right = 1 | ||||
| border_width_bottom = 1 | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
|  | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i6nbm"] | ||||
| bg_color = Color(0, 0, 0, 1) | ||||
| border_width_left = 1 | ||||
| border_width_top = 1 | ||||
| border_width_right = 1 | ||||
| border_width_bottom = 1 | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
|  | ||||
| [sub_resource type="Theme" id="Theme_qq3yp"] | ||||
| default_font_size = 8 | ||||
| Button/styles/disabled = SubResource("StyleBoxFlat_235ry") | ||||
| Button/styles/focus = SubResource("StyleBoxFlat_ufjut") | ||||
| Button/styles/hover = SubResource("StyleBoxFlat_fcbqo") | ||||
| Button/styles/normal = SubResource("StyleBoxFlat_t6i7a") | ||||
| MarginContainer/constants/margin_bottom = 4 | ||||
| MarginContainer/constants/margin_left = 8 | ||||
| MarginContainer/constants/margin_right = 8 | ||||
| MarginContainer/constants/margin_top = 4 | ||||
| PanelContainer/styles/panel = SubResource("StyleBoxFlat_i6nbm") | ||||
|  | ||||
| [node name="ExampleBalloon" type="CanvasLayer"] | ||||
| layer = 100 | ||||
| script = ExtResource("1_s2gbs") | ||||
|  | ||||
| [node name="Balloon" type="Control" parent="."] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 3 | ||||
| anchors_preset = 15 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 1.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| theme = SubResource("Theme_qq3yp") | ||||
|  | ||||
| [node name="MarginContainer" type="MarginContainer" parent="Balloon"] | ||||
| layout_mode = 1 | ||||
| anchors_preset = 12 | ||||
| anchor_top = 1.0 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 1.0 | ||||
| offset_top = -71.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 0 | ||||
|  | ||||
| [node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"] | ||||
| clip_children = 2 | ||||
| layout_mode = 2 | ||||
| mouse_filter = 1 | ||||
|  | ||||
| [node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"] | ||||
| layout_mode = 2 | ||||
|  | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"] | ||||
| layout_mode = 2 | ||||
|  | ||||
| [node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"] | ||||
| unique_name_in_owner = true | ||||
| modulate = Color(1, 1, 1, 0.501961) | ||||
| layout_mode = 2 | ||||
| mouse_filter = 1 | ||||
| bbcode_enabled = true | ||||
| text = "Character" | ||||
| fit_content = true | ||||
| scroll_active = false | ||||
|  | ||||
| [node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_hfvdi")] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 3 | ||||
| text = "Dialogue..." | ||||
|  | ||||
| [node name="ResponsesMenu" type="VBoxContainer" parent="Balloon"] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 1 | ||||
| anchors_preset = 8 | ||||
| anchor_left = 0.5 | ||||
| anchor_top = 0.5 | ||||
| anchor_right = 0.5 | ||||
| anchor_bottom = 0.5 | ||||
| offset_left = -116.5 | ||||
| offset_top = -9.0 | ||||
| offset_right = 116.5 | ||||
| offset_bottom = 9.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_override_constants/separation = 2 | ||||
| script = ExtResource("3_1j1j0") | ||||
|  | ||||
| [node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"] | ||||
| layout_mode = 2 | ||||
| text = "Response Example" | ||||
|  | ||||
| [connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"] | ||||
| [connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"] | ||||
		Reference in New Issue
	
	Block a user