-
-
Notifications
You must be signed in to change notification settings - Fork 23.4k
Description
Tested versions
v4.5.stable.mono.Official
System information
Windows 10 - Godot 4.5.Stable.Mono
Issue description
When using the C# bindings, setting the AnchorsPreset property on any Control-derived node has no effect and fails silently. The property's value remains at 0 (PRESET_NONE), and the control's anchors are not updated. To correctly change the anchors preset, one must call the SetAnchorsPreset() method.
This represents a significant API "paper cut" as it violates the Principle of Least Astonishment. Code that appears correct and compiles without error (myControl.AnchorsPreset = (int)LayoutPreset.FullRect;) does not perform the expected action. This leads to frustrating bugs that are difficult to diagnose, as the failure is completely silent.
Potential solutions:
(Ideal Fix) Modify the C# source generator to ensure that the generated set accessor for properties like this correctly calls the corresponding Set...() method (e.g., set { SetAnchorsPreset((LayoutPreset)value); }).
(Minimum Fix) If the ideal fix is not feasible, the property should be made read-only ({ get; }) in the C# bindings. This would prevent this error by forcing developers to use the SetAnchorsPreset() method, resulting in a compile-time error instead of a silent runtime failure.
This would significantly improve the developer experience and prevent future confusion for C# users.
Steps to reproduce
Create a new C# script.
- In the _Ready() method, instantiate a Control node.
- Attempt to set its anchors using the AnchorsPreset property.
- Print the value of the property and the control's AnchorRight after setting.
public override void _Ready()
{
var myControl = new Panel();
AddChild(myControl);
GD.Print($"Before setting: AnchorsPreset = {myControl.AnchorsPreset}, AnchorRight = {myControl.AnchorRight}");
// This line compiles but does nothing at runtime.
myControl.AnchorsPreset = (int)LayoutPreset.FullRect;
GD.Print($"After setting: AnchorsPreset = {myControl.AnchorsPreset}, AnchorRight = {myControl.AnchorRight}");
// The correct way, which works as expected.
// myControl.SetAnchorsPreset(LayoutPreset.FullRect);
// GD.Print($"After SetAnchorsPreset(): AnchorRight = {myControl.AnchorRight}");
}
Actual Behavior:
The console shows that AnchorsPreset remains 0 and AnchorRight remains 0.0. The property assignment failed silently.
Analysis and Suggested Fix:
This issue appears to stem from the C# source generator. The property is defined in scene/gui/control.cpp using ADD_PROPERTY with set_anchors_preset as the setter method. The generated C# property AnchorsPreset does not seem to call this method in its setter.
Minimal reproduction project (MRP)
this isnt really necessary for this bug report as it is a simple bindings issue.