diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs
index 3e5d034268..16e133a2b5 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs
@@ -253,6 +253,10 @@ partial class ExportedFields
///
public new static readonly global::Godot.StringName @_fieldGodotGenericArray = "_fieldGodotGenericArray";
///
+ /// Cached name for the '_notIgnoredField' field.
+ ///
+ public new static readonly global::Godot.StringName @_notIgnoredField = "_notIgnoredField";
+ ///
/// Cached name for the '_fieldEmptyInt64Array' field.
///
public new static readonly global::Godot.StringName @_fieldEmptyInt64Array = "_fieldEmptyInt64Array";
@@ -505,6 +509,10 @@ partial class ExportedFields
this.@_fieldGodotGenericArray = global::Godot.NativeInterop.VariantUtils.ConvertToArray(value);
return true;
}
+ if (name == PropertyName.@_notIgnoredField) {
+ this.@_notIgnoredField = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
+ return true;
+ }
if (name == PropertyName.@_fieldEmptyInt64Array) {
this.@_fieldEmptyInt64Array = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
return true;
@@ -759,6 +767,10 @@ partial class ExportedFields
value = global::Godot.NativeInterop.VariantUtils.CreateFromArray(this.@_fieldGodotGenericArray);
return true;
}
+ if (name == PropertyName.@_notIgnoredField) {
+ value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@_notIgnoredField);
+ return true;
+ }
if (name == PropertyName.@_fieldEmptyInt64Array) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@_fieldEmptyInt64Array);
return true;
@@ -835,6 +847,7 @@ partial class ExportedFields
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@_fieldGodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@_fieldGodotGenericDictionary, hint: (global::Godot.PropertyHint)23, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@_fieldGodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
+ properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@_notIgnoredField, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
properties.Add(new(type: (global::Godot.Variant.Type)31, name: PropertyName.@_fieldEmptyInt64Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
return properties;
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
index 05ffd873be..dd2e1a0495 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
@@ -293,6 +293,10 @@ partial class ExportedProperties
///
public new static readonly global::Godot.StringName @PropertyGodotGenericArray = "PropertyGodotGenericArray";
///
+ /// Cached name for the 'NotIgnoredProperty' property.
+ ///
+ public new static readonly global::Godot.StringName @NotIgnoredProperty = "NotIgnoredProperty";
+ ///
/// Cached name for the '_notGeneratePropertyString' field.
///
public new static readonly global::Godot.StringName @_notGeneratePropertyString = "_notGeneratePropertyString";
@@ -609,6 +613,10 @@ partial class ExportedProperties
this.@PropertyGodotGenericArray = global::Godot.NativeInterop.VariantUtils.ConvertToArray(value);
return true;
}
+ if (name == PropertyName.@NotIgnoredProperty) {
+ this.@NotIgnoredProperty = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
+ return true;
+ }
if (name == PropertyName.@_notGeneratePropertyString) {
this.@_notGeneratePropertyString = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
return true;
@@ -927,6 +935,10 @@ partial class ExportedProperties
value = global::Godot.NativeInterop.VariantUtils.CreateFromArray(this.@PropertyGodotGenericArray);
return true;
}
+ if (name == PropertyName.@NotIgnoredProperty) {
+ value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@NotIgnoredProperty);
+ return true;
+ }
if (name == PropertyName.@_notGeneratePropertyString) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@_notGeneratePropertyString);
return true;
@@ -1044,6 +1056,7 @@ partial class ExportedProperties
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@PropertyGodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.@PropertyGodotGenericDictionary, hint: (global::Godot.PropertyHint)23, hintString: "4/0:;1/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.@PropertyGodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
+ properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@NotIgnoredProperty, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
return properties;
}
#pragma warning restore CS0109
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs
index a89c4afc2e..3cb438056c 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs
@@ -104,4 +104,9 @@ public partial class ExportedFields : GodotObject
[Export]
private Godot.Collections.Array _fieldGodotGenericArray = new() { 0, 1, 2, 3, 4, 5, 6 };
+
+ private int _notIgnoredField;
+
+ [IgnoreMember]
+ private int _ignoredField;
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
index 2753c5ec9a..76d2d30d65 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
@@ -223,4 +223,9 @@ public partial class ExportedProperties(string primaryCtorParameter) : GodotObje
[Export]
private Godot.Collections.Array PropertyGodotGenericArray { get; set; } = new() { 0, 1, 2, 3, 4, 5, 6 };
+
+ public int NotIgnoredProperty { get; set; }
+
+ [IgnoreMember]
+ public int IgnoredProperty { get; set; }
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs
index 1da9db8204..8526fbd260 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs
@@ -2,6 +2,11 @@ using Godot;
public partial class Methods : GodotObject
{
+ [IgnoreMember]
+ private void IgnoredMethod()
+ {
+ }
+
private void MethodWithOverload()
{
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs
index b431522e7c..5f91f89b7a 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs
@@ -5,6 +5,12 @@ public partial class ScriptBoilerplate : Node
private NodePath _nodePath;
private int _velocity;
+ [IgnoreMember]
+ private int _ignoredField;
+
+ [IgnoreMember]
+ private int IgnoredProperty { get; set; }
+
public override void _Process(double delta)
{
_ = delta;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
index 4ba64dc8dd..222e479bfe 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -299,6 +299,9 @@ namespace Godot.SourceGenerators
public static bool IsSystemFlagsAttribute(this INamedTypeSymbol symbol)
=> symbol.FullQualifiedNameOmitGlobal() == GodotClasses.SystemFlagsAttr;
+ public static bool IsGodotIgnoreMemberAttribute(this INamedTypeSymbol symbol)
+ => symbol.FullQualifiedNameOmitGlobal() == GodotClasses.IgnoreMemberAttr;
+
public static GodotMethodData? HasGodotCompatibleSignature(
this IMethodSymbol method,
MarshalUtils.TypeCache typeCache
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
index 3264ec2b54..8dee054652 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
@@ -11,6 +11,7 @@ namespace Godot.SourceGenerators
public const string ExportGroupAttr = "Godot.ExportGroupAttribute";
public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute";
public const string ExportToolButtonAttr = "Godot.ExportToolButtonAttribute";
+ public const string IgnoreMemberAttr = "Godot.IgnoreMemberAttribute";
public const string SignalAttr = "Godot.SignalAttribute";
public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute";
public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute";
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
index 7cbab34c5b..ddff4ddf7a 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
@@ -128,6 +128,8 @@ namespace Godot.SourceGenerators
var methodSymbols = members
.Where(s => s.Kind == SymbolKind.Method && !s.IsImplicitlyDeclared)
.Cast()
+ .Where(m => !m.GetAttributes()
+ .Any(a => a.AttributeClass?.IsGodotIgnoreMemberAttribute() ?? false))
.Where(m => m.MethodKind == MethodKind.Ordinary);
var godotClassMethods = methodSymbols.WhereHasGodotCompatibleSignature(typeCache)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
index 3846cc0a04..05db522bdb 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -112,7 +112,9 @@ namespace Godot.SourceGenerators
source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
source.Append("\n{\n");
- var members = symbol.GetMembers();
+ var members = symbol.GetMembers()
+ .Where(m => !m.GetAttributes()
+ .Any(a => a.AttributeClass?.IsGodotIgnoreMemberAttribute() ?? false));
var propertySymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Property)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index b3e6a055fe..a9659ccec2 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -111,7 +111,9 @@ namespace Godot.SourceGenerators
var exportedMembers = new List();
- var members = symbol.GetMembers();
+ var members = symbol.GetMembers()
+ .Where(m => !m.GetAttributes()
+ .Any(a => a.AttributeClass?.IsGodotIgnoreMemberAttribute() ?? false));
var exportedProperties = members
.Where(s => s.Kind == SymbolKind.Property)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
index 1329727448..c83fbb3bd2 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -110,7 +110,9 @@ namespace Godot.SourceGenerators
source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
source.Append("\n{\n");
- var members = symbol.GetMembers();
+ var members = symbol.GetMembers()
+ .Where(m => !m.GetAttributes()
+ .Any(a => a.AttributeClass?.IsGodotIgnoreMemberAttribute() ?? false));
var propertySymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Property)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/IgnoreMemberAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/IgnoreMemberAttribute.cs
new file mode 100644
index 0000000000..8517df5fe6
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/IgnoreMemberAttribute.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Godot
+{
+ ///
+ /// An attribute that excludes a member from registering as a method or property in Godot.
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)]
+ public sealed class IgnoreMemberAttribute : Attribute { }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 6482a16c53..cabcdea25b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -74,6 +74,7 @@
+