├── .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 | ![GIF 27-03-2025 8-39-25](https://github.com/user-attachments/assets/c84f9abf-dfec-4867-b0c2-ffce9ea7e220) 5 | 6 | ![2025-03-27_08-40-57-Godot_v4 4 1-stable_win64 - Copy](https://github.com/user-attachments/assets/6623d69e-f6c5-4ad7-8314-8397eb5b609e) 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 | 14 | 16 | 27 | 38 | 39 | 58 | 62 | 68 | 72 | 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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 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 | 4 | 5 | 6 | 7 | 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 | --------------------------------------------------------------------------------