-
-
Notifications
You must be signed in to change notification settings - Fork 97
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 a generic parameter to PackedScene (like Array) to allow for easier type safety #6694
Comments
This seems to be difficult to implement. Even for typed arrays, the methods return a To work around the problem, you can use an intermediate typed variable or the var bullet: Bullet = bullet_scene.instantiate()
bullet.init(Vector2.UP * 200) var bullet = (bullet_scene.instantiate() as Bullet).init(Vector2.UP * 200) Also you can use the following approach (see #1935): extends Node2D
class_name Bullet
var velocity: Vector2
static func create(p_velocity: Vector2) -> Bullet:
var bullet: Bullet = load("res://bullet.tscn").instantiate()
bullet.velocity = p_velocity
return bullet |
@KoBeWi It would be perfectly fine if typed PackedScenes returned a variant like Arrays do as long as Godot can enforce using the variable properly the same way. But I hadn't thought of the workaround of instantiating the scene in Bullet, that might be even better than the initial approach! |
When instantiating nodes at runtime, I have found that I need to declare a Coming from Unity, this way of instantiating prefabs in a typesafe way was very comforting and convenient. I'd love to have a // No way in editor to only assign the correct type,
// nor any hints about what the correct type is.
[Export] public PackedScene PlayerPrefab { get; private set; }
public void SpawnPlayer()
{
// Could crash at runtime if the wrong type of PackedScene was assigned
var player = PlayerPrefab.Instantiate<FpvPlayer>();
...
} |
What you want is more like PackedScene subtypes, though? Because you shouldn't be able to assign non scene things to an export of type PackedScene? Workaround I use in GDScript: check that the scene has expected variables. |
I had a suggestion like this where we could export something like...
it would actually be really useful to make sure when you instance a type your getting what you need. Either way though it requires alot of code that could just be as easy as a simple export. I do agree that we should be able to pass Scenes directly to Node types
and of course I would support custom types from the get go |
im a little confused, is this different from the original suggestion? |
No but it was just to show we could do this with NodePath's as well and then we can treat exporting Node's and either a NodePath or a PackedScene |
What about adding a new annotation for scenes? Something like: @export_scene(MyType) var my_scene : PackedScene
@export_scene(MyType) var my_scenes : Array[PackedScene] It might not help with type safety on the code side, but the editor side will be tasked with filtering PackedScenes with that root node type (or subtype). This can make casting much less error-prone. Although, the editor would have to keep an active lookout for cases where the root node of a scene has its type changed. |
Isn't that only a editor thing? I would like this for scripting too. |
This would be extremely helpful for resources with a tree-like structure. In my case, attacks are defined as a root node with a tree of subproperties and subattacks. If I define them as a Resource, I lose the Node/Scene editor (as well as transform behavior), and quickly editing trees of attack definitions becomes much more cumbersome. But if I define my attacks as Scene of nodes instead of a Resource, there's no way to ensure at compile-time that I'm giving my objects the attack definitions they expect. Giving PackedScenes a "type" would solve this issue. |
I think this issue should be linked: #5255 |
Describe the project you are working on
A game in which the player can shoot bullets. The class
Bullet
has aninit
method that sets it up and returnsself
.bullet_scene
contains a scene in which the root has theBullet
script.Describe the problem or limitation you are having in your project
I want to instance and set up the bullet like so:
which works fine but it isn't type safe. I can't have godot infer the type of bullet with
:=
and its becauseinstantiate
just returns a node of unknown type. I can't autocompleteBullet
's methods and mistakes aren't caught until they come up in runtimeDescribe the feature / enhancement and how it helps to overcome the problem or limitation
A typed
PackedScene
that, wheninstantiate
is called, returns a value statically typed as whatever type it only supposed to be able to contain.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Godot 4 brings typed arrays where getting an item from them automatically types that value as the type they are marked to contain.
Seeing that this is possible, I imagine it wouldn't be too much more difficult to type a PackedScene in a similar way, say
In the export section in the inspector, the editor should either somehow refuse scenes that do not have the given type as the root, or if this is not possible the game should create a runtime error as soon as you try to put a scene that doesn't fit into a packed scene variable.
instantiate
would return a value that is statically types just as typed arrays return a typed value when you call the indexing method.If this enhancement will not be used often, can it be worked around with a few lines of script?
You can ignore type safety and hope for the best (bad) or cast the value from
instantiate
before using it (ugly and unreadable)Is there a reason why this should be core and not an add-on in the asset library?
Changing the way gdscript works isn't possible through an addon
I am unfortunately not able to implement this myself looking through godots source code made my head spin
The text was updated successfully, but these errors were encountered: