Skip to content

Add relevant traits to existing native classes (once traits are implemented) #12586

@Meorge

Description

@Meorge

Describe the project you are working on

Various games and the Godot engine

Describe the problem or limitation you are having in your project

There have been times I've wanted to access properties or methods of an object that could be one of a few different types, where the properties/methods aren't all covered by a single ancestor class.

The Node2D.position and Control.position properties are examples that come to mind for me; it would be nice to be able to access and modify the position of a node whether it inherits from either of those two base classes.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Once GDScript traits have been merged, create an API that allows native/C++ classes to be marked as implementing traits. Then, particular traits could be defined and applied to existing classes.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The Node2D and Control classes could implement a trait Positionable2D. If the classes were written in GDScript, they might look like so:

class Node2D extends CanvasItem uses Positionable2D:
    ...

class Control extends CanvasItem uses Positionable2D:
    var size: Vector2 = Vector2.ONE
    ...

trait Positionable2D:
    var position: Vector2 = Vector2.ZERO

Then, a GDScript user could do something like the following:

func move_node(some_node):
    if some_node is Positionable2D:  # some_node could be a Node2D or a Control
        some_node.position += Vector2(3, 6)

I'm not entirely certain how the C++ API for assigning traits to classes would work at this point. If this idea gains traction, we can discuss that in more detail.

Possible groupings

  • Positionable2D (position)
    • Node2D
    • Control
  • Labels (text)
    • Label
    • Label3D
    • RichTextLabel(?)
  • AudioStream players (play(), stop(), stream, volume_db, etc)
    • AudioStreamPlayer
    • AudioStreamPlayer2D
    • AudioStreamPlayer3D
  • Animated sprites (play(), stop(), animation, etc)
    • AnimatedSprite2D
    • AnimatedSprite3D

If this enhancement will not be used often, can it be worked around with a few lines of script?

Frequently, yes. For my example above, I think the same thing could be accomplished with multiple is checks:

if some_node is Node2D or some_node is Control:
    some_node.position += Vector2(3, 6)

This exact approach might fall apart for more complex operations, and if the user wants to ensure static typing, since some_node's type can't be defined as a union of either Node2D or Control.

Is there a reason why this should be core and not an add-on in the asset library?

I don't believe this would be possible to implement as an addon.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions