-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add switch_scene resource #298
Conversation
type = 2 | ||
variant_type = 4 | ||
display_template = "switch the scene to {file_path: STRING}" | ||
code_template = "get_tree().change_scene_to_file({file_path}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People more expert in Godot than me: is there some way we can refer to the other scene other than by file path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm imagining here is: can we make it possible to drag a tscn
file onto the canvas and then have a block representing a different scene? Or a dropdown list of all tscn
files in the project, except the current one and scenes that are part of the plugin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is another way to do is to export a PackedScene variable packed scene. It will allows the user to assign the scene in the inspector. Should we update and use this approach instead? (Although I'm not the expert)
During my research, I found three ways to switch scenes: T35706. Hopefully, we can get more input from the experts!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is right to do this in the block coding canvas (as you have done) not to go to the inspector. I was hoping we could do something similar to how we can drop nodes into the canvas to get a block that represents that node.
I did some brief experiments with this... If you have a node that exports a variable of type PackedScene
, then assign a scene to it, it gets represented as (wrapped for legibility):
[ext_resource type="PackedScene"
uid="uid://c2pcat3ejl74o"
path="res://Scene2.tscn"
id="2_g4qc4"]
I feel like it ought to be possible to define a value block that gets serialised in a way that refers to an external scene in this way. Then this switch_scene
block would accept a parameter of type PackedScene. And for bonus points we would give it a dropdown of all scenes in the project, like we do for parameters of type node or group.
Unfortunately block parameter types are expressed as Variant.Type enum members and a PackedScene
is just an OBJECT
. There's no analogue to NODE_PATH
.
As well as the drag-and-drop idea, another reason it may be nice to store the reference to another scene in a way that Godot itself understands to be a reference to a file rather than just a string is that Godot knows how to update all such references if you rename the scene.
Anyway... What I'm suggesting is of course all way more work than adding a switch_scene block whose parameter is a string. And having the block at all would make a whole world of things possible which currently aren't. So all my suggestions here should probably be considered further work for another time…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm imagining here is: can we make it possible to drag a
tscn
file onto the canvas and then have a block representing a different scene? Or a dropdown list of alltscn
files in the project, except the current one and scenes that are part of the plugin?
Yeah, in the same way as the more sophisticated alternative to drag&drop sounds that I described in #166 (comment)
Unfortunately block parameter types are expressed as Variant.Type enum members and a
PackedScene
is just anOBJECT
. There's no analogue toNODE_PATH
.
I think that we should add a class_name
field to the block definition, that will pair with the variant_type
field for the case where the variant is of type OBJECT
. This is the same Godot has for typed arrays:
- https://docs.godotengine.org/en/stable/classes/class_array.html#class-array-method-get-typed-builtin
- https://docs.godotengine.org/en/stable/classes/class_array.html#class-array-method-get-typed-class-name
Then when dragging from the Filesystem to the block canvas:
- If the resource is a sound, add a value block of variant type OBJECT and class name AudioStream.
- If the resource is a
tscn
orscn
, add a value block of variant type OBJECT and class name PackedScene.
In the same way, the holes or slots can be enhaced to allow a specific class name when the variant type is OBJECT. Then we could do:
- "play sound" block: Has a slot that supports a value block of variant type OBJECT and class name AudioStream.
- "switch scene" block: Has a slot that supports a value block of variant type OBJECT and class name PackedScene.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, a PackedScene is a Resource
. SceneTree (what you get from get_tree()
) provides 2 methods for changing scenes - from a file path, and from a PackedScene.
In code you might do it like this:
func change_scene(scene: Variant):
if scene is String:
get_tree().change_scene_to_file(scene)
elif scene is PackedScene:
get_tree().change_scene_to_packed(scene)
else:
push_error("Can only change scene from String or PackedScene")
With blocks we kinda need to be specific about what kind of Variant
the parameter is, so we'd need to do one or the other. @manuq has some suggestions on handling that if we want to use PackedScene
s.
I like the idea of loading a PackedScene
with change_scene_to_packed
, but then you'd have to tackle the whole part of creating a scene with a block using load
. It would be very similar to the get_node
block, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think #305 helps get_tree().change_scene_to_file(scene)
:)
Having said everything about using a |
7b3e199
to
4b64665
Compare
This is a basic scene-switching block using a string. If we have time later, we can make further improvements by adding a block for loading a scene and using that as the argument to the switch_scene block to implement PackedScene. https://phabricator.endlessm.com/T35706
4b64665
to
d88cae7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works!
Add a new block that allows the user to switch to another scene via a specified scene file path.
https://phabricator.endlessm.com/T35706