├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── addons
└── action_button
│ ├── action_button.gd
│ ├── action_button.gd.uid
│ ├── action_button_autoload.gd
│ ├── action_button_autoload.gd.uid
│ ├── action_button_effect.gd
│ ├── action_button_effect.gd.uid
│ ├── icons
│ ├── ActionButton.svg
│ ├── ActionButton.svg.import
│ ├── ActionButtonAudio.svg
│ ├── ActionButtonAudio.svg.import
│ ├── ActionButtonEffect.svg
│ └── ActionButtonEffect.svg.import
│ ├── plugin.cfg
│ ├── plugin.gd
│ └── plugin.gd.uid
├── demo_action_button
├── action_button_demo.tscn
└── assets
│ ├── cork-plug.mp3
│ ├── cork-plug.mp3.import
│ ├── cursor.mp3
│ ├── cursor.mp3.import
│ ├── decision.mp3
│ ├── decision.mp3.import
│ ├── icon.png
│ ├── icon.png.import
│ ├── paper-take.mp3
│ ├── paper-take.mp3.import
│ └── sound credit.txt
└── project.godot
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Normalize EOL for all files that Git considers text files.
2 | * text=auto eol=lf
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 |
4 | # Godot-specific ignores
5 | .import/
6 | export.cfg
7 | export_presets.cfg
8 |
9 | # Imported translations (automatically generated from CSV files)
10 | *.translation
11 |
12 | # Mono-specific ignores
13 | .mono/
14 | data_*/
15 | mono_crash.*.json
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Michael
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ActionButton 🎞️
2 | Godot plugin that adds a button with extended audio visual capabilities.
3 |
4 | 
5 |
6 | 
7 |
8 | # How to use
9 | 1) Install through the Asset Library within Godot, look for `ActionButton`. You can also get the files by downloading this repository and putting it inside your project folder.
10 | 2) Enable the plugin in the project settings.
11 | 3) To add this fancy new button to a scene simply search for a node called `ActionButton`
12 |
13 | # Features
14 | * Customize how the button animates and looks when you interact with it.
15 | * Configure sounds for the button, with a system that keeps track of sounds and reuses them accross the project.
16 | * A mostly documated code
17 |
--------------------------------------------------------------------------------
/addons/action_button/action_button.gd:
--------------------------------------------------------------------------------
1 | @icon("res://addons/action_button/icons/ActionButton.svg")
2 | class_name ActionButton
3 | extends Button
4 |
5 | ##Action that plays when you hover over the button with your mouse or when you focus on it.
6 | @export var on_hover : ActionButtonEffect
7 | ##Action that plays when the button is pressed either with mouse or UI input. Has no connection with [member BaseButton.action_mode]
8 | @export var on_button_down : ActionButtonEffect
9 | ##Action that plays when the button is let go either with mouse or UI input. Has no connection with [member BaseButton.action_mode]
10 | @export var on_button_up : ActionButtonEffect
11 | ##Action that plays when the button is back to its original base state. In most use cases this can be left at default values or be [code]null[/code].
12 | @export var on_rest : ActionButtonEffect
13 |
14 | ##Reference to the audio stream used for [member on_hover]
15 | var stream_hover : AudioStreamPlayer
16 | ##Reference to the audio stream used for [member on_button_down]
17 | var stream_button_down : AudioStreamPlayer
18 | ##Reference to the audio stream used for [member on_button_up]
19 | var stream_button_up : AudioStreamPlayer
20 | ##Reference to the audio stream used for [member on_rest]
21 | var stream_rest : AudioStreamPlayer
22 |
23 | var tween : Tween
24 | var tween_reset : Tween
25 | ##Default effect that is used when a [ActionButtonEffect] is not set for a state.
26 | var fallback_property : ActionButtonEffect
27 |
28 | ##Keeps track of where the "original" position of the button is. If you are moving the button outside of this code you might want to set this variable.
29 | var default_position : Vector2
30 | var default_z_index : int
31 | enum state {REST, HOVER, BUTTON_DOWN, BUTTON_UP}
32 | var current_state : state
33 | var is_focused : bool
34 | var audio_manager : Node
35 |
36 |
37 |
38 | func _ready() -> void:
39 | await get_tree().process_frame
40 |
41 | init_audio()
42 |
43 | mouse_entered.connect(_on_mouse_entered)
44 | mouse_exited.connect(_on_mouse_exited)
45 |
46 | focus_entered.connect(_on_focus_entered)
47 | focus_exited.connect(_on_focus_exited)
48 |
49 | button_down.connect(_on_button_down)
50 | button_up.connect(_on_button_up)
51 |
52 | toggled.connect(_on_toggle)
53 |
54 | var parent = get_parent_control()
55 | if parent is Container:
56 | parent.sort_children.connect(_on_container_sort)
57 |
58 | if on_hover == null or on_button_up == null or on_button_down == null or on_rest == null:
59 | fallback_property = ActionButtonEffect.new()
60 |
61 | default_position = position
62 | default_z_index = z_index
63 | pivot_offset = size / 2
64 |
65 | reset()
66 |
67 |
68 | ##Sets up all the audio stuff with the global ActionButtonAudio so the button can have sounds.
69 | func init_audio() -> void:
70 | #ATTENTION, if this is giving you an errors you probably did not enable the plugin in project settings
71 | stream_hover = ActionButtonAudio.append_audio(on_hover)
72 | stream_button_down = ActionButtonAudio.append_audio(on_button_down)
73 | stream_button_up = ActionButtonAudio.append_audio(on_button_up)
74 | stream_rest = ActionButtonAudio.append_audio(on_rest)
75 |
76 |
77 | func _on_container_sort() -> void:
78 | default_position = position
79 | if tween_reset:
80 | tween_reset.kill()
81 | if tween:
82 | tween.kill()
83 | reset()
84 |
85 |
86 | func _on_mouse_entered():
87 | if toggle_mode and button_pressed:
88 | return
89 | if disabled:
90 | return
91 | if is_focused:
92 | return
93 | if toggle_mode and button_pressed:
94 | return
95 | if stream_hover:
96 | stream_hover.play()
97 | tween_it(on_hover, state.HOVER, false, true)
98 |
99 |
100 | func _on_mouse_exited():
101 | if disabled:
102 | return
103 | if toggle_mode and button_pressed:
104 | return
105 | if stream_rest:
106 | stream_rest.play()
107 | tween_it_reset()
108 |
109 |
110 | func _on_focus_entered():
111 | if toggle_mode and button_pressed:
112 | return
113 | if disabled:
114 | return
115 | if is_hovered():
116 | return
117 | if stream_hover:
118 | stream_hover.play()
119 | is_focused = true
120 | tween_it(on_hover, state.HOVER, false, true)
121 |
122 |
123 | func _on_focus_exited():
124 | if disabled:
125 | return
126 | if is_hovered():
127 | return
128 | if toggle_mode and button_pressed:
129 | return
130 | is_focused = false
131 | tween_it_reset()
132 |
133 |
134 | func _on_button_down():
135 | if toggle_mode:
136 | return
137 | if stream_button_down:
138 | stream_button_down.play()
139 | tween_it(on_button_down, state.BUTTON_DOWN)
140 |
141 |
142 | func _on_button_up():
143 | if toggle_mode:
144 | return
145 | if stream_button_up:
146 | stream_button_up.play()
147 | tween_it(on_button_up, state.BUTTON_UP, true)
148 |
149 |
150 | func _on_toggle(toggled_on : bool):
151 | if toggle_mode:
152 | if toggled_on:
153 | if stream_button_down:
154 | stream_button_down.play()
155 | tween_it(on_button_down, state.BUTTON_DOWN)
156 | else:
157 | if tween_reset:
158 | tween_reset.kill()
159 | if stream_button_up:
160 | stream_button_up.play()
161 | tween_it(on_button_up, state.BUTTON_UP, true)
162 |
163 |
164 | ## Tweens to a state.
165 | func tween_it(property : ActionButtonEffect, what_state : state ,reset_after_done : bool = false, override : bool = false) -> void:
166 | if current_state == what_state:
167 | return
168 | if tween:
169 | if tween.is_running() and override:
170 | return
171 | tween.kill()
172 | if property == null:
173 | property = fallback_property
174 | z_index = default_z_index+100
175 | current_state = what_state
176 | tween = create_tween()
177 | tween.set_trans(property.transition_type)
178 | tween.set_ease(property.ease_type)
179 | tween.set_parallel(true)
180 | tween.tween_property(self, "position", default_position + property.position, property.motion_duration)
181 | tween.tween_property(self, "rotation_degrees", property.rotation, property.motion_duration)
182 | tween.tween_property(self, "scale", property.scale, property.motion_duration)
183 | tween.tween_property(self, "self_modulate", property.color, property.motion_duration)
184 | await tween.finished
185 | if reset_after_done:
186 | if is_hovered():
187 | tween_it(on_hover, state.HOVER)
188 | else:
189 | tween_it_reset()
190 |
191 |
192 | ##Tweens to [memeber on_rest]
193 | func tween_it_reset():
194 | var property : ActionButtonEffect = on_rest
195 | if current_state == state.REST:
196 | return
197 | if tween_reset:
198 | tween_reset.kill()
199 | if tween:
200 | tween.kill()
201 | if property == null:
202 | property = fallback_property
203 | z_index = default_z_index
204 | current_state = state.REST
205 | tween_reset = create_tween()
206 | tween_reset.set_trans(property.transition_type)
207 | tween_reset.set_ease(property.ease_type)
208 | tween_reset.set_parallel(true)
209 | tween_reset.tween_property(self, "position", default_position + property.position, property.motion_duration)
210 | tween_reset.tween_property(self, "rotation_degrees", property.rotation, property.motion_duration)
211 | tween_reset.tween_property(self, "scale", property.scale, property.motion_duration)
212 | tween_reset.tween_property(self, "self_modulate", property.color, property.motion_duration)
213 |
214 |
215 | ##Reset to [member on_rest] immediately
216 | func reset():
217 | var property : ActionButtonEffect = on_rest
218 | if property == null:
219 | property = fallback_property
220 | position = default_position + property.position
221 | rotation_degrees = property.rotation
222 | scale = Vector2.ONE * property.scale
223 | self_modulate = property.color
224 |
--------------------------------------------------------------------------------
/addons/action_button/action_button.gd.uid:
--------------------------------------------------------------------------------
1 | uid://di11q0mhb4hdo
2 |
--------------------------------------------------------------------------------
/addons/action_button/action_button_autoload.gd:
--------------------------------------------------------------------------------
1 | @icon("res://addons/action_button/icons/ActionButtonAudio.svg")
2 | extends Node
3 |
4 | var streams : Dictionary[String, AudioStreamPlayer]
5 |
6 | ##Function that appends and keeps reference of sounds to use for ActionButton.
7 | ##Where possible it will reuse sounds if they have the same settings.
8 | func append_audio(property : ActionButtonEffect) -> AudioStreamPlayer:
9 | if !property:
10 | return null
11 | if !property.audio_stream:
12 | return null
13 |
14 | var path : String = property.audio_stream.resource_path
15 | var key : String = path
16 | key += str(property.volume_db)
17 | key += str(property.pitch_scale)
18 | key += str(property.max_polyphony)
19 | key += property.bus
20 |
21 | var has = streams.has(key)
22 | if has:
23 | return streams[key]
24 | else:
25 | var stream : AudioStreamPlayer = AudioStreamPlayer.new()
26 | stream.stream = property.audio_stream
27 | stream.volume_db = property.volume_db
28 | stream.pitch_scale = property.pitch_scale
29 | stream.max_polyphony = property.max_polyphony
30 | stream.bus = property.bus
31 | stream.name = path.get_file().trim_suffix("." + path.get_extension()) + "_00"
32 | streams[key] = stream
33 | add_child(stream, true)
34 | return streams[key]
35 |
--------------------------------------------------------------------------------
/addons/action_button/action_button_autoload.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dqc44ymqkgy64
2 |
--------------------------------------------------------------------------------
/addons/action_button/action_button_effect.gd:
--------------------------------------------------------------------------------
1 | @icon("res://addons/action_button/icons/ActionButtonEffect.svg")
2 | class_name ActionButtonEffect
3 | extends Resource
4 | ##Defines the parameters for how to animate and what sonuds to emit for a [ActionButton] state.
5 |
6 | ##For how long the motion will animate for in seconds.
7 | @export var motion_duration : float = 0.1
8 | ##How much to offset the position of the button when animated. Big values might make the button behave unexpecedly.
9 | @export_custom(PROPERTY_HINT_NONE, "suffix:px") var position : Vector2
10 | ##How much to rotate the button when animated, in degrees.
11 | @export_range(-360, 360, 0.1, "degrees", "or_greater", "or_less") var rotation : float
12 | ##How much to scale the button when animated.
13 | @export_custom(PROPERTY_HINT_LINK, "") var scale : Vector2 = Vector2.ONE
14 | ##How much to modulate the color of the button when animated, uses self-modulate.
15 | @export var color : Color = Color.WHITE
16 | @export var transition_type: Tween.TransitionType
17 | @export var ease_type: Tween.EaseType
18 | @export_category("Audio")
19 | ##What sound to emit when this action happens, sounds are reused globally when possible (in ActionButtonAudio autoload).
20 | @export var audio_stream : AudioStream
21 | ##Volume of sound, in decibels.
22 | @export_range(-80, 24, 0.001, "suffix:dB") var volume_db : float
23 | ##The audio's pitch and tempo, as a multiplier of the stream's sample rate.
24 | @export_range(0.01, 4, 0.01, "or_greater") var pitch_scale : float = 1
25 | ##How many times this sound can play at the same time.
26 | @export_range(0, 2147483647) var max_polyphony : int = 1
27 | ##The target bus name. The sound will be playing on this bus.
28 | @export var bus : StringName = "Master"
29 |
--------------------------------------------------------------------------------
/addons/action_button/action_button_effect.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bbmr3yytorn4r
2 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
73 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButton.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://d3nuoocxhnijm"
6 | path="res://.godot/imported/ActionButton.svg-671b6c8eea1c45fe0aebd7ae8ea41f05.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/action_button/icons/ActionButton.svg"
14 | dest_files=["res://.godot/imported/ActionButton.svg-671b6c8eea1c45fe0aebd7ae8ea41f05.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButtonAudio.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButtonAudio.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://dgnsitq6anbme"
6 | path="res://.godot/imported/ActionButtonAudio.svg-be7ace593a399a4d1eb9062ff49ae307.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/action_button/icons/ActionButtonAudio.svg"
14 | dest_files=["res://.godot/imported/ActionButtonAudio.svg-be7ace593a399a4d1eb9062ff49ae307.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButtonEffect.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/addons/action_button/icons/ActionButtonEffect.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://ctds3uq3vefc1"
6 | path="res://.godot/imported/ActionButtonEffect.svg-0db0885d69112be98c7323edc99d43ab.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/action_button/icons/ActionButtonEffect.svg"
14 | dest_files=["res://.godot/imported/ActionButtonEffect.svg-0db0885d69112be98c7323edc99d43ab.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/action_button/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="Action Button"
4 | description="Button with extended audio visual capabilities"
5 | author="Hapty"
6 | version="1.0"
7 | script="plugin.gd"
8 |
--------------------------------------------------------------------------------
/addons/action_button/plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 |
4 | const AUTOLOAD_NAME = "ActionButtonAudio"
5 | const AUTOLOAD_PATH = "res://addons/action_button/action_button_autoload.gd"
6 |
7 | func _enable_plugin():
8 | add_autoload_singleton(AUTOLOAD_NAME, AUTOLOAD_PATH)
9 |
10 | func _disable_plugin():
11 | remove_autoload_singleton(AUTOLOAD_NAME)
12 |
--------------------------------------------------------------------------------
/addons/action_button/plugin.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dyln6lq2c2pdx
2 |
--------------------------------------------------------------------------------
/demo_action_button/action_button_demo.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=17 format=3 uid="uid://v7jp6ksajc3g"]
2 |
3 | [ext_resource type="Script" uid="uid://di11q0mhb4hdo" path="res://addons/action_button/action_button.gd" id="1_gx22s"]
4 | [ext_resource type="Script" uid="uid://bbmr3yytorn4r" path="res://addons/action_button/action_button_effect.gd" id="2_h2i6h"]
5 | [ext_resource type="AudioStream" uid="uid://b5vyle6fatqw2" path="res://demo_action_button/assets/cursor.mp3" id="3_dtld8"]
6 | [ext_resource type="AudioStream" uid="uid://7qb2vdolws16" path="res://demo_action_button/assets/decision.mp3" id="4_xb8g1"]
7 | [ext_resource type="AudioStream" uid="uid://bynw6hi6knbpj" path="res://demo_action_button/assets/paper-take.mp3" id="5_s40ro"]
8 | [ext_resource type="AudioStream" uid="uid://dui53pbcgoy2k" path="res://demo_action_button/assets/cork-plug.mp3" id="6_2gyio"]
9 |
10 | [sub_resource type="Resource" id="Resource_fcyx5"]
11 | script = ExtResource("2_h2i6h")
12 | motion_duration = 0.1
13 | position = Vector2(0, -8)
14 | rotation = 0.0
15 | scale = Vector2(1, 1)
16 | color = Color(1, 1, 1, 1)
17 | transition_type = 0
18 | ease_type = 0
19 | volume_db = 0.0
20 | pitch_scale = 1.0
21 | max_polyphony = 1
22 | bus = &"Master"
23 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
24 |
25 | [sub_resource type="Resource" id="Resource_0h0yp"]
26 | script = ExtResource("2_h2i6h")
27 | motion_duration = 0.05
28 | position = Vector2(0, 8)
29 | rotation = 0.0
30 | scale = Vector2(1, 1)
31 | color = Color(1, 1, 1, 1)
32 | transition_type = 4
33 | ease_type = 1
34 | audio_stream = ExtResource("3_dtld8")
35 | volume_db = 0.0
36 | pitch_scale = 0.9
37 | max_polyphony = 1
38 | bus = &"Master"
39 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
40 |
41 | [sub_resource type="Resource" id="Resource_w3kbx"]
42 | script = ExtResource("2_h2i6h")
43 | motion_duration = 0.1
44 | position = Vector2(0, -8)
45 | rotation = 0.0
46 | scale = Vector2(1, 1)
47 | color = Color(1, 1, 1, 1)
48 | transition_type = 9
49 | ease_type = 1
50 | audio_stream = ExtResource("3_dtld8")
51 | volume_db = 0.0
52 | pitch_scale = 1.0
53 | max_polyphony = 1
54 | bus = &"Master"
55 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
56 |
57 | [sub_resource type="Resource" id="Resource_k2f74"]
58 | script = ExtResource("2_h2i6h")
59 | motion_duration = 0.15
60 | position = Vector2(0, 0)
61 | rotation = 0.0
62 | scale = Vector2(1.1, 1.1)
63 | color = Color(1, 1, 1, 1)
64 | transition_type = 4
65 | ease_type = 0
66 | volume_db = 0.0
67 | pitch_scale = 0.7
68 | max_polyphony = 1
69 | bus = &"Master"
70 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
71 |
72 | [sub_resource type="Resource" id="Resource_svrvd"]
73 | script = ExtResource("2_h2i6h")
74 | motion_duration = 0.2
75 | position = Vector2(0, 0)
76 | rotation = 0.0
77 | scale = Vector2(0.9, 0.9)
78 | color = Color(1, 1, 1, 1)
79 | transition_type = 5
80 | ease_type = 1
81 | volume_db = 0.0
82 | pitch_scale = 1.0
83 | max_polyphony = 1
84 | bus = &"Master"
85 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
86 |
87 | [sub_resource type="Resource" id="Resource_5orp4"]
88 | script = ExtResource("2_h2i6h")
89 | motion_duration = 0.1
90 | position = Vector2(0, 0)
91 | rotation = 0.0
92 | scale = Vector2(1.25, 1.25)
93 | color = Color(1, 1, 1, 1)
94 | transition_type = 4
95 | ease_type = 1
96 | audio_stream = ExtResource("4_xb8g1")
97 | volume_db = -10.0
98 | pitch_scale = 1.4
99 | max_polyphony = 1
100 | bus = &"Master"
101 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
102 |
103 | [sub_resource type="Resource" id="Resource_eygla"]
104 | script = ExtResource("2_h2i6h")
105 | motion_duration = 0.1
106 | position = Vector2(0, -4)
107 | rotation = -1.0
108 | scale = Vector2(1.1, 1.1)
109 | color = Color(0.647645, 0.489049, 0.841254, 1)
110 | transition_type = 0
111 | ease_type = 0
112 | audio_stream = ExtResource("5_s40ro")
113 | volume_db = -12.0
114 | pitch_scale = 2.0
115 | max_polyphony = 2
116 | bus = &"Master"
117 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
118 |
119 | [sub_resource type="Resource" id="Resource_3gv6m"]
120 | script = ExtResource("2_h2i6h")
121 | motion_duration = 0.1
122 | position = Vector2(0, -4)
123 | rotation = -5.0
124 | scale = Vector2(1, 1)
125 | color = Color(0.585062, 0.585062, 0.585062, 1)
126 | transition_type = 2
127 | ease_type = 1
128 | audio_stream = ExtResource("6_2gyio")
129 | volume_db = -20.0
130 | pitch_scale = 1.3
131 | max_polyphony = 1
132 | bus = &"Master"
133 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
134 |
135 | [sub_resource type="Resource" id="Resource_udfxo"]
136 | script = ExtResource("2_h2i6h")
137 | motion_duration = 0.08
138 | position = Vector2(0, -4)
139 | rotation = 7.5
140 | scale = Vector2(1, 1)
141 | color = Color(2, 2, 2, 1)
142 | transition_type = 3
143 | ease_type = 1
144 | audio_stream = ExtResource("6_2gyio")
145 | volume_db = -20.0
146 | pitch_scale = 1.0
147 | max_polyphony = 1
148 | bus = &"Master"
149 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
150 |
151 | [sub_resource type="Resource" id="Resource_774mx"]
152 | script = ExtResource("2_h2i6h")
153 | motion_duration = 0.1
154 | position = Vector2(0, 0)
155 | rotation = 0.0
156 | scale = Vector2(1, 1)
157 | color = Color(1, 1, 1, 1)
158 | transition_type = 0
159 | ease_type = 0
160 | audio_stream = ExtResource("5_s40ro")
161 | volume_db = -12.0
162 | pitch_scale = 1.8
163 | max_polyphony = 1
164 | bus = &"Master"
165 | metadata/_custom_type_script = "uid://bbmr3yytorn4r"
166 |
167 | [node name="ButtonPlusDemo" type="Control"]
168 | layout_mode = 3
169 | anchors_preset = 15
170 | anchor_right = 1.0
171 | anchor_bottom = 1.0
172 | grow_horizontal = 2
173 | grow_vertical = 2
174 |
175 | [node name="GridContainer" type="GridContainer" parent="."]
176 | layout_mode = 1
177 | anchors_preset = 8
178 | anchor_left = 0.5
179 | anchor_top = 0.5
180 | anchor_right = 0.5
181 | anchor_bottom = 0.5
182 | offset_left = -344.0
183 | offset_top = -89.0
184 | offset_right = 345.0
185 | offset_bottom = 94.0
186 | grow_horizontal = 2
187 | grow_vertical = 2
188 | columns = 3
189 |
190 | [node name="ButtonPlus" type="Button" parent="GridContainer"]
191 | layout_mode = 2
192 | size_flags_vertical = 3
193 | focus_neighbor_bottom = NodePath("../ButtonPlus4")
194 | theme_override_font_sizes/font_size = 32
195 | text = "Clicky button"
196 | script = ExtResource("1_gx22s")
197 | on_hover = SubResource("Resource_fcyx5")
198 | on_button_down = SubResource("Resource_0h0yp")
199 | on_button_up = SubResource("Resource_w3kbx")
200 | metadata/_custom_type_script = "uid://di11q0mhb4hdo"
201 |
202 | [node name="ButtonPlus5" type="Button" parent="GridContainer"]
203 | layout_mode = 2
204 | size_flags_vertical = 3
205 | theme_override_font_sizes/font_size = 32
206 | text = "Bouncy button"
207 | script = ExtResource("1_gx22s")
208 | on_hover = SubResource("Resource_k2f74")
209 | on_button_down = SubResource("Resource_svrvd")
210 | on_button_up = SubResource("Resource_5orp4")
211 | metadata/_custom_type_script = "uid://di11q0mhb4hdo"
212 |
213 | [node name="ButtonPlus3" type="Button" parent="GridContainer"]
214 | layout_mode = 2
215 | size_flags_vertical = 3
216 | theme_override_font_sizes/font_size = 32
217 | text = "Wacky button"
218 | script = ExtResource("1_gx22s")
219 | on_hover = SubResource("Resource_eygla")
220 | on_button_down = SubResource("Resource_3gv6m")
221 | on_button_up = SubResource("Resource_udfxo")
222 | on_rest = SubResource("Resource_774mx")
223 | metadata/_custom_type_script = "uid://di11q0mhb4hdo"
224 |
225 | [node name="ButtonPlus4" type="Button" parent="GridContainer"]
226 | layout_mode = 2
227 | size_flags_vertical = 3
228 | theme_override_font_sizes/font_size = 32
229 | toggle_mode = true
230 | text = "Toggle button"
231 | script = ExtResource("1_gx22s")
232 | on_hover = SubResource("Resource_fcyx5")
233 | on_button_down = SubResource("Resource_0h0yp")
234 | on_button_up = SubResource("Resource_w3kbx")
235 | metadata/_custom_type_script = "uid://di11q0mhb4hdo"
236 |
237 | [node name="ButtonPlus6" type="Button" parent="GridContainer"]
238 | layout_mode = 2
239 | size_flags_vertical = 3
240 | theme_override_font_sizes/font_size = 32
241 | disabled = true
242 | text = "Disabled button"
243 | script = ExtResource("1_gx22s")
244 | on_hover = SubResource("Resource_eygla")
245 | on_button_down = SubResource("Resource_3gv6m")
246 | on_button_up = SubResource("Resource_udfxo")
247 | on_rest = SubResource("Resource_774mx")
248 | metadata/_custom_type_script = "uid://di11q0mhb4hdo"
249 |
--------------------------------------------------------------------------------
/demo_action_button/assets/cork-plug.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HappyHeads/ActionButton/8b17c94eb61e8bded163a208f74c4e8998c9f566/demo_action_button/assets/cork-plug.mp3
--------------------------------------------------------------------------------
/demo_action_button/assets/cork-plug.mp3.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="mp3"
4 | type="AudioStreamMP3"
5 | uid="uid://dui53pbcgoy2k"
6 | path="res://.godot/imported/cork-plug.mp3-00f5fe5ab62d6f9f5b7fe4bc44c0edf3.mp3str"
7 |
8 | [deps]
9 |
10 | source_file="res://demo_action_button/assets/cork-plug.mp3"
11 | dest_files=["res://.godot/imported/cork-plug.mp3-00f5fe5ab62d6f9f5b7fe4bc44c0edf3.mp3str"]
12 |
13 | [params]
14 |
15 | loop=false
16 | loop_offset=0
17 | bpm=0
18 | beat_count=0
19 | bar_beats=4
20 |
--------------------------------------------------------------------------------
/demo_action_button/assets/cursor.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HappyHeads/ActionButton/8b17c94eb61e8bded163a208f74c4e8998c9f566/demo_action_button/assets/cursor.mp3
--------------------------------------------------------------------------------
/demo_action_button/assets/cursor.mp3.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="mp3"
4 | type="AudioStreamMP3"
5 | uid="uid://b5vyle6fatqw2"
6 | path="res://.godot/imported/cursor.mp3-416808f0e37240f8bd15b617500fbe91.mp3str"
7 |
8 | [deps]
9 |
10 | source_file="res://demo_action_button/assets/cursor.mp3"
11 | dest_files=["res://.godot/imported/cursor.mp3-416808f0e37240f8bd15b617500fbe91.mp3str"]
12 |
13 | [params]
14 |
15 | loop=false
16 | loop_offset=0
17 | bpm=0
18 | beat_count=0
19 | bar_beats=4
20 |
--------------------------------------------------------------------------------
/demo_action_button/assets/decision.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HappyHeads/ActionButton/8b17c94eb61e8bded163a208f74c4e8998c9f566/demo_action_button/assets/decision.mp3
--------------------------------------------------------------------------------
/demo_action_button/assets/decision.mp3.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="mp3"
4 | type="AudioStreamMP3"
5 | uid="uid://7qb2vdolws16"
6 | path="res://.godot/imported/decision.mp3-31c858d6f130111ee7abb18d4c5f88af.mp3str"
7 |
8 | [deps]
9 |
10 | source_file="res://demo_action_button/assets/decision.mp3"
11 | dest_files=["res://.godot/imported/decision.mp3-31c858d6f130111ee7abb18d4c5f88af.mp3str"]
12 |
13 | [params]
14 |
15 | loop=false
16 | loop_offset=0
17 | bpm=0
18 | beat_count=0
19 | bar_beats=4
20 |
--------------------------------------------------------------------------------
/demo_action_button/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HappyHeads/ActionButton/8b17c94eb61e8bded163a208f74c4e8998c9f566/demo_action_button/assets/icon.png
--------------------------------------------------------------------------------
/demo_action_button/assets/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cq6ij8p75omcr"
6 | path="res://.godot/imported/icon.png-fd8d368fd28c993ddad1007c1f9e64f1.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://demo_action_button/assets/icon.png"
14 | dest_files=["res://.godot/imported/icon.png-fd8d368fd28c993ddad1007c1f9e64f1.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/demo_action_button/assets/paper-take.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HappyHeads/ActionButton/8b17c94eb61e8bded163a208f74c4e8998c9f566/demo_action_button/assets/paper-take.mp3
--------------------------------------------------------------------------------
/demo_action_button/assets/paper-take.mp3.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="mp3"
4 | type="AudioStreamMP3"
5 | uid="uid://bynw6hi6knbpj"
6 | path="res://.godot/imported/paper-take.mp3-c46c23707a2093ee1586afc41af5373d.mp3str"
7 |
8 | [deps]
9 |
10 | source_file="res://demo_action_button/assets/paper-take.mp3"
11 | dest_files=["res://.godot/imported/paper-take.mp3-c46c23707a2093ee1586afc41af5373d.mp3str"]
12 |
13 | [params]
14 |
15 | loop=false
16 | loop_offset=0
17 | bpm=0
18 | beat_count=0
19 | bar_beats=4
20 |
--------------------------------------------------------------------------------
/demo_action_button/assets/sound credit.txt:
--------------------------------------------------------------------------------
1 | All of these demo sounds are from (https://soundeffect-lab.info/)
--------------------------------------------------------------------------------
/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="ActionButton"
14 | run/main_scene="uid://v7jp6ksajc3g"
15 | config/features=PackedStringArray("4.4", "Forward Plus")
16 | config/icon="uid://cq6ij8p75omcr"
17 |
18 | [autoload]
19 |
20 | ActionButtonAudio="*res://addons/action_button/action_button_autoload.gd"
21 |
22 | [editor_plugins]
23 |
24 | enabled=PackedStringArray("res://addons/action_button/plugin.cfg")
25 |
--------------------------------------------------------------------------------