Skip to content

Commit

Permalink
First init
Browse files Browse the repository at this point in the history
  • Loading branch information
EiTaNBaRiBoA committed Jun 22, 2024
1 parent 88bb232 commit fa19fc7
Show file tree
Hide file tree
Showing 12 changed files with 421 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
97 changes: 95 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,95 @@
# SearchByNode
A godot tool that provides a convenient way to find nodes in your scene tree by type, visibility, (including within sub-viewports or specific parent nodes)
## SearchByNode 🔍

This Godot tool provides a simple and efficient way to search and retrieve nodes within your scene tree (including within sub-viewports or specific parent nodes) based on their type and visibility. It's particularly useful for finding specific nodes without manually traversing the hierarchy.

### Features

- Find a single node by type (e.g., `Control`, `Node2D`, custom class).
- Find all nodes of a specific type.
- Option to search for active (visible) nodes only.
- Ability to limit the search to a specific sub-viewport.
- Find nodes within a specific parent node.

### Installation

1. **Download/Clone the GitHub repo:** Get the `SearchByNode.gd` script from the repository.
2. **Enable Autoload:**
- In your Godot project, go to **Project -> Project Settings -> AutoLoad**.
- Click "Add" and select the `SearchByNode.gd` script.
- Give it a name (e.g., "SearchByNode") in the AutoLoad settings.
3. **Use `SearchByNode` in your scripts:** Now you can access the `SearchByNode` functions directly in any of your project's scripts.

### Usage

#### Finding Nodes

```gdscript
# Find the first active node of type ClassB
var objB_one : ClassB = SearchByNode.findNodeByType(ClassB)
if objB_one:
print(objB_one.nameObj)
# Find all active nodes of type ClassA
var classA_array : Array[ClassA]
classA_array.assign(SearchByNode.findNodesByType(ClassA))
for objA_all : ClassA in classA_array:
print(objA_all.nameObj)
# Find the first active ClassA node within 'self' node
var objA_innerOne : ClassA = SearchByNode.findInnerNodeInNode(ClassA,self)
if objA_innerOne:
print(objA_innerOne.nameObj)
# Find all active ClassA nodes within 'self' node
var innerClassA_array : Array[ClassA]
innerClassA_array.assign(SearchByNode.findInnerNodesInNode(ClassA,self))
for objA_inner_all : ClassA in innerClassA_array:
print(objA_inner_all.nameObj)
```

#### Finding the Main Scene of a Viewport

```gdscript
# Get the main scene of the viewport that 'self' belongs to
var main_scene = SearchByNode.get_main_scene_of_viewport(self)
print(main_scene.name)
```

### Parameters

- **_type:** The type of node to search for (e.g., `ClassB`, `Control`, `Node`).
- **_active_only:** (Optional) If `true`, only visible nodes will be returned. Defaults to `true`.
- **mainSubViewPort:** (Optional) The `SubViewport` to limit the search within. Defaults to `null` (searches the entire scene).
- **parentObject:** The parent node to search within.

### Examples

**1. Finding a specific UI element:**

```gdscript
# Find the "StartButton" button
var start_button : Button = SearchByNode.findNodeByType(Button, true, null)
```

**2. Finding all enemies in a level:**

```gdscript
# Find all active "Enemy" nodes within the "Level" sub-viewport
for enemy : Enemy in SearchByNode.findNodesByType(Enemy,true,level):
print(enemy.name)
```
### Additional Examples

For more detailed examples and practical use cases, check out the **example scenes** included in this repository.
You can load and run these scenes in Godot to see `SearchByNode` in action.
Feel free to experiment and adapt the examples to fit your specific needs.

### Notes

- The script assumes you are passing valid types and nodes as arguments.
- The `_active_only` parameter relies on the `is_visible_in_tree()` method, which might not be suitable for all scenarios (for example when looking for inactive objects also).
- The `get_main_scene_of_viewport()` function is useful when working with nested viewports.

### License

This asset is provided under the [MIT License](LICENSE.md).
Binary file added SearchIcon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions SearchIcon.jpg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://d00s7ogckc22v"
path="res://.godot/imported/SearchIcon.jpg-6ef744b2619a0876b32ad2e3cbd0171f.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://SearchIcon.jpg"
dest_files=["res://.godot/imported/SearchIcon.jpg-6ef744b2619a0876b32ad2e3cbd0171f.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
40 changes: 40 additions & 0 deletions addons/SearchByNode/Examples/FindMainScene/FindMainScene.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[gd_scene load_steps=2 format=3 uid="uid://b3y3anla8qv17"]

[ext_resource type="Script" path="res://addons/SearchByNode/Examples/FindMainScene/findMainSceneExample.gd" id="1_53184"]

[node name="MainScene" type="Node2D"]

[node name="Obj1" type="Node2D" parent="."]

[node name="Obj2" type="Node" parent="."]
script = ExtResource("1_53184")

[node name="Obj3" type="Node3D" parent="."]

[node name="SubViewport" type="SubViewport" parent="."]

[node name="SubMainScene" type="Node" parent="SubViewport"]

[node name="subObj1" type="Node2D" parent="SubViewport/SubMainScene"]

[node name="subObj2" type="Node2D" parent="SubViewport/SubMainScene"]
script = ExtResource("1_53184")

[node name="subObj3" type="Node2D" parent="SubViewport/SubMainScene"]

[node name="SubSubMainScene" type="Node3D" parent="SubViewport/SubMainScene"]

[node name="subObj1" type="Node2D" parent="SubViewport/SubMainScene/SubSubMainScene"]

[node name="subObj2" type="Node2D" parent="SubViewport/SubMainScene/SubSubMainScene"]
script = ExtResource("1_53184")

[node name="subObj3" type="Node2D" parent="SubViewport/SubMainScene/SubSubMainScene"]

[node name="SubMainScene2" type="Node2D" parent="SubViewport"]

[node name="subObj1" type="Node2D" parent="SubViewport/SubMainScene2"]

[node name="subObj2" type="Node2D" parent="SubViewport/SubMainScene2"]

[node name="subObj3" type="Node2D" parent="SubViewport/SubMainScene2"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extends Node


func _ready() -> void:
print(SearchByNode.get_main_scene_of_viewport(self).name) # will return current MainScene of a specific viewport
#print(self.get_viewport().name) # will return viewport but not the MainScene or subMainScenes
#print(get_tree().current_scene.name) # Will always return the currentScene "MainScene"
6 changes: 6 additions & 0 deletions addons/SearchByNode/Examples/FindNodeByType/ClassA.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extends Node
class_name ClassA


@export var nameObj : String = ""
@export var someInt : int = 3
5 changes: 5 additions & 0 deletions addons/SearchByNode/Examples/FindNodeByType/ClassB.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extends Node2D
class_name ClassB

@export var nameObj : String = ""
@export var someInt : int = 3
45 changes: 45 additions & 0 deletions addons/SearchByNode/Examples/FindNodeByType/SearchNodeByType.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[gd_scene load_steps=4 format=3 uid="uid://cysdm8cjpgygq"]

[ext_resource type="Script" path="res://addons/SearchByNode/Examples/FindNodeByType/findNodeExample.gd" id="1_42tc7"]
[ext_resource type="Script" path="res://addons/SearchByNode/Examples/FindNodeByType/ClassA.gd" id="2_ysxnj"]
[ext_resource type="Script" path="res://addons/SearchByNode/Examples/FindNodeByType/ClassB.gd" id="3_8wveg"]

[node name="MainScene" type="Node2D"]

[node name="ClassAObj1" type="Node2D" parent="."]
script = ExtResource("2_ysxnj")
nameObj = "ObjA1"

[node name="ClassAObj2" type="Node2D" parent="."]
script = ExtResource("2_ysxnj")
nameObj = "ObjA2"

[node name="ClassAObj4" type="Node2D" parent="ClassAObj2"]
script = ExtResource("2_ysxnj")
nameObj = "ObjA4"

[node name="ClassAObj3 NotVisible" type="Node2D" parent="."]
visible = false
script = ExtResource("2_ysxnj")
nameObj = "ObjA3 Not visible"

[node name="ClassBObj1" type="Node2D" parent="."]
script = ExtResource("3_8wveg")
nameObj = "ObjB1"

[node name="SomeObj" type="Node3D" parent="."]

[node name="SearchExample" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_42tc7")

[node name="InnerClassAObj5" type="Node2D" parent="SearchExample"]
script = ExtResource("2_ysxnj")
nameObj = "InnerObjA5"

[node name="InnerInnerClassAObj6" type="Node2D" parent="SearchExample/InnerClassAObj5"]
script = ExtResource("2_ysxnj")
nameObj = "InnerInnerObjA6"
37 changes: 37 additions & 0 deletions addons/SearchByNode/Examples/FindNodeByType/findNodeExample.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
extends Control


func _ready() -> void:
print("----------Find one ClassB Visible Node-------------------")
var objB_one : ClassB = SearchByNode.findNodeByType(ClassB,true)
if objB_one:
print(objB_one.nameObj)

print("----------Find all ClassA Visible only Nodes-------------------")
var classA_array : Array[ClassA]
classA_array.assign(SearchByNode.findNodesByType(ClassA,true))
for objA_all : ClassA in classA_array:
print(objA_all.nameObj)

print("----------Find all ClassA Visible and not Visible Nodes-------------------")
var classA_array_all_visiibility : Array[ClassA]
classA_array_all_visiibility.assign(SearchByNode.findNodesByType(ClassA,false))
for objA_all : ClassA in classA_array_all_visiibility:
print(objA_all.nameObj)



print("----------Find one InnerNode Visible Node-------------------")
var objA_innerOne : ClassA = SearchByNode.findInnerNodeInNode(ClassA,self)
if objA_innerOne:
print(objA_innerOne.nameObj)
print("----------Find all inner nodes of type ClassA Visible-------------------")
var innerClassA_array : Array[ClassA]
innerClassA_array.assign(SearchByNode.findInnerNodesInNode(ClassA,self))
for objA_inner_all : ClassA in innerClassA_array:
print(objA_inner_all.nameObj)



#SearchByNode.findNodeByType(ClassA.new(),true) # Do not use it like this as it will produce Error
#SearchByObject.findNodeByType(null,true) # Do not use it like this as it will produce Error
Loading

0 comments on commit fa19fc7

Please sign in to comment.