
Publisher
amopel
xchange-scene
Xchange-scene is a robust, high level interface for manipulating child scenes below a given Node and indexing them.
This plugin has been mirrored from the Godot Asset Library.
The plugin author is in no way affiliated with Gadget.
If you are the author of this plugin and would like this mirror removed, please contact support@gadgetgodot.com.
xchange-scene
Xchange-scene is a robust, high level interface for manipulating child scenes below a given Node
and indexing them.
Disclaimer: In the following, when talking about scenes, often it's about the instance of the scene, which is added as a child scene to the tree, and which is also a Node.
Inspired by this part of the godot docs.
TL;DR
Scenes can be in these states:
state | function used | consequence |
---|---|---|
ACTIVE | .add_child(Node) |
running and visible |
HIDDEN | Node.hide() |
running and hidden |
STOPPED | .remove_child(Node) |
not running, but still in memory |
FREE | Node.free() |
no longer in memory and no longer indexed |
In the example/main.gd you can see all of the features in action.
Here is a first taste:
var scene1 = preload("scene1.tscn")
# x adds and removes scenes below $World
# adds itself to the tree below $World
var x = XScene.new($World)
# this is a reference to $World
var r = x.root
# add_scene takes a PackedScene or a Node
# without a key specified it indexes automatically with integers starting at 1
# (this can be changed to 0)
# default method is ACTIVE, using add_child()
x.add_scene(scene1)
# uses add_child() and .hide()
x.add_scene(scene1, "a", x.HIDDEN)
# just instances and indexes the scene
x.add_scene(scene1, "stopped_s1", x.STOPPED)
get_node("/root").print_tree_pretty()
# ┖╴root
# ┖╴Main
# ┠╴Gui
# ┃ ┖╴ColorRect
# ┠╴World
# ┃ ┠╴Node2D ACTIVE
# a:{scene:[Node2D:1231], state:1}, -> HIDDEN
# stopped_s1:{scene:[Node2D:1235], state:2}} -> STOPPED
# uses remove_child()
x.remove_scene(1, x.STOPPED)
get_node("/root").print_tree_pretty()
# ┠╴World
# ┃ ┠╴Node2D
# ┃ ┃ ┖╴Node2D
# ┃ ┃ ┖╴Node2D
# ┃ ┃ ┖╴icon
# ┃ ┠╴@@2
# ┃ ┖╴@Node2D@4
- Download a __.zip__ of this repo and unpack it into your project
The version in the AsserLib is __not__ up to date
For more details, read the [godot docs on installing Plugins
](https://docs.godotengine.org/en/stable/tutorials/plugins/editor/installing_plugins.html)
__Don't forget to enable it in your project settings!__
### Run examples
To run the examples yourself, you can
1. Clone this repo
`git clone https://github.com/aMOPel/godot-xchange-scene.git xscene`
2. Run godot in it (eg. using linux and bash)
`cd xscene; godot --editor`
3. Comment and uncomment the functions in [__example/main.gd__](https://raw.githubusercontent.com/aMOPel/godot-xchange-scene/main/example/main.gd) `_ready()`
4. Run the main scene in godot
### Usage
In the [__example/main.gd__](https://raw.githubusercontent.com/aMOPel/godot-xchange-scene/main/example/main.gd) you can see how to use it.
There are little __tutorials__ split in functions with __a lot of comments__ to explain everything in detail.
Also in [__docs/XScene.md__](https://raw.githubusercontent.com/aMOPel/godot-xchange-scene/main/docs/XScene.md) is a full markdown reference built from the docstrings.
However it is hard to read on Github because it merges the linebreaks. Either read it in an editor on read it
["Raw" on Github](https://raw.githubusercontent.com/aMOPel/godot-xchange-scene/main/docs/XScene.md).
```gdscript
# example/main.gd
# gives an instance of XScene
# it adds itself below $World
# it doesn't index itself
x = XScene.new($World)
# ┖╴root
# ┖╴Main
# ┠╴Gui
# ┃ ┖╴ColorRect
# ┖╴World <- acts below World
# ┖╴@@2 <- x
This will give you an instance of XScene
(the main class), which acts and sits below
World
.
Transistions
from\to | ACTIVE = 0 | HIDDEN = 1 | STOPPED = 2 | FREE = 3 |
---|---|---|---|---|
ACTIVE | --- | remove_scene(key, HIDDEN) |
remove_scene(key, STOPPED) |
remove_scene(key, FREE) |
HIDDEN | show_scene(key) |
--- | remove_scene(key, STOPPED) |
remove_scene(key, FREE) |
STOPPED | show_scene(key) |
--- | --- | remove_scene(key, FREE) |
FREE | add_scene(scene, key, ACTIVE) |
add_scene(scene, key, HIDDEN) |
add_scene(scene, key, STOPPED) |
--- |
The states are just an enum
, so you can also use the integers, but writing out
the names helps readability of your code.
Normally the visibility of a node (HIDDEN) and if it's in the tree or not
(STOPPED), are unrelated. However, in this plugin it's either or. Meaning, when
a hidden scene is stopped, its visibility will be reset to true
. And when a
stopped scene happened to also be hidden, show_scene
will reset its visibility
to true
.
NOTE: Although this plugin resembles a state machine, it isn't implemented as one.
Caveats
- This plugin adds an overhead to adding and removing scenes. When you add or remove in high quantities, you should consider using the built-in commands, if you don't have to index the scenes so thoroughly.
- The sync feature adds more overhead and should also only be used for small quantities of scenes. Mind that this feature checks for every addition in the whole tree. So if you were to have a few
XScene
instances with sync enabled, every instances will make checks and add even more overhead
Here are some really basic benchmarks taken on my mediocre personal PC.
This benchmark comes from adding (ACTIVE) and removing (FREE) 1000 instances of a scene
that consists of 4 nodes below root
. Every test was done 10 times and the
time was averaged. In example/main.gd test_time()
you can see the code used.
X | no sync | sync |
---|---|---|
add_child() |
0.011148 | 0.020159 |
add_scene(ACTIVE) |
0.014747 | 0.017216 |
free() |
0.090902 | 0.098739 |
remove_scene(FREE) |
0.098556 | 0.099513 |
These measurements aren't exactly statistically significant, but they give a good idea of the overhead added by this plugin, especially when using sync. Note that the overhead is more or less independent of sync when removing scenes.
TODO
- You can open an issue if you're missing a feature