You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add trait-related keywords to syntax highlighting
Update style guide and static typing pages
Currently, the style guide uses what seem like good reasonable policies to me (notably, PascalCase adjectives for trait names, and `uses` after `extends`). We'll need to make sure this is agreed-upon as the good way to do it before merging, though
Document behavior of static variables in traits [no ci]
Document behavior of casting to traits
| in | Tests whether a value is within a string, array, range, dictionary, or node. When used with ``for``, it iterates through them instead of testing. |
- Constant names if they contain a script resource (``MyScript`` if you declared ``const MyScript = preload("res://my_script.gd")``).
1040
-
- Other classes in the same script, respecting scope (``InnerClass.NestedClass`` if you declared ``class NestedClass`` inside the ``class InnerClass`` in the same scope).
1062
+
- Constant names if they contain a script or trait resource (``MyScript`` if you declared ``const MyScript = preload("res://my_script.gd")``).
1063
+
- Other classes or traits in the same file, respecting scope (``InnerClass.NestedClass`` if you declared ``class NestedClass`` inside the ``class InnerClass`` in the same scope).
1041
1064
- Script classes declared with the ``class_name`` keyword.
1065
+
- Traits declared with the ``trait_name`` keyword.
1042
1066
- Autoloads registered as singletons.
1043
1067
1044
1068
.. note::
@@ -1104,11 +1128,11 @@ A class member variable can be declared static::
1104
1128
1105
1129
static var a
1106
1130
1107
-
Static variables belong to the class, not instances. This means that static variables
1131
+
Static variables belong to the class or trait, not instances. This means that static variables
1108
1132
share values between multiple instances, unlike regular member variables.
1109
1133
1110
-
From inside a class, you can access static variables from any function, both static and non-static.
1111
-
From outside the class, you can access static variables using the class or an instance
1134
+
From inside a class/trait, you can access static variables from any function, both static and non-static.
1135
+
From outside the class/trait, you can access static variables using the class/trait or an instance
1112
1136
(the second is not recommended as it is less readable).
1113
1137
1114
1138
.. note::
@@ -1179,6 +1203,24 @@ A base class static variable can also be accessed via a child class::
1179
1203
B.x = 3
1180
1204
prints(A.x, B.x) # 3 3
1181
1205
1206
+
.. warning::
1207
+
1208
+
Static variables declared on traits belong to the trait *itself*, and are *not*
1209
+
inherited by classes that use the trait::
1210
+
1211
+
trait HasStatic:
1212
+
static var static_var = 3
1213
+
1214
+
class UsingClass:
1215
+
uses HasStatic
1216
+
1217
+
func _ready():
1218
+
# Will work
1219
+
print(HasStatic.static_var)
1220
+
1221
+
# Will NOT work, as UsingClass does not get static_var from HasStatic
1222
+
print(UsingClass.static_var)
1223
+
1182
1224
``@static_unload`` annotation
1183
1225
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1184
1226
@@ -1208,15 +1250,15 @@ Values assigned to typed variables must have a compatible type. If it's needed t
1208
1250
coerce a value to be of a certain type, in particular for object types, you can
1209
1251
use the casting operator ``as``.
1210
1252
1211
-
Casting between object types results in the same object if the value is of the
1212
-
same type or a subtype of the cast type.
1253
+
Casting between object types or traits results in the same object if the value is of the
1254
+
same type or a subtype of the cast type, or if the value uses the trait.
1213
1255
1214
1256
::
1215
1257
1216
1258
var my_node2D: Node2D
1217
1259
my_node2D = $Sprite2D as Node2D # Works since Sprite2D is a subtype of Node2D.
1218
1260
1219
-
If the value is not a subtype, the casting operation will result in a ``null`` value.
1261
+
If the value is not a subtype or does not use the trait, the casting operation will result in a ``null`` value.
1220
1262
1221
1263
::
1222
1264
@@ -1324,7 +1366,7 @@ or ``0`` if it is the first entry in the enum. Multiple keys with the same value
1324
1366
Functions
1325
1367
---------
1326
1368
1327
-
Functions always belong to a `class <Classes_>`_. The scope priority for
1369
+
Functions always belong to a `class <Classes_>`_ or a `trait <Traits_>`_. The scope priority for
1328
1370
variable look-up is: local → class member → global. The ``self`` variable is
1329
1371
always available and is provided as an option for accessing class members, but
1330
1372
is not always required (and should *not* be sent as the function's first
@@ -1941,6 +1983,11 @@ A class (stored as a file) can inherit from:
1941
1983
1942
1984
Multiple inheritance is not allowed.
1943
1985
1986
+
.. note::
1987
+
Godot 4.x introduces `traits <Traits_>`_ to GDScript, which may cover many of
1988
+
the use cases for multiple inheritance. See their section for more information
1989
+
about how they work.
1990
+
1944
1991
Inheritance uses the ``extends`` keyword::
1945
1992
1946
1993
# Inherit/extend a globally available class.
@@ -1957,7 +2004,7 @@ Inheritance uses the ``extends`` keyword::
1957
2004
If inheritance is not explicitly defined, the class will default to inheriting
1958
2005
:ref:`class_RefCounted`.
1959
2006
1960
-
To check if a given instance inherits from a given class,
2007
+
To check if a given instance inherits from a given class or uses a given trait,
1961
2008
the ``is`` keyword can be used::
1962
2009
1963
2010
# Cache the enemy class.
@@ -1969,6 +2016,15 @@ the ``is`` keyword can be used::
1969
2016
if entity is Enemy:
1970
2017
entity.apply_damage()
1971
2018
2019
+
# Cache the Flammable trait.
2020
+
const Flammable = preload("flammable.gdt")
2021
+
2022
+
# [...]
2023
+
2024
+
# Use 'is' to check usage of the trait.
2025
+
if entity is Flammable:
2026
+
entity.light_on_fire()
2027
+
1972
2028
To call a function in a *super class* (i.e. one ``extend``-ed in your current
1973
2029
class), use the ``super`` keyword::
1974
2030
@@ -2121,6 +2177,136 @@ class resource is done by calling the ``new`` function on the class object::
2121
2177
var a = MyClass.new()
2122
2178
a.some_function()
2123
2179
2180
+
Traits
2181
+
------
2182
+
2183
+
Traits are collections of behaviors and attributes that classes can use to guarantee
2184
+
functionality to themselves and other objects that may be attempting to use them.
2185
+
2186
+
Like classes, by default all ``.gdt`` files are unnamed traits, and you must reference
2187
+
them using a relative or absolute path.
2188
+
::
2189
+
# Use the trait 'interactable.gdt'.
2190
+
uses "res://path/to/interactable.gdt"
2191
+
2192
+
Note that traits on their own *cannot* be instantiated the same way that classes can.
2193
+
2194
+
.. _doc_gdscript_basics_trait_name:
2195
+
2196
+
Registering named traits
2197
+
~~~~~~~~~~~~~~~~~~~~~~~~
2198
+
2199
+
Traits can be given a global name by using the ``trait_name`` keyword.
2200
+
::
2201
+
trait_name MyTrait
2202
+
2203
+
Using traits in a class
2204
+
~~~~~~~~~~~~~~~~~~~~~~~
2205
+
2206
+
For a class to use a trait, use the ``uses`` keyword:
2207
+
::
2208
+
class_name MyScript
2209
+
uses MyTrait
2210
+
2211
+
2212
+
Traits may also extend classes. If a trait extends a class, then any class
2213
+
that uses that trait must also have that class as an ancestor.
2214
+
::
2215
+
# movable.gdt
2216
+
trait_name Movable
2217
+
extends PhysicsBody2D
2218
+
2219
+
# character.gd
2220
+
class_name Character
2221
+
extends CharacterBody2D
2222
+
uses Movable # Allowed, since CharacterBody2D inherits from PhysicsBody2D.
2223
+
2224
+
The ``is`` keyword can be used to determine if a given instance uses a particular trait.
2225
+
::
2226
+
if entity is Movable:
2227
+
entity.move()
2228
+
2229
+
If a trait provides a method signature, but no body, then the using class must implement
2230
+
a body for the method.
2231
+
::
2232
+
# explosive.gdt
2233
+
trait_name Explosive
2234
+
2235
+
func explode() # Body is not defined here, so it must be defined in each class that uses it.
2236
+
2237
+
2238
+
# exploding_barrel.gd
2239
+
class_name ExplodingBarrel
2240
+
extends Sprite2D
2241
+
uses Explosive
2242
+
2243
+
func explode(): # If this definition of Explosive.explode isn't provided, we will get an error.
2244
+
print("Kaboom!")
2245
+
queue_free()
2246
+
2247
+
If a trait provides a method signature *and* a body, then the using class inherits it by default
2248
+
and doesn't need to provide its own implementation. It still can override the trait's
2249
+
implementation if desired, but the parameter count must stay the same, and the parameter and return
2250
+
types must be compatible.
2251
+
::
2252
+
# damageable.gdt
2253
+
trait_name Damageable
2254
+
2255
+
func take_damage():
2256
+
print("Ouch!")
2257
+
2258
+
2259
+
# invincible_npc.gd
2260
+
class_name InvincibleNPC
2261
+
extends Sprite2D
2262
+
uses Damageable
2263
+
2264
+
# Allowed, and will run instead of Damageable's original take_damage method.
2265
+
func take_damage():
2266
+
print("You can't hurt me!")
2267
+
2268
+
..
2269
+
TODO: Confirm these behaviors
2270
+
2271
+
Other class members have similar rules:
2272
+
2273
+
- Variables and constants can be overridden, as long as the type is compatible and the value is changed.
2274
+
- Signals can be overriden, as long as the parameter count is maintained and the parameter types are compatible.
2275
+
- Named enums can be overriden and have new enum values.
2276
+
2277
+
.. _doc_gdscript_basics_inner_traits:
2278
+
2279
+
Inner traits
2280
+
~~~~~~~~~~~~
2281
+
2282
+
Like inner classes, a class or trait file may contain inner traits, defined with the ``trait``
2283
+
keyword. Unlike inner classes, they cannot be instantiated directly, but their name can be
2284
+
referenced for using or checking use of themselves.
2285
+
::
2286
+
# An inner trait in this class file.
2287
+
trait SomeInnerTrait:
2288
+
func do_something():
2289
+
print("I did something!")
2290
+
2291
+
2292
+
# An inner class in this class file, which uses the inner trait.
2293
+
class SomeInnerClass:
2294
+
uses SomeInnerTrait
2295
+
2296
+
2297
+
func _init():
2298
+
var c = SomeInnerClass.new()
2299
+
if c is SomeInnerTrait:
2300
+
c.do_something()
2301
+
2302
+
.. _doc_gdscript_basics_traits_as_resources:
2303
+
2304
+
Traits as resources
2305
+
~~~~~~~~~~~~~~~~~~~
2306
+
2307
+
Traits stored as files are treated as :ref:`GDTraits <class_GDTrait>`, and must
2308
+
be loaded similarly to classes (see `Classes as resources`_).
0 commit comments