Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 31 additions & 33 deletions tutorials/best_practices/godot_notifications.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,28 +164,39 @@ _init vs. initialization vs. export
-----------------------------------

If the script initializes its own node subtree, without a scene,
that code should execute here. Other property or SceneTree-independent
initializations should also run here. This triggers before ``_ready()`` or
``_enter_tree()``, but after a script creates and initializes its properties.
that code should execute in ``_init()``. Other property or SceneTree-independent
initializations should also run here.

Scripts have three types of property assignments that can occur during
instantiation:
.. note::
The C# equivalent to GDScript's ``_init()`` method is the constructor.

``_init()`` triggers before ``_enter_tree()`` or ``_ready()``, but after a script
creates and initializes its properties. When instantiating a scene, property
values will set up according to the following sequence:

1. **Initial value assignment:** the property is assigned its initialization value,
or its default value if one is not specified. If a setter exists, it is not used.

2. **``_init()`` assignment:** the property's value is replaced by any assignments
made in ``_init()``, triggering the setter.

3. **Exported value assignment:** an exported property's value is again replaced by
any value set in the Inspector, triggering the setter.

.. tabs::
.. code-tab:: gdscript GDScript

# "one" is an "initialized value". These DO NOT trigger the setter.
# If someone set the value as "two" from the Inspector, this would be an
# "exported value". These DO trigger the setter.
# test is initialized to "one", without triggering the setter.
@export var test: String = "one":
set(value):
test = value
print("Setting: ", test)
test = value + "!"

func _init():
# "three" is an "init assignment value".
# Trigger the setter
test = "three"
# Triggers the setter, changing test's value from "one" to "two!".
test = "two"

# If someone sets test to "three" from the Inspector, it would trigger
# the setter, changing test's value from "two!" to "three!".

.. code-tab:: csharp

Expand All @@ -195,37 +206,24 @@ instantiation:
{
private string _test = "one";

// Changing the value from the inspector does trigger the setter in C#.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is important because it lets users know that property setters will be executed by the inspector. It's true that the previous message seems to assume that you've read the GDScript example before, so it could be reworded but I don't think it should be removed entirely.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data is moved to line 220. I put discussion of @exports at the bottom of the file in both languages so that the order of value assignment matches the order you read the example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I guess it's fine. I still find it a bit weird that information about the exported property is so far from the property itself.

[Export]
public string Test
{
get { return _test; }
set
{
_test = value;
GD.Print($"Setting: {_test}");
}
set { _test = $"{value}!"; }
}

public MyNode()
{
// Triggers the setter as well
Test = "three";
// Triggers the setter, changing _test's value from "one" to "two!".
Test = "two";
}
}

When instantiating a scene, property values will set up according to the
following sequence:

1. **Initial value assignment:** instantiation will assign either the
initialization value or the init assignment value. Init assignments take
priority over initialization values.

2. **Exported value assignment:** If instancing from a scene rather than
a script, Godot will assign the exported value to replace the initial
value defined in the script.
// If someone sets Test to "three" in the Inspector, it would trigger
// the setter, changing _test's value from "two!" to "three!".
}

As a result, instantiating a script versus a scene will affect both the
As a result, instantiating a script versus a scene may affect both the
initialization *and* the number of times the engine calls the setter.

_ready vs. _enter_tree vs. NOTIFICATION_PARENTED
Expand Down