Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
|
947bdba21e | ||
|
194ae93854 | ||
|
dd5b4bcae5 | ||
|
45193fc27f | ||
|
78b4a3bba2 | ||
|
d92086f600 | ||
|
21e927966d | ||
|
431fb8220e | ||
|
520a5db2c6 | ||
|
7ff15597a0 | ||
|
bcebec2656 | ||
|
4c881027a1 | ||
|
4676b83b61 | ||
|
9a2b3c1677 | ||
|
2f0e5a59d9 | ||
|
9b8f4db275 |
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: Ericdowney
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. macOS]
|
||||||
|
- Godot Version [e.g. 4.1.1 stable]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
5
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
||||||
# Godot 4+ specific ignores
|
# Godot 4+ specific ignores
|
||||||
.godot/
|
.godot/
|
||||||
|
|
||||||
/android/
|
images/
|
||||||
/builds/
|
android/
|
||||||
|
builds/
|
||||||
|
|
BIN
Megamichisfont-small.otf
Normal file
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
importer="font_data_dynamic"
|
importer="font_data_dynamic"
|
||||||
type="FontFile"
|
type="FontFile"
|
||||||
uid="uid://ddcous2vnc3ux"
|
uid="uid://ddvhypxkj8a1b"
|
||||||
path="res://.godot/imported/m5x7.ttf-ede74fbe3753eb2fe0ebc455b7b3a4db.fontdata"
|
path="res://.godot/imported/Megamichisfont-small.otf-43fae38c860095c22170042e51803feb.fontdata"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://m5x7.ttf"
|
source_file="res://Megamichisfont-small.otf"
|
||||||
dest_files=["res://.godot/imported/m5x7.ttf-ede74fbe3753eb2fe0ebc455b7b3a4db.fontdata"]
|
dest_files=["res://.godot/imported/Megamichisfont-small.otf-43fae38c860095c22170042e51803feb.fontdata"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
8
README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# DuckRun ![ ](https://teapot.informationsanarchistik.de/Megamichi/DuckRun/raw/branch/main/icon.png)
|
||||||
|
DuckRun ist ein einfacher Chrome Dino Clone programmiert in der Godot Game Engine.
|
||||||
|
|
||||||
|
|
||||||
|
[Downloads](https://teapot.informationsanarchistik.de/Megamichi/DuckRun/releases)
|
||||||
|
|
||||||
|
Bei Verbesserungsvorschlägen oder Ideen bitte bei Michi melden :)
|
||||||
|
###### [Godot Lizenz](https://godotengine.org/license/)
|
1
addons/SignalVisualizer/Clear.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="24" viewBox="0 0 16 16" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v5h-2c-1.108 0-2 .892-2 2v1h10v-1c0-1.108-.892-2-2-2h-2v-5a1 1 0 0 0 -1-1zm-5 10v4l10-1v-3z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 227 B |
37
addons/SignalVisualizer/Clear.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bmnff63evbdhv"
|
||||||
|
path="res://.godot/imported/Clear.svg-d661617e27b91e3580171e3447fde514.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/SignalVisualizer/Clear.svg"
|
||||||
|
dest_files=["res://.godot/imported/Clear.svg-d661617e27b91e3580171e3447fde514.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
58
addons/SignalVisualizer/Common/signal_connection.gd
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
class_name SignalConnection extends Object
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var signal_id: int
|
||||||
|
var source_node_name: String
|
||||||
|
var destination_node_name: String
|
||||||
|
var method_signature: String
|
||||||
|
|
||||||
|
var description: String :
|
||||||
|
get:
|
||||||
|
return "ID: {signal_id} Source: {source_node_name} Destination: {destination_node_name} Method: {method_signature}".format({
|
||||||
|
"signal_id": signal_id,
|
||||||
|
"source_node_name": source_node_name,
|
||||||
|
"destination_node_name": destination_node_name,
|
||||||
|
"method_signature": method_signature,
|
||||||
|
})
|
||||||
|
|
||||||
|
var dictionary_key: String :
|
||||||
|
get:
|
||||||
|
return "{signal_id}__{source_node_name}__{destination_node_name}__{method_signature}".format({ "signal_id": signal_id, "source_node_name": source_node_name, "destination_node_name": destination_node_name, "method_signature": method_signature.replace("::", "_") })
|
||||||
|
|
||||||
|
var dictionary_representation: Dictionary :
|
||||||
|
get:
|
||||||
|
return {
|
||||||
|
"signal_id": signal_id,
|
||||||
|
"source_node_name": source_node_name,
|
||||||
|
"destination_node_name": destination_node_name,
|
||||||
|
"method_signature": method_signature,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _init(signal_id: int, source_node_name: String, destination_node_name: String, method_signature: String):
|
||||||
|
self.signal_id = signal_id
|
||||||
|
self.source_node_name = source_node_name
|
||||||
|
self.destination_node_name = destination_node_name
|
||||||
|
self.method_signature = method_signature
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
56
addons/SignalVisualizer/Common/signal_description.gd
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
class_name SignalDescription extends Object
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var id: int:
|
||||||
|
get:
|
||||||
|
if _source_id != null:
|
||||||
|
return _source_id
|
||||||
|
return get_instance_id()
|
||||||
|
|
||||||
|
var node_name: String
|
||||||
|
var signal_name: String
|
||||||
|
|
||||||
|
var description: String :
|
||||||
|
get:
|
||||||
|
return "ID: {id} Node: {node_name} Signal: {signal_name}".format({
|
||||||
|
"id": id,
|
||||||
|
"node_name": node_name,
|
||||||
|
"signal_name": signal_name,
|
||||||
|
})
|
||||||
|
|
||||||
|
var dictionary_representation: Dictionary :
|
||||||
|
get:
|
||||||
|
return {
|
||||||
|
"id": id,
|
||||||
|
"node_name": node_name,
|
||||||
|
"signal_name": signal_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
var _source_id = null
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _init(node_name: String, signal_name: String):
|
||||||
|
self.node_name = node_name
|
||||||
|
self.signal_name = signal_name
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
53
addons/SignalVisualizer/Common/signal_graph.gd
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
class_name SignalGraph extends Object
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var name: String
|
||||||
|
var signals: Array[SignalDescription]
|
||||||
|
var edges: Array[SignalConnection]
|
||||||
|
|
||||||
|
var description: String :
|
||||||
|
get:
|
||||||
|
return "Signals: {signals}\nEdges: {edges}".format({
|
||||||
|
"signals": signals.map(func (item): return item.description),
|
||||||
|
"edges": edges.map(func (item): return item.description),
|
||||||
|
})
|
||||||
|
|
||||||
|
var dictionary_representation: Dictionary :
|
||||||
|
get:
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"signals": signals.map(func (element): return element.dictionary_representation),
|
||||||
|
"edges": edges.map(func (element): return element.dictionary_representation),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _init(name: String, signals: Array[SignalDescription] = [], edges: Array[SignalConnection] = []):
|
||||||
|
self.name = name
|
||||||
|
self.signals = signals
|
||||||
|
self.edges = edges
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func get_source_signal_for_edge(edge: SignalConnection) -> SignalDescription:
|
||||||
|
var result = signals.filter(func (item): return item.id == edge.signal_id)
|
||||||
|
if result.size() > 0:
|
||||||
|
return result[0]
|
||||||
|
return null
|
170
addons/SignalVisualizer/Common/signal_graph_utility.gd
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
@tool
|
||||||
|
class_name SignalGraphUtility
|
||||||
|
|
||||||
|
static var SignalGraphNode = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node.tscn")
|
||||||
|
static var GraphNodeItem = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node_item.tscn")
|
||||||
|
|
||||||
|
const SOURCE_COLOR: Color = Color.SKY_BLUE
|
||||||
|
const DESTINATION_COLOR: Color = Color.CORAL
|
||||||
|
const CONNECTION_TYPE: int = 0
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
static func create_signal_graph(name: String, signals: Array, edges: Array) -> SignalGraph:
|
||||||
|
var signal_graph = SignalGraph.new(name)
|
||||||
|
|
||||||
|
for signal_item in signals:
|
||||||
|
var new_signal_description = SignalDescription.new(signal_item.node_name, signal_item.signal_name)
|
||||||
|
new_signal_description._source_id = signal_item.id
|
||||||
|
signal_graph.signals.append(new_signal_description)
|
||||||
|
|
||||||
|
for connection in edges:
|
||||||
|
var new_edge = SignalConnection.new(connection.signal_id, connection.source_node_name, connection.destination_node_name, connection.method_signature)
|
||||||
|
signal_graph.edges.append(new_edge)
|
||||||
|
|
||||||
|
return signal_graph
|
||||||
|
|
||||||
|
static func create_signal_graph_from_node(root_node: Node, is_persistent_only: bool = false):
|
||||||
|
var signal_graph = SignalGraph.new(root_node.scene_file_path)
|
||||||
|
var all_nodes: Array[Node] = _gather_nodes_from_node(root_node)
|
||||||
|
var signals: Array[SignalDescription] = []
|
||||||
|
var edges: Array[SignalConnection] = []
|
||||||
|
|
||||||
|
for node in all_nodes:
|
||||||
|
for signal_item in node.get_signal_list():
|
||||||
|
var existing_signals = []
|
||||||
|
var connection_list = node.get_signal_connection_list(signal_item["name"] as String)
|
||||||
|
if connection_list.size() > 0:
|
||||||
|
for connection in connection_list:
|
||||||
|
var enabled_flags = connection["flags"] == CONNECT_PERSIST if is_persistent_only else true
|
||||||
|
var should_display_connection = "name" in connection["callable"].get_object() and not connection["callable"].get_object().name.begins_with("@") and enabled_flags
|
||||||
|
if should_display_connection:
|
||||||
|
var signal_description: SignalDescription
|
||||||
|
var filtered_signals = existing_signals.filter(func (element): return element.signal_name == signal_item.name and element.node_name == node.name)
|
||||||
|
if filtered_signals.size() == 1:
|
||||||
|
signal_description = filtered_signals[0]
|
||||||
|
else:
|
||||||
|
signal_description = SignalDescription.new(node.name, signal_item.name)
|
||||||
|
existing_signals.append(signal_description)
|
||||||
|
signals.append(signal_description)
|
||||||
|
|
||||||
|
var signal_edge = SignalConnection.new(signal_description.id, signal_description.node_name, connection["callable"].get_object().name, connection["callable"].get_method())
|
||||||
|
if not signal_graph.edges.any(func (element): return element.signal_id == signal_description.id):
|
||||||
|
edges.append(signal_edge)
|
||||||
|
|
||||||
|
var temp_signals = {}
|
||||||
|
for item in signals:
|
||||||
|
temp_signals[item.id] = item
|
||||||
|
|
||||||
|
var temp_edges = {}
|
||||||
|
for item in edges:
|
||||||
|
temp_edges[item.dictionary_key] = item
|
||||||
|
|
||||||
|
signal_graph.signals.assign(temp_signals.keys().map(func (key): return temp_signals[key]))
|
||||||
|
signal_graph.edges.assign(temp_edges.keys().map(func (key): return temp_edges[key]))
|
||||||
|
|
||||||
|
return signal_graph
|
||||||
|
|
||||||
|
static func generate_signal_graph_nodes(signal_graph: SignalGraph, graph_node: GraphEdit, open_script_callable: Callable):
|
||||||
|
var graph_nodes: Dictionary = {}
|
||||||
|
|
||||||
|
for signal_item in signal_graph.signals:
|
||||||
|
var current_graph_node: SignalGraphNode
|
||||||
|
if graph_nodes.has(signal_item.node_name):
|
||||||
|
current_graph_node = graph_nodes[signal_item.node_name]
|
||||||
|
if not current_graph_node:
|
||||||
|
current_graph_node = SignalGraphNode.instantiate()
|
||||||
|
current_graph_node.title = signal_item.node_name
|
||||||
|
current_graph_node.name = _get_graph_node_name(signal_item.node_name)
|
||||||
|
graph_node.add_child(current_graph_node)
|
||||||
|
graph_nodes[signal_item.node_name] = current_graph_node
|
||||||
|
|
||||||
|
for edge in signal_graph.edges:
|
||||||
|
var destination_graph_node: SignalGraphNode
|
||||||
|
if graph_nodes.has(edge.destination_node_name):
|
||||||
|
destination_graph_node = graph_nodes[edge.destination_node_name]
|
||||||
|
else:
|
||||||
|
destination_graph_node = SignalGraphNode.instantiate()
|
||||||
|
destination_graph_node.title = edge.destination_node_name
|
||||||
|
destination_graph_node.name = _get_graph_node_name(edge.destination_node_name)
|
||||||
|
graph_node.add_child(destination_graph_node)
|
||||||
|
graph_nodes[edge.destination_node_name] = destination_graph_node
|
||||||
|
|
||||||
|
var source_signal = signal_graph.get_source_signal_for_edge(edge)
|
||||||
|
if source_signal != null:
|
||||||
|
var source_graph_node: SignalGraphNode = graph_nodes[edge.source_node_name] as SignalGraphNode
|
||||||
|
|
||||||
|
if not source_graph_node.has_source_signal_description(source_signal.signal_name, edge.destination_node_name):
|
||||||
|
var source_signal_label = Label.new()
|
||||||
|
source_signal_label.text = source_signal.signal_name
|
||||||
|
source_signal_label.name = "source_" + source_signal.signal_name + "_" + edge.destination_node_name
|
||||||
|
source_graph_node.add_child(source_signal_label)
|
||||||
|
|
||||||
|
var destination_signal_name = "destination_" + source_signal.signal_name + "_" + edge.method_signature.replace("::", "__")
|
||||||
|
var has_destination = destination_graph_node.has_destination_signal_description(source_signal.signal_name, edge.method_signature)
|
||||||
|
if not has_destination:
|
||||||
|
var destination_signal_item = GraphNodeItem.instantiate()
|
||||||
|
destination_signal_item.signal_data = SignalGraphNodeItem.Metadata.new(source_signal.signal_name, edge.method_signature, edge.destination_node_name)
|
||||||
|
destination_signal_item.text = edge.method_signature
|
||||||
|
destination_signal_item.name = destination_signal_name
|
||||||
|
destination_signal_item.open_script.connect(open_script_callable)
|
||||||
|
destination_graph_node.add_child(destination_signal_item)
|
||||||
|
|
||||||
|
for edge in signal_graph.edges:
|
||||||
|
var source_signal = signal_graph.get_source_signal_for_edge(edge)
|
||||||
|
if source_signal != null:
|
||||||
|
var source_graph_node: SignalGraphNode = graph_nodes[edge.source_node_name] as SignalGraphNode
|
||||||
|
var destination_graph_node: SignalGraphNode = graph_nodes[edge.destination_node_name] as SignalGraphNode
|
||||||
|
|
||||||
|
var from_port = source_graph_node.get_source_slot(source_signal.signal_name, edge.destination_node_name)
|
||||||
|
var to_port = destination_graph_node.get_destination_slot(source_signal.signal_name, edge.method_signature)
|
||||||
|
|
||||||
|
source_graph_node.set_slot(from_port, false, CONNECTION_TYPE, Color.BLACK, true, CONNECTION_TYPE, SOURCE_COLOR)
|
||||||
|
destination_graph_node.set_slot(to_port, true, CONNECTION_TYPE, DESTINATION_COLOR, false, CONNECTION_TYPE, Color.BLACK)
|
||||||
|
|
||||||
|
var from_slot_index = source_graph_node.get_next_source_slot(source_signal.signal_name, edge.destination_node_name)
|
||||||
|
var to_slot_index = destination_graph_node.get_next_destination_slot(source_signal.signal_name, edge.method_signature)
|
||||||
|
|
||||||
|
if from_port >= 0 and to_port >= 0:
|
||||||
|
graph_node.connect_node(source_graph_node.name, from_slot_index, destination_graph_node.name, to_slot_index)
|
||||||
|
else:
|
||||||
|
print(">>> Invalid Connection Request")
|
||||||
|
|
||||||
|
static func generate_signal_graph_tree(signal_graph: SignalGraph, tree_node: Tree):
|
||||||
|
var root = tree_node.create_item()
|
||||||
|
root.set_text(0, signal_graph.name)
|
||||||
|
|
||||||
|
var tree_items: Dictionary = {}
|
||||||
|
|
||||||
|
for signal_item in signal_graph.signals:
|
||||||
|
var node_tree_item: TreeItem
|
||||||
|
if tree_items.has(signal_item.node_name):
|
||||||
|
node_tree_item = tree_items[signal_item.node_name] as TreeItem
|
||||||
|
else:
|
||||||
|
node_tree_item = tree_node.create_item(root)
|
||||||
|
node_tree_item.set_text(0, signal_item.node_name)
|
||||||
|
tree_items[signal_item.node_name] = node_tree_item
|
||||||
|
|
||||||
|
var signal_tree_item = tree_node.create_item(node_tree_item)
|
||||||
|
signal_tree_item.set_text(0, signal_item.signal_name)
|
||||||
|
|
||||||
|
for edge in signal_graph.edges.filter(func (item): return item.signal_id == signal_item.id):
|
||||||
|
var signal_connection_tree_item = tree_node.create_item(signal_tree_item)
|
||||||
|
signal_connection_tree_item.set_text(0, edge.destination_node_name + "::" + edge.method_signature)
|
||||||
|
|
||||||
|
static func _get_graph_node_name(name: String) -> String:
|
||||||
|
return "{node_name}_graph_node".format({ "node_name": name })
|
||||||
|
|
||||||
|
static func _gather_nodes_from_node(root_node: Node) -> Array[Node]:
|
||||||
|
var node_list: Array[Node] = [root_node]
|
||||||
|
return node_list + __gather_nodes_from_node(root_node)
|
||||||
|
|
||||||
|
static func __gather_nodes_from_node(node: Node) -> Array[Node]:
|
||||||
|
var nodes: Array[Node] = []
|
||||||
|
for child in node.get_children(false):
|
||||||
|
nodes.append(child)
|
||||||
|
nodes += __gather_nodes_from_node(child)
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
#endregion
|
146
addons/SignalVisualizer/Debugger/SignalDebugger.gd
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var _signal_graph: SignalGraph
|
||||||
|
var _lambda_map: Dictionary = {}
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if OS.is_debug_build():
|
||||||
|
EngineDebugger.register_message_capture("signal_debugger", _on_signal_debugger_message_capture)
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_signal_debugger_message_capture(message: String, data: Array) -> bool:
|
||||||
|
if message == "start":
|
||||||
|
_signal_graph = generate_signal_graph()
|
||||||
|
for signal_item in _signal_graph.signals:
|
||||||
|
_connect_to_signal(signal_item)
|
||||||
|
EngineDebugger.send_message(
|
||||||
|
"signal_debugger:generated_graph",
|
||||||
|
[[_signal_graph.signals.map(func (item): return item.dictionary_representation), _signal_graph.edges.map(func (item): return item.dictionary_representation)]]
|
||||||
|
)
|
||||||
|
if message == "stop" and _signal_graph:
|
||||||
|
for signal_item in _signal_graph.signals:
|
||||||
|
_disconnect_from_signal(signal_item)
|
||||||
|
|
||||||
|
if message == "invoke_signal" and data.size() == 2:
|
||||||
|
var node_name = data[0]
|
||||||
|
var signal_name = data[1]
|
||||||
|
|
||||||
|
var root_node = get_tree().current_scene
|
||||||
|
var node = root_node if root_node.name == node_name else root_node.find_child(node_name)
|
||||||
|
if node:
|
||||||
|
var connection_list = node.get_signal_connection_list(signal_name)
|
||||||
|
for connection in connection_list:
|
||||||
|
var callable = connection["callable"]
|
||||||
|
var bound_args = callable.get_bound_arguments()
|
||||||
|
var bound_args_count = callable.get_bound_arguments_count()
|
||||||
|
var method = callable.get_method()
|
||||||
|
callable.callv([node])
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
func _on_signal_execution(signal_name: String, node_name: String, args):
|
||||||
|
EngineDebugger.send_message(
|
||||||
|
"signal_debugger:signal_executed",
|
||||||
|
[Time.get_datetime_string_from_system(), node_name, signal_name]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func generate_signal_graph() -> SignalGraph:
|
||||||
|
var graph = SignalGraphUtility.create_signal_graph_from_node(get_tree().current_scene)
|
||||||
|
return graph
|
||||||
|
#var signal_graph = SignalGraph.new(get_tree().current_scene.name)
|
||||||
|
#var all_nodes: Array[Node] = _gather_nodes_in_scene()
|
||||||
|
#var signals: Array[SignalDescription] = []
|
||||||
|
#var edges: Array[SignalConnection] = []
|
||||||
|
#
|
||||||
|
#for node in all_nodes:
|
||||||
|
#for signal_item in node.get_signal_list():
|
||||||
|
#var existing_signals = []
|
||||||
|
#var connection_list = node.get_signal_connection_list(signal_item["name"] as String)
|
||||||
|
#if connection_list.size() > 0:
|
||||||
|
#for connection in connection_list:
|
||||||
|
#var should_display_connection = "name" in connection["callable"].get_object() and not connection["callable"].get_object().name.begins_with("@")
|
||||||
|
#if should_display_connection:
|
||||||
|
#var signal_description: SignalDescription
|
||||||
|
#var filtered_signals = existing_signals.filter(func (element): return element.signal_name == signal_item.name and element.node_name == node.name)
|
||||||
|
#if filtered_signals.size() == 1:
|
||||||
|
#signal_description = filtered_signals[0]
|
||||||
|
#else:
|
||||||
|
#signal_description = SignalDescription.new(node.name, signal_item.name)
|
||||||
|
#existing_signals.append(signal_description)
|
||||||
|
#signals.append(signal_description)
|
||||||
|
#
|
||||||
|
#var signal_edge = SignalConnection.new(signal_description.id, signal_description.node_name, connection["callable"].get_object().name, connection["callable"].get_method())
|
||||||
|
#if not signal_graph.edges.any(func (element): return element.signal_id == signal_description.id):
|
||||||
|
#edges.append(signal_edge)
|
||||||
|
#
|
||||||
|
#var temp_signals = {}
|
||||||
|
#for item in signals:
|
||||||
|
#temp_signals[item.id] = item
|
||||||
|
#
|
||||||
|
#var temp_edges = {}
|
||||||
|
#for item in edges:
|
||||||
|
#temp_edges[item.dictionary_key] = item
|
||||||
|
#
|
||||||
|
#signal_graph.signals.assign(temp_signals.keys().map(func (key): return temp_signals[key]))
|
||||||
|
#signal_graph.edges.assign(temp_edges.keys().map(func (key): return temp_edges[key]))
|
||||||
|
#
|
||||||
|
#return signal_graph
|
||||||
|
|
||||||
|
#func _gather_nodes_in_scene() -> Array[Node]:
|
||||||
|
#var scene_root = get_tree().current_scene
|
||||||
|
#var node_list: Array[Node] = [scene_root]
|
||||||
|
#return node_list + _gather_nodes_from_node(scene_root)
|
||||||
|
#
|
||||||
|
#func _gather_nodes_from_node(node: Node) -> Array[Node]:
|
||||||
|
#var nodes: Array[Node] = []
|
||||||
|
#for child in node.get_children(false):
|
||||||
|
#nodes.append(child)
|
||||||
|
#nodes += _gather_nodes_from_node(child)
|
||||||
|
#
|
||||||
|
#return nodes
|
||||||
|
|
||||||
|
func _connect_to_signal(signal_item: SignalDescription):
|
||||||
|
var root_node = get_tree().current_scene
|
||||||
|
var _execute: Callable = func (args = []): _on_signal_execution(signal_item.signal_name, signal_item.node_name, args)
|
||||||
|
if root_node.name == signal_item.node_name:
|
||||||
|
root_node.connect(signal_item.signal_name, _execute)
|
||||||
|
_lambda_map[signal_item] = _execute
|
||||||
|
else:
|
||||||
|
var child = root_node.find_child(signal_item.node_name)
|
||||||
|
if child:
|
||||||
|
child.connect(signal_item.signal_name, _execute)
|
||||||
|
_lambda_map[signal_item] = _execute
|
||||||
|
|
||||||
|
func _disconnect_from_signal(signal_item: SignalDescription):
|
||||||
|
var root_node = get_tree().current_scene
|
||||||
|
if root_node.name == signal_item.node_name:
|
||||||
|
var callable = _lambda_map[signal_item]
|
||||||
|
if callable:
|
||||||
|
root_node.disconnect(signal_item.signal_name, callable)
|
||||||
|
_lambda_map.erase(signal_item)
|
||||||
|
else:
|
||||||
|
var child = root_node.find_child(signal_item.node_name)
|
||||||
|
if child:
|
||||||
|
var callable = _lambda_map[signal_item]
|
||||||
|
if callable:
|
||||||
|
child.disconnect(signal_item.signal_name, callable)
|
||||||
|
_lambda_map.erase(signal_item)
|
97
addons/SignalVisualizer/Debugger/SignalDebugger.tscn
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
[gd_scene load_steps=5 format=3 uid="uid://cbsmvov8u78q"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/SignalVisualizer/Debugger/signal_debugger_panel.gd" id="1_66cpc"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://be3nwoioa311t" path="res://addons/SignalVisualizer/Play.svg" id="2_2wkuv"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://oo1oq2colx5b" path="res://addons/SignalVisualizer/Stop.svg" id="3_bg5eu"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bmnff63evbdhv" path="res://addons/SignalVisualizer/Clear.svg" id="4_vg63r"]
|
||||||
|
|
||||||
|
[node name="SignalDebugger" type="Control"]
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_66cpc")
|
||||||
|
start_icon = ExtResource("2_2wkuv")
|
||||||
|
stop_icon = ExtResource("3_bg5eu")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(2.08165e-12, 50)
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 8
|
||||||
|
|
||||||
|
[node name="ActionButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
disabled = true
|
||||||
|
text = "Start"
|
||||||
|
icon = ExtResource("2_2wkuv")
|
||||||
|
|
||||||
|
[node name="ClearAllButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Clear All"
|
||||||
|
icon = ExtResource("4_vg63r")
|
||||||
|
|
||||||
|
[node name="Spacer" type="Control" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="ClearLogsButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Clear Logs"
|
||||||
|
icon = ExtResource("4_vg63r")
|
||||||
|
|
||||||
|
[node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="SignalTree" type="Tree" parent="VBoxContainer/HSplitContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(250, 2.08165e-12)
|
||||||
|
layout_mode = 2
|
||||||
|
columns = 2
|
||||||
|
allow_reselect = true
|
||||||
|
allow_rmb_select = true
|
||||||
|
hide_root = true
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="TabBar" type="TabBar" parent="VBoxContainer/HSplitContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
tab_count = 2
|
||||||
|
tab_0/title = "Signal Log"
|
||||||
|
tab_1/title = "Signal Graph"
|
||||||
|
|
||||||
|
[node name="LogLabel" type="RichTextLabel" parent="VBoxContainer/HSplitContainer/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme_override_colors/default_color = Color(0.690196, 0.690196, 0.690196, 1)
|
||||||
|
bbcode_enabled = true
|
||||||
|
scroll_following = true
|
||||||
|
|
||||||
|
[node name="Graph" type="GraphEdit" parent="VBoxContainer/HSplitContainer/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ActionButton" to="." method="_on_action_button_pressed"]
|
||||||
|
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ClearAllButton" to="." method="_on_clear_all_button_pressed"]
|
||||||
|
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ClearLogsButton" to="." method="_on_clear_logs_button_pressed"]
|
||||||
|
[connection signal="item_selected" from="VBoxContainer/HSplitContainer/SignalTree" to="." method="_on_signal_tree_item_selected"]
|
||||||
|
[connection signal="tab_changed" from="VBoxContainer/HSplitContainer/VBoxContainer/TabBar" to="." method="_on_tab_bar_tab_changed"]
|
192
addons/SignalVisualizer/Debugger/signal_debugger_panel.gd
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
@tool
|
||||||
|
class_name SignalDebuggerPanel extends Control
|
||||||
|
|
||||||
|
signal open_script(node_name: String, method_signature: String)
|
||||||
|
|
||||||
|
signal start_signal_debugging
|
||||||
|
signal stop_signal_debugging
|
||||||
|
|
||||||
|
var SignalGraphNode = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node.tscn")
|
||||||
|
var GraphNodeItem = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node_item.tscn")
|
||||||
|
|
||||||
|
const SOURCE_COLOR: Color = Color.SKY_BLUE
|
||||||
|
const DESTINATION_COLOR: Color = Color.CORAL
|
||||||
|
const CONNECTION_TYPE: int = 0
|
||||||
|
|
||||||
|
enum Tabs {
|
||||||
|
LOG,
|
||||||
|
GRAPH
|
||||||
|
}
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
@export var start_icon: Texture2D
|
||||||
|
@export var stop_icon: Texture2D
|
||||||
|
|
||||||
|
@onready var action_button: Button = %ActionButton
|
||||||
|
@onready var clear_all_button: Button = %ClearAllButton
|
||||||
|
@onready var signal_tree: Tree = %SignalTree
|
||||||
|
@onready var log_label: RichTextLabel = %LogLabel
|
||||||
|
@onready var graph_node: GraphEdit = %Graph
|
||||||
|
|
||||||
|
var is_started: bool = false :
|
||||||
|
get: return is_started
|
||||||
|
set(new_value):
|
||||||
|
is_started = new_value
|
||||||
|
_update_action_button()
|
||||||
|
|
||||||
|
var _signals: Array = []
|
||||||
|
var _signal_filter: Array = []
|
||||||
|
var _is_stack_trace_enabled: bool = false
|
||||||
|
var _debugger_tab_state: Tabs = Tabs.LOG
|
||||||
|
var _graph: SignalGraph
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
disable()
|
||||||
|
_handle_tab_update(0)
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_action_button_pressed():
|
||||||
|
if is_started:
|
||||||
|
stop()
|
||||||
|
else:
|
||||||
|
start()
|
||||||
|
|
||||||
|
func _on_clear_all_button_pressed():
|
||||||
|
log_label.clear()
|
||||||
|
signal_tree.clear()
|
||||||
|
graph_node.clear_connections()
|
||||||
|
for child in graph_node.get_children():
|
||||||
|
if child is SignalGraphNode:
|
||||||
|
child.queue_free()
|
||||||
|
|
||||||
|
func _on_clear_logs_button_pressed():
|
||||||
|
log_label.clear()
|
||||||
|
|
||||||
|
func _on_signal_tree_item_selected():
|
||||||
|
# Updates the checkmark button
|
||||||
|
var selected_item = signal_tree.get_selected()
|
||||||
|
var is_checked = selected_item.is_checked(1)
|
||||||
|
selected_item.set_checked(1, (not is_checked))
|
||||||
|
|
||||||
|
# Add / Remove signal from filters
|
||||||
|
var selected_signal = _signals.filter(func (element): return element.signal_name == selected_item.get_text(0))[0]
|
||||||
|
if _signal_filter.has(selected_signal.signal_name):
|
||||||
|
var selected_index = _signal_filter.find(selected_signal.signal_name)
|
||||||
|
_signal_filter.remove_at(selected_index)
|
||||||
|
else:
|
||||||
|
_signal_filter.append(selected_signal.signal_name)
|
||||||
|
|
||||||
|
func _on_tab_bar_tab_changed(tab: int):
|
||||||
|
_handle_tab_update(tab)
|
||||||
|
|
||||||
|
func _on_stack_trace_button_pressed():
|
||||||
|
_is_stack_trace_enabled = not _is_stack_trace_enabled
|
||||||
|
|
||||||
|
func _on_open_signal_in_script(data: SignalGraphNodeItem.Metadata):
|
||||||
|
open_script.emit(data.node_name, data.method_signature)
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func enable():
|
||||||
|
action_button.disabled = false
|
||||||
|
|
||||||
|
func disable():
|
||||||
|
action_button.disabled = true
|
||||||
|
|
||||||
|
func start():
|
||||||
|
if not is_started:
|
||||||
|
is_started = true
|
||||||
|
action_button.icon = stop_icon
|
||||||
|
start_signal_debugging.emit()
|
||||||
|
log_label.append_text("[color=#B0B0B0]Signal Debugging Started...[/color]")
|
||||||
|
log_label.newline()
|
||||||
|
log_label.newline()
|
||||||
|
|
||||||
|
func stop():
|
||||||
|
if is_started:
|
||||||
|
is_started = false
|
||||||
|
action_button.icon = start_icon
|
||||||
|
stop_signal_debugging.emit()
|
||||||
|
log_label.newline()
|
||||||
|
log_label.append_text("[color=#B0B0B0]Signal Debugging Stopped[/color]")
|
||||||
|
log_label.newline()
|
||||||
|
log_label.newline()
|
||||||
|
|
||||||
|
func create_tree_from_signals(signals: Array):
|
||||||
|
_signals = signals
|
||||||
|
var root = signal_tree.create_item()
|
||||||
|
root.set_text(0, "Signals")
|
||||||
|
|
||||||
|
var tree_items: Dictionary = {}
|
||||||
|
|
||||||
|
for signal_item in signals:
|
||||||
|
var node_tree_item: TreeItem
|
||||||
|
if tree_items.has(signal_item.node_name):
|
||||||
|
node_tree_item = tree_items[signal_item.node_name] as TreeItem
|
||||||
|
else:
|
||||||
|
node_tree_item = signal_tree.create_item(root)
|
||||||
|
node_tree_item.set_text(0, signal_item.node_name)
|
||||||
|
node_tree_item.set_selectable(0, false)
|
||||||
|
node_tree_item.set_selectable(1, false)
|
||||||
|
tree_items[signal_item.node_name] = node_tree_item
|
||||||
|
|
||||||
|
var signal_tree_item = signal_tree.create_item(node_tree_item)
|
||||||
|
signal_tree_item.set_text(0, signal_item.signal_name)
|
||||||
|
signal_tree_item.set_cell_mode(1, TreeItem.CELL_MODE_CHECK)
|
||||||
|
signal_tree_item.set_checked(1, true)
|
||||||
|
signal_tree_item.set_selectable(0, false)
|
||||||
|
signal_tree_item.set_selectable(1, true)
|
||||||
|
|
||||||
|
func create_signal_graph(signals: Array, edges: Array):
|
||||||
|
_graph = SignalGraphUtility.create_signal_graph(get_tree().edited_scene_root.scene_file_path, signals, edges)
|
||||||
|
SignalGraphUtility.generate_signal_graph_nodes(_graph, graph_node, _on_open_signal_in_script)
|
||||||
|
|
||||||
|
func log_signal_execution(time: String, node_name: String, signal_name: String):
|
||||||
|
if _signal_filter != null and _signal_filter.has(signal_name):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not log_label.text.is_empty():
|
||||||
|
log_label.newline()
|
||||||
|
log_label.append_text(
|
||||||
|
"[color=#FFCC00]{time}[/color]\t\t{node_name}\t\t{signal_name}".format({ "time": time, "node_name": node_name, "signal_name": signal_name })
|
||||||
|
)
|
||||||
|
log_label.newline()
|
||||||
|
|
||||||
|
func _handle_tab_update(selected_tab_index: int):
|
||||||
|
match selected_tab_index:
|
||||||
|
1:
|
||||||
|
_debugger_tab_state = Tabs.GRAPH
|
||||||
|
_:
|
||||||
|
_debugger_tab_state = Tabs.LOG
|
||||||
|
|
||||||
|
match _debugger_tab_state:
|
||||||
|
Tabs.LOG:
|
||||||
|
log_label.show()
|
||||||
|
graph_node.hide()
|
||||||
|
Tabs.GRAPH:
|
||||||
|
log_label.hide()
|
||||||
|
graph_node.show()
|
||||||
|
|
||||||
|
func _update_action_button():
|
||||||
|
if is_started:
|
||||||
|
action_button.text = "Stop"
|
||||||
|
action_button.modulate = Color("#ff3b30")
|
||||||
|
else:
|
||||||
|
action_button.text = "Start"
|
||||||
|
action_button.modulate = Color.WHITE
|
1
addons/SignalVisualizer/GraphEdit.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="24" width="24" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M11 1a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM6.732 5A2 2 0 0 1 7 6v1.117L9.268 6A2 2 0 0 1 9 5V3.883zM2 5a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zm5 3.883V10a2 2 0 0 1-.268 1L9 12.117V11a2 2 0 0 1 .268-1zM11 10a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1z" fill="#8eef97"/></svg>
|
After Width: | Height: | Size: 437 B |
37
addons/SignalVisualizer/GraphEdit.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bxj8ep08wbnm6"
|
||||||
|
path="res://.godot/imported/GraphEdit.svg-90dae61e8e0b157ab8eff95fe4b91e53.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/SignalVisualizer/GraphEdit.svg"
|
||||||
|
dest_files=["res://.godot/imported/GraphEdit.svg-90dae61e8e0b157ab8eff95fe4b91e53.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/SignalVisualizer/Play.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="24" viewBox="0 0 16 16" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4 12a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 4 4z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 184 B |
37
addons/SignalVisualizer/Play.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://be3nwoioa311t"
|
||||||
|
path="res://.godot/imported/Play.svg-a446691ffcef211028bb160b5a2d6ff1.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/SignalVisualizer/Play.svg"
|
||||||
|
dest_files=["res://.godot/imported/Play.svg-a446691ffcef211028bb160b5a2d6ff1.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
162
addons/SignalVisualizer/SignalVisualizer.gd
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
class SignalDebuggerPlugin extends EditorDebuggerPlugin:
|
||||||
|
var SignalDebuggerPanelScene = preload("res://addons/SignalVisualizer/Debugger/SignalDebugger.tscn")
|
||||||
|
|
||||||
|
signal open_script
|
||||||
|
signal start_signal_debugging
|
||||||
|
signal stop_signal_debugging
|
||||||
|
|
||||||
|
var debugger_panel
|
||||||
|
|
||||||
|
func _has_capture(prefix) -> bool:
|
||||||
|
return prefix == "signal_debugger"
|
||||||
|
|
||||||
|
func _capture(message, data, session_id) -> bool:
|
||||||
|
if message == "signal_debugger:signal_executed":
|
||||||
|
if data.size() == 3:
|
||||||
|
var time = data[0]
|
||||||
|
var node_name = data[1]
|
||||||
|
var signal_name = data[2]
|
||||||
|
debugger_panel.log_signal_execution(time, node_name, signal_name)
|
||||||
|
return true
|
||||||
|
|
||||||
|
if message == "signal_debugger:generated_graph":
|
||||||
|
if data.size() == 1:
|
||||||
|
var signals = data[0][0] as Array
|
||||||
|
var edges = data[0][1] as Array
|
||||||
|
debugger_panel.create_tree_from_signals(signals)
|
||||||
|
debugger_panel.create_signal_graph(signals, edges)
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
func _setup_session(session_id):
|
||||||
|
debugger_panel = SignalDebuggerPanelScene.instantiate()
|
||||||
|
var session = get_session(session_id)
|
||||||
|
|
||||||
|
debugger_panel.name = "Signal Debugger"
|
||||||
|
debugger_panel.open_script.connect(func (arg1, arg2): open_script.emit(arg1, arg2))
|
||||||
|
debugger_panel.start_signal_debugging.connect(func (): start_signal_debugging.emit())
|
||||||
|
debugger_panel.stop_signal_debugging.connect(func (): stop_signal_debugging.emit())
|
||||||
|
|
||||||
|
session.started.connect(
|
||||||
|
func ():
|
||||||
|
debugger_panel.enable()
|
||||||
|
)
|
||||||
|
session.stopped.connect(
|
||||||
|
func ():
|
||||||
|
debugger_panel.stop()
|
||||||
|
debugger_panel.disable()
|
||||||
|
stop_signal_debugging.emit()
|
||||||
|
)
|
||||||
|
|
||||||
|
session.add_session_tab(debugger_panel)
|
||||||
|
|
||||||
|
var SignalVisualizerDockScene = preload("res://addons/SignalVisualizer/Visualizer/signal_visualizer_dock.tscn")
|
||||||
|
|
||||||
|
class ScriptMethodReference:
|
||||||
|
var script_reference: Script
|
||||||
|
var line_number: int
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var dock: Control
|
||||||
|
var debugger: SignalDebuggerPlugin
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
dock = SignalVisualizerDockScene.instantiate()
|
||||||
|
debugger = SignalDebuggerPlugin.new()
|
||||||
|
|
||||||
|
dock.open_script.connect(_on_open_signal_in_script)
|
||||||
|
add_control_to_bottom_panel(dock, "Signal Visualizer")
|
||||||
|
|
||||||
|
debugger.start_signal_debugging.connect(_on_debugger_start_signal_debugging)
|
||||||
|
debugger.stop_signal_debugging.connect(_on_debugger_stop_signal_debugging)
|
||||||
|
debugger.open_script.connect(_on_open_signal_in_script)
|
||||||
|
add_debugger_plugin(debugger)
|
||||||
|
|
||||||
|
if not ProjectSettings.has_setting("autoload/Signal_Debugger"):
|
||||||
|
add_autoload_singleton("Signal_Debugger", "res://addons/SignalVisualizer/Debugger/SignalDebugger.gd")
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
remove_control_from_bottom_panel(dock)
|
||||||
|
dock.free()
|
||||||
|
|
||||||
|
remove_debugger_plugin(debugger)
|
||||||
|
remove_autoload_singleton("Signal_Debugger")
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_open_signal_in_script(node_name: String, method_signature: String):
|
||||||
|
var node: Node
|
||||||
|
if get_tree().edited_scene_root.name == node_name:
|
||||||
|
node = get_tree().edited_scene_root
|
||||||
|
else:
|
||||||
|
node = get_tree().edited_scene_root.find_child(node_name)
|
||||||
|
|
||||||
|
if node != null:
|
||||||
|
var script: Script = node.get_script()
|
||||||
|
if script != null:
|
||||||
|
var editor = get_editor_interface()
|
||||||
|
var method_reference = _find_method_reference_in_script(script, method_signature)
|
||||||
|
|
||||||
|
if method_reference != null:
|
||||||
|
editor.edit_script(method_reference.script_reference, method_reference.line_number, 0)
|
||||||
|
editor.set_main_screen_editor("Script")
|
||||||
|
else:
|
||||||
|
push_warning("Requested method in script ({script}) for node ({name}) is not available.".format({ "name": node_name, "script": script.name }))
|
||||||
|
else:
|
||||||
|
push_warning("Requested script for node ({name}) is not available.".format({ "name": node_name }))
|
||||||
|
else:
|
||||||
|
push_warning("Requested script for node ({name}) is not available.".format({ "name": node_name }))
|
||||||
|
|
||||||
|
func _on_debugger_start_signal_debugging():
|
||||||
|
for session in debugger.get_sessions():
|
||||||
|
session.send_message("signal_debugger:start", [])
|
||||||
|
|
||||||
|
func _on_debugger_stop_signal_debugging():
|
||||||
|
for session in debugger.get_sessions():
|
||||||
|
session.send_message("signal_debugger:stop", [])
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _find_method_reference_in_script(script: Script, method_signature: String) -> ScriptMethodReference:
|
||||||
|
var line_number = __find_method_line_number_in_script(script, method_signature)
|
||||||
|
|
||||||
|
if line_number == -1:
|
||||||
|
var base_script = script.get_base_script()
|
||||||
|
if base_script:
|
||||||
|
return _find_method_reference_in_script(base_script, method_signature)
|
||||||
|
|
||||||
|
var reference = ScriptMethodReference.new()
|
||||||
|
reference.script_reference = script
|
||||||
|
reference.line_number = line_number
|
||||||
|
|
||||||
|
return reference
|
||||||
|
|
||||||
|
func __find_method_line_number_in_script(script: Script, method_signature: String) -> int:
|
||||||
|
var line_number = 0
|
||||||
|
var found = false
|
||||||
|
for line in script.source_code.split("\n", true):
|
||||||
|
line_number += 1
|
||||||
|
if line.contains(method_signature):
|
||||||
|
found = true
|
||||||
|
return line_number
|
||||||
|
|
||||||
|
return -1
|
1
addons/SignalVisualizer/Stop.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="24" viewBox="0 0 16 16" width="24" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="3" height="10" width="10" rx="1" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 154 B |
37
addons/SignalVisualizer/Stop.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://oo1oq2colx5b"
|
||||||
|
path="res://.godot/imported/Stop.svg-e085086fb31c334bc2f02ca2bffba522.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/SignalVisualizer/Stop.svg"
|
||||||
|
dest_files=["res://.godot/imported/Stop.svg-e085086fb31c334bc2f02ca2bffba522.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
31
addons/SignalVisualizer/Visualizer/resizable_label.gd
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
@tool
|
||||||
|
extends Label
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func get_text_size() -> Vector2:
|
||||||
|
return get_theme_default_font().get_string_size(text)
|
94
addons/SignalVisualizer/Visualizer/signal_graph_node.gd
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
@tool
|
||||||
|
class_name SignalGraphNode extends GraphNode
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
var connections: Array = [] :
|
||||||
|
get: return connections
|
||||||
|
set(new_value):
|
||||||
|
connections = new_value
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
selectable = true
|
||||||
|
resizable = true
|
||||||
|
draggable = true
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_resize_request(new_minsize):
|
||||||
|
size = new_minsize
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func has_source_signal_description(signal_name: String, destination_node_name: String) -> bool:
|
||||||
|
for child in get_children():
|
||||||
|
if child.name == "source_" + signal_name + "_" + destination_node_name:
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
func get_source_slot(signal_name: String, destination_node_name: String) -> int:
|
||||||
|
var index = 0
|
||||||
|
for child in get_children():
|
||||||
|
if child.name == "source_" + signal_name + "_" + destination_node_name:
|
||||||
|
return index
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
func get_next_source_slot(signal_name: String, destination_node_name: String) -> int:
|
||||||
|
var index = 0
|
||||||
|
for child in get_children():
|
||||||
|
if child.name.begins_with("source_"):
|
||||||
|
if child.name == "source_" + signal_name + "_" + destination_node_name:
|
||||||
|
return index
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
func has_destination_signal_description(signal_name: String, method_signature: String) -> bool:
|
||||||
|
for child in get_children():
|
||||||
|
if child.name == "destination_" + signal_name + "_" + _sanitize_method_signature(method_signature):
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
func get_destination_slot(signal_name: String, method_signature: String) -> int:
|
||||||
|
var index = 0
|
||||||
|
for child in get_children():
|
||||||
|
if child.name == "destination_" + signal_name + "_" + _sanitize_method_signature(method_signature):
|
||||||
|
return index
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
func get_next_destination_slot(signal_name: String, method_signature: String) -> int:
|
||||||
|
var index = 0
|
||||||
|
for child in get_children():
|
||||||
|
if child.name.begins_with("destination_"):
|
||||||
|
if child.name == "destination_" + signal_name + "_" + _sanitize_method_signature(method_signature):
|
||||||
|
return index
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
func _sanitize_method_signature(signature: String) -> String:
|
||||||
|
return signature.replace("::", "__")
|
12
addons/SignalVisualizer/Visualizer/signal_graph_node.tscn
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://cq10iaub18e54"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/SignalVisualizer/Visualizer/signal_graph_node.gd" id="1_ovklj"]
|
||||||
|
|
||||||
|
[node name="SignalGraphNode" type="GraphNode"]
|
||||||
|
custom_minimum_size = Vector2(100, 50)
|
||||||
|
offset_right = 232.0
|
||||||
|
offset_bottom = 54.0
|
||||||
|
resizable = true
|
||||||
|
script = ExtResource("1_ovklj")
|
||||||
|
|
||||||
|
[connection signal="resize_request" from="." to="." method="_on_resize_request"]
|
57
addons/SignalVisualizer/Visualizer/signal_graph_node_item.gd
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
@tool
|
||||||
|
class_name SignalGraphNodeItem extends Control
|
||||||
|
|
||||||
|
signal open_script(metadata: SignalGraphNodeItem.Metadata)
|
||||||
|
|
||||||
|
class Metadata:
|
||||||
|
var signal_name: String
|
||||||
|
var method_signature: String
|
||||||
|
var node_name: String
|
||||||
|
|
||||||
|
func _init(signal_name: String, method_signature: String, node_name: String):
|
||||||
|
self.signal_name = signal_name
|
||||||
|
self.method_signature = method_signature
|
||||||
|
self.node_name = node_name
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
@onready var label: Label = %DescriptionLabel
|
||||||
|
|
||||||
|
var signal_data: Metadata = null
|
||||||
|
|
||||||
|
var text: String = "" :
|
||||||
|
get: return text
|
||||||
|
set(new_value):
|
||||||
|
text = new_value
|
||||||
|
if label:
|
||||||
|
label.text = text
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
_update()
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_open_signal_in_script_button_pressed():
|
||||||
|
open_script.emit(signal_data)
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _update():
|
||||||
|
label.text = text
|
||||||
|
|
||||||
|
var text_size = label.get_text_size()
|
||||||
|
custom_minimum_size = Vector2((text_size.x * 2) + 50, text_size.y * 3)
|
|
@ -0,0 +1,43 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://b2lwtwp6kpwtb"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/SignalVisualizer/Visualizer/signal_graph_node_item.gd" id="1_jrd34"]
|
||||||
|
[ext_resource type="Script" path="res://addons/SignalVisualizer/Visualizer/resizable_label.gd" id="2_4wwd5"]
|
||||||
|
|
||||||
|
[node name="SignalItem" type="Control"]
|
||||||
|
clip_contents = true
|
||||||
|
custom_minimum_size = Vector2(51, 23)
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
script = ExtResource("1_jrd34")
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||||
|
custom_minimum_size = Vector2(100, 50)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="DescriptionLabel" type="Label" parent="HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(100, 50)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
clip_text = true
|
||||||
|
script = ExtResource("2_4wwd5")
|
||||||
|
|
||||||
|
[node name="OpenSignalInScriptButton" type="Button" parent="HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Open"
|
||||||
|
flat = true
|
||||||
|
|
||||||
|
[connection signal="pressed" from="HBoxContainer/OpenSignalInScriptButton" to="." method="_on_open_signal_in_script_button_pressed"]
|
67
addons/SignalVisualizer/Visualizer/signal_visualizer_dock.gd
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
@tool
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
signal open_script(node_name: String, method_signature: String)
|
||||||
|
|
||||||
|
var SignalGraphNode = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node.tscn")
|
||||||
|
var GraphNodeItem = preload("res://addons/SignalVisualizer/Visualizer/signal_graph_node_item.tscn")
|
||||||
|
|
||||||
|
# Properties
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
const SOURCE_COLOR: Color = Color.SKY_BLUE
|
||||||
|
const DESTINATION_COLOR: Color = Color.CORAL
|
||||||
|
const CONNECTION_TYPE: int = 0
|
||||||
|
|
||||||
|
@onready var arrange_nodes_checkbox: CheckBox = %ArrangeNodesCheckBox
|
||||||
|
@onready var signal_details_checkbox: CheckBox = %SignalDetailsCheckBox
|
||||||
|
@onready var signal_tree: Tree = %SignalTree
|
||||||
|
@onready var graph: GraphEdit = %Graph
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func _on_clear_graph_button_pressed():
|
||||||
|
clear()
|
||||||
|
|
||||||
|
func _on_generate_graph_button_pressed():
|
||||||
|
clear()
|
||||||
|
|
||||||
|
var scene_signal_graph = SignalGraphUtility.create_signal_graph_from_node(get_tree().edited_scene_root, true)
|
||||||
|
SignalGraphUtility.generate_signal_graph_nodes(scene_signal_graph, graph, _on_open_signal_in_script)
|
||||||
|
SignalGraphUtility.generate_signal_graph_tree(scene_signal_graph, signal_tree)
|
||||||
|
|
||||||
|
if arrange_nodes_checkbox.button_pressed:
|
||||||
|
graph.arrange_nodes()
|
||||||
|
|
||||||
|
func _on_open_signal_in_script(data: SignalGraphNodeItem.Metadata):
|
||||||
|
open_script.emit(data.node_name, data.method_signature)
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
# |===================================|
|
||||||
|
|
||||||
|
func clear():
|
||||||
|
_clear_graph_nodes()
|
||||||
|
_clear_tree()
|
||||||
|
|
||||||
|
func _clear_graph_nodes():
|
||||||
|
graph.clear_connections()
|
||||||
|
for child in graph.get_children():
|
||||||
|
if child is SignalGraphNode:
|
||||||
|
child.queue_free()
|
||||||
|
|
||||||
|
func _clear_tree():
|
||||||
|
signal_tree.clear()
|
|
@ -0,0 +1,78 @@
|
||||||
|
[gd_scene load_steps=5 format=3 uid="uid://dppfamjc0ji40"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/SignalVisualizer/Visualizer/signal_visualizer_dock.gd" id="1_akar5"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bmnff63evbdhv" path="res://addons/SignalVisualizer/Clear.svg" id="2_m8bsv"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bxj8ep08wbnm6" path="res://addons/SignalVisualizer/GraphEdit.svg" id="3_dtmqs"]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ae0jg"]
|
||||||
|
|
||||||
|
[node name="SignalVisualizerDock" type="Control"]
|
||||||
|
clip_contents = true
|
||||||
|
custom_minimum_size = Vector2(2.08165e-12, 200)
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_akar5")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
clip_contents = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||||
|
clip_contents = true
|
||||||
|
custom_minimum_size = Vector2(2.08165e-12, 50)
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 8
|
||||||
|
alignment = 2
|
||||||
|
|
||||||
|
[node name="ArrangeNodesCheckBox" type="CheckBox" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Arrange Nodes"
|
||||||
|
|
||||||
|
[node name="SignalDetailsCheckBox" type="CheckBox" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Signal Details"
|
||||||
|
|
||||||
|
[node name="Panel" type="Panel" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_styles/panel = SubResource("StyleBoxEmpty_ae0jg")
|
||||||
|
|
||||||
|
[node name="ClearGraphButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Clear Graph"
|
||||||
|
icon = ExtResource("2_m8bsv")
|
||||||
|
|
||||||
|
[node name="GenerateGraphButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Generate Graph"
|
||||||
|
icon = ExtResource("3_dtmqs")
|
||||||
|
|
||||||
|
[node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="SignalTree" type="Tree" parent="VBoxContainer/HSplitContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(200, 2.08165e-12)
|
||||||
|
layout_mode = 2
|
||||||
|
column_titles_visible = true
|
||||||
|
|
||||||
|
[node name="Graph" type="GraphEdit" parent="VBoxContainer/HSplitContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[connection signal="pressed" from="VBoxContainer/HBoxContainer/ClearGraphButton" to="." method="_on_clear_graph_button_pressed"]
|
||||||
|
[connection signal="pressed" from="VBoxContainer/HBoxContainer/GenerateGraphButton" to="." method="_on_generate_graph_button_pressed"]
|
7
addons/SignalVisualizer/plugin.cfg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="SignalVisualizer"
|
||||||
|
description="Visual the current scene's signal connections as a graph. Debug the current running scene's signals with automatic logging in a new debugger panel."
|
||||||
|
author="MiniGameDev"
|
||||||
|
version="1.7.0"
|
||||||
|
script="SignalVisualizer.gd"
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 559 B |
BIN
assets/GUI/buttons fucused/back button f.png
Normal file
After Width: | Height: | Size: 563 B |
34
assets/GUI/buttons fucused/back button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://fon35dtl2fdd"
|
||||||
|
path="res://.godot/imported/back button f.png-efb6ddf8f429550b2341f025ce20dd5a.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/back button f.png"
|
||||||
|
dest_files=["res://.godot/imported/back button f.png-efb6ddf8f429550b2341f025ce20dd5a.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/note button f.png
Normal file
After Width: | Height: | Size: 587 B |
34
assets/GUI/buttons fucused/note button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c8um1xy8sixhb"
|
||||||
|
path="res://.godot/imported/note button f.png-1397d916f56d1ff7f08e313d3b74bff7.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/note button f.png"
|
||||||
|
dest_files=["res://.godot/imported/note button f.png-1397d916f56d1ff7f08e313d3b74bff7.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/restart button f.png
Normal file
After Width: | Height: | Size: 574 B |
34
assets/GUI/buttons fucused/restart button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bj06y06uq303j"
|
||||||
|
path="res://.godot/imported/restart button f.png-4b164de13f5dd59ea9c0197ef4d4bfda.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/restart button f.png"
|
||||||
|
dest_files=["res://.godot/imported/restart button f.png-4b164de13f5dd59ea9c0197ef4d4bfda.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/settings button f.png
Normal file
After Width: | Height: | Size: 568 B |
34
assets/GUI/buttons fucused/settings button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c66oktmsmdu0f"
|
||||||
|
path="res://.godot/imported/settings button f.png-2be0c78f63190ae3eba8fa51c122327b.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/settings button f.png"
|
||||||
|
dest_files=["res://.godot/imported/settings button f.png-2be0c78f63190ae3eba8fa51c122327b.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/sound button f.png
Normal file
After Width: | Height: | Size: 600 B |
34
assets/GUI/buttons fucused/sound button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://botwq4rflsfl3"
|
||||||
|
path="res://.godot/imported/sound button f.png-93410106fda92fcdc0d46920cf415401.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/sound button f.png"
|
||||||
|
dest_files=["res://.godot/imported/sound button f.png-93410106fda92fcdc0d46920cf415401.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/sound button off f.png
Normal file
After Width: | Height: | Size: 607 B |
34
assets/GUI/buttons fucused/sound button off f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dui5dacb5lpfg"
|
||||||
|
path="res://.godot/imported/sound button off f.png-3945d9207f642dfe8529e5786a9b11c3.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/sound button off f.png"
|
||||||
|
dest_files=["res://.godot/imported/sound button off f.png-3945d9207f642dfe8529e5786a9b11c3.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/buttons fucused/start button f.png
Normal file
After Width: | Height: | Size: 559 B |
34
assets/GUI/buttons fucused/start button f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://2mq6ck123lm"
|
||||||
|
path="res://.godot/imported/start button f.png-4d7107cb861657e999ab17db80bfd0d5.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/buttons fucused/start button f.png"
|
||||||
|
dest_files=["res://.godot/imported/start button f.png-4d7107cb861657e999ab17db80bfd0d5.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
34
assets/GUI/note button.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b4k3dsaoft0uf"
|
||||||
|
path="res://.godot/imported/note button.png-d01ea21981304add54e4d620f6e0137c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/note button.png"
|
||||||
|
dest_files=["res://.godot/imported/note button.png-d01ea21981304add54e4d620f6e0137c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/GUI/sound button off.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
34
assets/GUI/sound button off.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d0s1arwpmlxot"
|
||||||
|
path="res://.godot/imported/sound button off.png-364c5b9e9d325567ac89e0662c159ee6.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/sound button off.png"
|
||||||
|
dest_files=["res://.godot/imported/sound button off.png-364c5b9e9d325567ac89e0662c159ee6.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.3 KiB |
34
assets/GUI/sound button.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://46wo0ufacs5d"
|
||||||
|
path="res://.godot/imported/sound button.png-cbd8cb8ff7b0b3140245c51cf2746007.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/sound button.png"
|
||||||
|
dest_files=["res://.godot/imported/sound button.png-cbd8cb8ff7b0b3140245c51cf2746007.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 553 B |
BIN
assets/GUI/theme_slider/slider f.png
Normal file
After Width: | Height: | Size: 548 B |
34
assets/GUI/theme_slider/slider f.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bkcpp1iryq4hc"
|
||||||
|
path="res://.godot/imported/slider f.png-3d54eedc4180582468b166aaeccf5dd6.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/GUI/theme_slider/slider f.png"
|
||||||
|
dest_files=["res://.godot/imported/slider f.png-3d54eedc4180582468b166aaeccf5dd6.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/f.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://bmklwmjrtynqo"
|
uid="uid://bkvncdu12do8h"
|
||||||
path="res://.godot/imported/ground.png-673271eeeb2d2777787f0fa18dd4ce4d.ctex"
|
path="res://.godot/imported/f.png-0bb357aaad3f190d3595a1032c921bfe.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/Ground/ground.png"
|
source_file="res://assets/Ground/f.png"
|
||||||
dest_files=["res://.godot/imported/ground.png-673271eeeb2d2777787f0fa18dd4ce4d.ctex"]
|
dest_files=["res://.godot/imported/f.png-0bb357aaad3f190d3595a1032c921bfe.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
Before Width: | Height: | Size: 5.8 KiB |
BIN
assets/Ground/n.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://bg78j6xxw3ck4"
|
uid="uid://bg78j6xxw3ck4"
|
||||||
path="res://.godot/imported/background.png-b4e7437f07894e7f253b684ff783fbd2.ctex"
|
path="res://.godot/imported/n.png-e0925980109603d0618d5083d12d13a4.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/Ground/background.png"
|
source_file="res://assets/Ground/n.png"
|
||||||
dest_files=["res://.godot/imported/background.png-b4e7437f07894e7f253b684ff783fbd2.ctex"]
|
dest_files=["res://.godot/imported/n.png-e0925980109603d0618d5083d12d13a4.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
BIN
assets/Ground/s.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
34
assets/Ground/s.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://h5lmps4jxju7"
|
||||||
|
path="res://.godot/imported/s.png-0af6d1fd4a1289066043e7b0864be0eb.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/s.png"
|
||||||
|
dest_files=["res://.godot/imported/s.png-0af6d1fd4a1289066043e7b0864be0eb.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/transisions/n_s.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
34
assets/Ground/transisions/n_s.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d3fy8kykhgook"
|
||||||
|
path="res://.godot/imported/n_s.png-cfcc7a58229e689440ae0dbfa52dc24b.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/transisions/n_s.png"
|
||||||
|
dest_files=["res://.godot/imported/n_s.png-cfcc7a58229e689440ae0dbfa52dc24b.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/transisions/n_w.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
34
assets/Ground/transisions/n_w.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cthy542lxhe5q"
|
||||||
|
path="res://.godot/imported/n_w.png-6b82a1e9d4c66f03fbccb2ea5d832613.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/transisions/n_w.png"
|
||||||
|
dest_files=["res://.godot/imported/n_w.png-6b82a1e9d4c66f03fbccb2ea5d832613.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/transisions/s_n.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
34
assets/Ground/transisions/s_n.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c8g0plv3864sx"
|
||||||
|
path="res://.godot/imported/s_n.png-c020b7ec12c669893cb80100a77473ac.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/transisions/s_n.png"
|
||||||
|
dest_files=["res://.godot/imported/s_n.png-c020b7ec12c669893cb80100a77473ac.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/transisions/w_n.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
34
assets/Ground/transisions/w_n.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bvel70kpfhdyx"
|
||||||
|
path="res://.godot/imported/w_n.png-c6ed57fb0761144dfd54fa145c0d35bb.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/transisions/w_n.png"
|
||||||
|
dest_files=["res://.godot/imported/w_n.png-c6ed57fb0761144dfd54fa145c0d35bb.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/Ground/w.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
34
assets/Ground/w.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bc586lwyvhc0x"
|
||||||
|
path="res://.godot/imported/w.png-eaecb02b75e3caf6be524da31509ca22.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Ground/w.png"
|
||||||
|
dest_files=["res://.godot/imported/w.png-eaecb02b75e3caf6be524da31509ca22.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
assets/audio/boing.mp3
Normal file
19
assets/audio/boing.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://ctt1kb2a66yyl"
|
||||||
|
path="res://.godot/imported/boing.mp3-0ccc2756ef81d14bc70acee782300198.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/audio/boing.mp3"
|
||||||
|
dest_files=["res://.godot/imported/boing.mp3-0ccc2756ef81d14bc70acee782300198.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
BIN
assets/audio/duckrun.mmpz
Normal file
BIN
assets/audio/duckrun.wav
Normal file
24
assets/audio/duckrun.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://c4wrtvywao1jn"
|
||||||
|
path="res://.godot/imported/duckrun.wav-242d7e6ae3c6a4a64a5d4361cd433eb4.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/audio/duckrun.wav"
|
||||||
|
dest_files=["res://.godot/imported/duckrun.wav-242d7e6ae3c6a4a64a5d4361cd433eb4.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=3
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
assets/audio/gui-in.ogg
Normal file
19
assets/audio/gui-in.ogg.import
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://drriw1cka4m3"
|
||||||
|
path="res://.godot/imported/gui-in.ogg-3746c6187b4c48f5c80251061dd72a42.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/audio/gui-in.ogg"
|
||||||
|
dest_files=["res://.godot/imported/gui-in.ogg-3746c6187b4c48f5c80251061dd72a42.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
BIN
assets/audio/gui-out.ogg
Normal file
19
assets/audio/gui-out.ogg.import
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://bktthpfrs0118"
|
||||||
|
path="res://.godot/imported/gui-out.ogg-33345eaf52b5afe61dac5bccb8beabb8.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/audio/gui-out.ogg"
|
||||||
|
dest_files=["res://.godot/imported/gui-out.ogg-33345eaf52b5afe61dac5bccb8beabb8.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://dgfvf2ta4lc4e"
|
uid="uid://dgfvf2ta4lc4e"
|
||||||
path="res://.godot/imported/stars.png-57bc8dc47b79b5d04d53ace720164aae.ctex"
|
path="res://.godot/imported/stars.png-0cec3e64e602a6d2ff05e29e04abb435.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/Ground/stars.png"
|
source_file="res://assets/stars.png"
|
||||||
dest_files=["res://.godot/imported/stars.png-57bc8dc47b79b5d04d53ace720164aae.ctex"]
|
dest_files=["res://.godot/imported/stars.png-0cec3e64e602a6d2ff05e29e04abb435.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
4
code/GUI/gui.gd
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
show()
|
|
@ -1,24 +1,23 @@
|
||||||
extends TextureRect
|
extends TextureRect
|
||||||
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
#global_position.y = -80
|
$AnimationPlayer.play_backwards("out-in")
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
pass
|
|
||||||
#global_position.x = get_viewport().get_visible_rect().size.x * 0.5
|
|
||||||
|
|
||||||
func _on_duck_gameover() -> void:
|
func _on_duck_gameover() -> void:
|
||||||
$AnimationPlayer.play_backwards("out-in")
|
$AnimationPlayer.pop_in()
|
||||||
show()
|
$"../../Audio/GameOver".play()
|
||||||
|
$Restart.grab_focus()
|
||||||
|
print($"/root/Global".hiscore)
|
||||||
|
if %ScoreContainer.get_score() > $"/root/Global".hiscore:
|
||||||
|
$"/root/Global".write_save()
|
||||||
|
|
||||||
func _on_restart_pressed() -> void:
|
func _on_restart_pressed() -> void:
|
||||||
$"../..".start_game()
|
$"../..".start_game()
|
||||||
$AnimationPlayer.play("out-in")
|
$AnimationPlayer.pop_out()
|
||||||
await $AnimationPlayer.animation_finished
|
|
||||||
hide()
|
|
||||||
|
|
||||||
|
|
||||||
|
func _on_back_pressed() -> void:
|
||||||
|
$"/root/Global".reset_game()
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
extends TextureRect
|
extends TextureRect
|
||||||
|
|
||||||
|
var audio_bus_music = 1
|
||||||
|
var audio_bus_sounds = 2
|
||||||
|
var sound_button_on_of = {true:preload("res://assets/GUI/sound button.png"),false:preload("res://assets/GUI/sound button off.png")}
|
||||||
|
var sound_button_on_of_f = {true:preload("res://assets/GUI/buttons fucused/sound button f.png"),false:preload("res://assets/GUI/buttons fucused/sound button off f.png")}
|
||||||
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
#$"../../Audio/Duckrun".volume_db = linear_to_db(20*0.01)
|
||||||
$AnimationPlayer.play_backwards("out-in")
|
$AnimationPlayer.play_backwards("out-in")
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
|
@ -11,11 +16,18 @@ func _process(_delta: float) -> void:
|
||||||
#$Logo.global_position.x = 0
|
#$Logo.global_position.x = 0
|
||||||
|
|
||||||
func open():
|
func open():
|
||||||
show()
|
$AnimationPlayer.pop_in()
|
||||||
$AnimationPlayer.play_backwards("out-in")
|
$BackButton.grab_focus()
|
||||||
|
|
||||||
func _on_back_pressed() -> void:
|
func _on_back_pressed() -> void:
|
||||||
$AnimationPlayer.play("out-in")
|
$AnimationPlayer.pop_out()
|
||||||
await $AnimationPlayer.animation_finished
|
|
||||||
hide()
|
|
||||||
$"../StartSchild"._ready()
|
$"../StartSchild"._ready()
|
||||||
|
|
||||||
|
func _volume_slider_changed(value: float) -> void:
|
||||||
|
AudioServer.set_bus_volume_db(audio_bus_music,linear_to_db(value*0.01))
|
||||||
|
|
||||||
|
|
||||||
|
func _on_sound_button_toggled(_toggled_on: bool) -> void:
|
||||||
|
$SoundToggleButton.texture_normal = sound_button_on_of[AudioServer.is_bus_mute(audio_bus_sounds)]
|
||||||
|
$SoundToggleButton.texture_focused = sound_button_on_of_f[AudioServer.is_bus_mute(audio_bus_sounds)]
|
||||||
|
AudioServer.set_bus_mute(audio_bus_sounds,not AudioServer.is_bus_mute(audio_bus_sounds))
|
||||||
|
|
|
@ -1,25 +1,21 @@
|
||||||
extends TextureRect
|
extends TextureRect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
$AnimationPlayer.play_backwards("out-in")
|
$"../StartSchildLogo/AnimationPlayer".pop_in()
|
||||||
show()
|
$AnimationPlayer.pop_in()
|
||||||
|
$Start.grab_focus()
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
global_position.x = get_viewport().get_visible_rect().size.x -100
|
|
||||||
$Logo.global_position.x = 0
|
|
||||||
|
|
||||||
|
|
||||||
func _on_start_pressed() -> void:
|
func _on_start_pressed() -> void:
|
||||||
|
$AnimationPlayer.pop_out()
|
||||||
|
$"../StartSchildLogo/AnimationPlayer".pop_out()
|
||||||
$"../..".start_game()
|
$"../..".start_game()
|
||||||
$AnimationPlayer.play("out-in")
|
|
||||||
await $AnimationPlayer.animation_finished
|
|
||||||
hide()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_pressed() -> void:
|
func _on_settings_pressed() -> void:
|
||||||
$AnimationPlayer.play("out-in")
|
$"../StartSchildLogo/AnimationPlayer".pop_out()
|
||||||
await $AnimationPlayer.animation_finished
|
$AnimationPlayer.pop_out()
|
||||||
hide()
|
|
||||||
$"../Settings".open()
|
$"../Settings".open()
|
||||||
|
|
4
code/first_save.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"hiscore":0,
|
||||||
|
"coins":0
|
||||||
|
}
|
|
@ -4,7 +4,61 @@ extends Node
|
||||||
signal levelup
|
signal levelup
|
||||||
signal start
|
signal start
|
||||||
|
|
||||||
|
|
||||||
var maxspeed = 260
|
var maxspeed = 260
|
||||||
var speed = 100
|
var speed = 100
|
||||||
var score = 0
|
var score = 0
|
||||||
|
var active_biom
|
||||||
var gamerunning = false
|
var gamerunning = false
|
||||||
|
|
||||||
|
|
||||||
|
var hiscore:int
|
||||||
|
var coins:int
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var save = load_save()
|
||||||
|
hiscore = save["hiscore"]
|
||||||
|
coins = save["hiscore"]
|
||||||
|
|
||||||
|
func reset_game():
|
||||||
|
speed = 100
|
||||||
|
score = 0
|
||||||
|
active_biom = "n"
|
||||||
|
gamerunning = false
|
||||||
|
_ready()
|
||||||
|
get_tree().reload_current_scene()
|
||||||
|
|
||||||
|
|
||||||
|
var data : FileAccess
|
||||||
|
|
||||||
|
func load_save() -> Dictionary:
|
||||||
|
# wenn kein save vorhanden ist, erstelle eins
|
||||||
|
if (not FileAccess.file_exists("user://save.json")) or (FileAccess.open("user://save.json", FileAccess.READ_WRITE).get_as_text() == ""):
|
||||||
|
init_save()
|
||||||
|
|
||||||
|
data = FileAccess.open("user://save.json", FileAccess.READ)
|
||||||
|
var content_text: Dictionary = JSON.parse_string(data.get_as_text())
|
||||||
|
|
||||||
|
if content_text:
|
||||||
|
print("loaded: ",content_text)
|
||||||
|
return content_text
|
||||||
|
else:
|
||||||
|
print("Failed to parse JSON")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
func write_save():
|
||||||
|
var sdata : FileAccess
|
||||||
|
sdata = FileAccess.open("user://save.json",FileAccess.WRITE)
|
||||||
|
var content = JSON.stringify(
|
||||||
|
{
|
||||||
|
"hiscore":$/root/Game/Gui/ScoreContainer.get_score()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print("saved: ",content)
|
||||||
|
sdata.store_string(content)
|
||||||
|
|
||||||
|
func init_save():
|
||||||
|
data = FileAccess.open("user://save.json", FileAccess.WRITE)
|
||||||
|
data.store_string(FileAccess.open("res://code/first_save.json", FileAccess.READ).get_as_text())
|
||||||
|
data.close()
|
||||||
|
|
5
code/hiscore.gd
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
extends Label
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
text = str($"/root/Global".hiscore)
|