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
- Constant names if they contain a script or trait resource (``MyScript`` if you declared ``const MyScript = preload("res://my_script.gd")``).
1108
1106
- 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).
1109
1107
- Script classes declared with the ``class_name`` keyword.
1110
-
- Traits declared with the ``trait_name`` keyword.
1111
1108
- Autoloads registered as singletons.
1112
1109
1113
1110
.. note::
@@ -1258,18 +1255,6 @@ A base class static variable can also be accessed via a child class:
1258
1255
B.x = 3
1259
1256
prints(A.x, B.x) # 3 3
1260
1257
1261
-
Likewise, if a class uses a trait with static variables, it will inherit those
1262
-
variables::
1263
-
1264
-
trait HasStatic:
1265
-
static var static_var = 3
1266
-
1267
-
class UsingClass:
1268
-
uses HasStatic
1269
-
1270
-
func _ready():
1271
-
print(UsingClass.static_var)
1272
-
1273
1258
``@static_unload`` annotation
1274
1259
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1275
1260
@@ -2381,94 +2366,74 @@ class resource is done by calling the ``new`` function on the class object:
2381
2366
var a = MyClass.new()
2382
2367
a.some_function()
2383
2368
2369
+
2370
+
.. _doc_gdscript_basics_traits:
2371
+
2384
2372
Traits
2385
2373
------
2386
2374
2387
2375
Since Godot 4.x, GDScript supports traits, which are collections of behaviors and attributes
2388
2376
that classes can use to guarantee
2389
2377
functionality to themselves and other objects that may be attempting to use them.
2390
2378
2391
-
Like classes, by default all ``.gdt`` files are unnamed traits, and you must reference
2392
-
them using a relative or absolute path.
2393
-
::
2394
-
# Use the trait 'interactable.gdt'.
2395
-
uses "res://path/to/interactable.gdt"
2396
-
2397
2379
Note that traits on their own *cannot* be instantiated the same way that classes can.
2398
2380
2399
-
.. _doc_gdscript_basics_trait_name:
2400
-
2401
-
Registering named traits
2381
+
Registering traits
2402
2382
~~~~~~~~~~~~~~~~~~~~~~~~
2403
2383
2404
-
Traits can be given a global name by using the ``trait_name`` keyword.
2384
+
Traits can be created inside of a GDScript class by using the ``trait`` keyword.
2405
2385
::
2406
-
trait_name MyTrait
2386
+
2387
+
trait Damageable:
2388
+
signal died
2389
+
2390
+
const MAX_HEALTH = 100
2391
+
var health = MAX_HEALTH
2392
+
2393
+
func take_damage(amount): # Will automatically exist in any class using this trait.
2394
+
health -= amount
2395
+
on_hit()
2396
+
if health <= 0:
2397
+
on_death()
2398
+
died.emit()
2399
+
2400
+
func on_hit() # Unimplemented method - Must be overriden in any class using this trait.
2407
2401
2408
2402
Using traits in a class
2409
2403
~~~~~~~~~~~~~~~~~~~~~~~
2410
2404
2411
-
For a class to use a trait, use the ``uses`` keyword:
2412
-
::
2413
-
class_name MyScript
2414
-
uses MyTrait
2415
-
2416
-
2417
-
Traits may also extend classes. If a trait extends a class, then any class
2418
-
that uses that trait must also have that class as an ancestor.
2405
+
For a class to use a trait, include the ``uses`` keyword:
2419
2406
::
2420
-
# movable.gdt
2421
-
trait_name Movable
2422
-
extends PhysicsBody2D
2423
-
2424
-
# character.gd
2425
-
class_name Character
2426
-
extends CharacterBody2D
2427
-
uses Movable # Allowed, since CharacterBody2D inherits from PhysicsBody2D.
2407
+
class_name Player
2408
+
uses Damageable
2428
2409
2429
2410
The ``is`` keyword can be used to determine if a given instance uses a particular trait.
2430
2411
::
2431
-
if entity is Movable:
2432
-
entity.move()
2412
+
if entity is Damageable:
2413
+
entity.take_damage(1)
2433
2414
2434
2415
If a trait provides a method signature, but no body, then the using class must implement
2435
2416
a body for the method.
2436
2417
::
2437
-
# explosive.gdt
2438
-
trait_name Explosive
2439
-
2440
-
func explode() # Body is not defined here, so it must be defined in each class that uses it.
2441
-
2442
-
2443
-
# exploding_barrel.gd
2444
-
class_name ExplodingBarrel
2445
-
extends Sprite2D
2446
-
uses Explosive
2418
+
class_name Player
2419
+
extends CharacterBody2D
2420
+
uses Damageable
2447
2421
2448
-
func explode(): # If this definition of Explosive.explode isn't provided, we will get an error.
2449
-
print("Kaboom!")
2450
-
queue_free()
2422
+
func on_hit():
2423
+
print("Ouch, that hurt!")
2451
2424
2452
2425
If a trait provides a method signature *and* a body, then the using class inherits it by default
2453
2426
and doesn't need to provide its own implementation. It still can override the trait's
2454
2427
implementation if desired, but the parameter count must stay the same, and the parameter and return
2455
2428
types must be compatible.
2456
2429
::
2457
-
# damageable.gdt
2458
-
trait_name Damageable
2459
-
2460
-
func take_damage():
2461
-
print("Ouch!")
2462
-
2463
-
2464
-
# invincible_npc.gd
2465
2430
class_name InvincibleNPC
2466
2431
extends Sprite2D
2467
2432
uses Damageable
2468
2433
2469
2434
# Allowed, and will run instead of Damageable's original take_damage method.
2470
-
func take_damage():
2471
-
print("You can't hurt me!")
2435
+
func take_damage(amount):
2436
+
print("Ah ha ha! You can't hurt me!")
2472
2437
2473
2438
..
2474
2439
TODO: Confirm these behaviors
@@ -2479,39 +2444,6 @@ Other class members have similar rules:
2479
2444
- Signals can be overriden, as long as the parameter count is maintained and the parameter types are compatible.
2480
2445
- Named enums can be overriden and have new enum values.
2481
2446
2482
-
.. _doc_gdscript_basics_inner_traits:
2483
-
2484
-
Inner traits
2485
-
~~~~~~~~~~~~
2486
-
2487
-
Like inner classes, a class or trait file may contain inner traits, defined with the ``trait``
2488
-
keyword. Unlike inner classes, they cannot be instantiated directly, but their name can be
2489
-
referenced for using or checking use of themselves.
2490
-
::
2491
-
# An inner trait in this class file.
2492
-
trait SomeInnerTrait:
2493
-
func do_something():
2494
-
print("I did something!")
2495
-
2496
-
2497
-
# An inner class in this class file, which uses the inner trait.
2498
-
class SomeInnerClass:
2499
-
uses SomeInnerTrait
2500
-
2501
-
2502
-
func _init():
2503
-
var c = SomeInnerClass.new()
2504
-
if c is SomeInnerTrait:
2505
-
c.do_something()
2506
-
2507
-
.. _doc_gdscript_basics_traits_as_resources:
2508
-
2509
-
Traits as resources
2510
-
~~~~~~~~~~~~~~~~~~~
2511
-
2512
-
Traits stored as files are treated as :ref:`GDTraits <class_GDTrait>`, and must
2513
-
be loaded similarly to classes (see `Classes as resources`_).
0 commit comments