Node that isn't a tool but was created by tool in editor runs _Process until restart
Tested versions
v4.3.stable.mono.official [77dcf97d8]
dotnet --info
.NET SDK:
Version: 8.0.402
Commit: 70aa751718
Workload version: 8.0.400-manifests.b6724b7a
MSBuild version: 17.11.4+37eb419ad
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: c:\program files\dotnet\sdk\8.0.402\
.NET workloads installed:
Configured to use loose manifests when installing new manifests.
There are no installed workloads to display.
Host:
Version: 8.0.8
Architecture: x64
Commit: 08338fcaa5
.NET SDKs installed:
8.0.402 [c:\program files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.8 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.15 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.11 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.2 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.8 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.15 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.11 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.2 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.8 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
System information
Godot v4.3.stable.mono - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 32.0.15.6094) - AMD Ryzen 9 5950X 16-Core Processor (32 Threads)
Issue description
When creating a node from a C# tool script, even if the created node is not a tool, it runs its _process function as if it was until the editor is restarted
I may be just misunderstanding how tools work, but I thought that nodes that are not tools should never be able run code in the editor.
Steps to reproduce
- Create blank scene
- Create Tool:
using Godot;
using System;
[GlobalClass, Tool]
public partial class ThisIsATool : Node3D
{
[Export] public bool Toggle {
get => _toggle;
set {
_toggle = value;
CreateBrokenNode();
}
}
private bool _toggle = false;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
private void CreateBrokenNode()
{
var root = EditorInterface.Singleton.GetEditedSceneRoot();
var node = new ThisIsNotATool();
AddSibling(node);
node.SetOwner(root);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
}
- Create a type that isn't a tool
using Godot;
using System;
[GlobalClass]
public partial class ThisIsNotATool : Node
{
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
GD.Print("This is not a tool");
}
}
- Hitting the toggle will cause node to be created and "This is not a tool" to be spammed in editor.
- Restart editor, problem goes away.
Minimal reproduction project (MRP)
So I thought this was an issue just with C# but it does it with GDscript too, This MRP has both examples: brokentool_v2.zip
@tool
extends Node3D
class_name ThisIsAToolGodot
@export var toggle: bool = false :
get:
return toggle
set(value):
toggle = value
toggle_set()
func toggle_set():
var root = EditorInterface.get_edited_scene_root()
var node = ThisIsNotAToolGodot.new()
root.add_child(node)
node.set_owner(root)
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
toggle_set() # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
extends Node3D
class_name ThisIsNotAToolGodot;
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
print("This is not a tool")
@tool only allows creating a script instance when node is instantiated. If you do Node.new() and node.set_script(ThisIsNotAToolGodot) it will have different effect than ThisIsNotAToolGodot.new(). In the latter case you are instantiating the script, in the former it's just attached to the node, but script instance is not created.