Godot Version
v4.2.2.stable.mono.official [15073afe3]
Question
I’m trying to figure out a good way to set up my Camera2D
. Right now, I’ve got the camera as its own scene called Camera
, which is autoloaded. It’s meant to find and follow my player using this code:
using Godot;
public partial class CameraManager : Camera2D {
public static CameraManager cameraManager;
Node2D player;
public CameraManager() {
cameraManager = this;
}
public override void _Ready() {
ProcessMode = ProcessModeEnum.Always;
FindPlayer();
}
// Get a reference to the Player node
public void FindPlayer() {
if (player is null) {
player = GetTree().Root.FindChild("Player", true, false) as Node2D;
}
}
// Move towards the player's position every frame
public override void _Process(double delta) {
Position = player.Position;
}
}
This works surprisingly well — the camera still does smoothing and adheres to its boundary limits — except for one problem: reloading the scene. When I call GetTree().ReloadCurrentScene()
, the camera functionality breaks.
E 0:00:02:0887 GodotObject.base.cs:73 @ nint Godot.GodotObject.GetPtr(Godot.GodotObject): System.ObjectDisposedException: Cannot access a disposed object.
Object name: ‘CharacterMovement’.
<C# Error> System.ObjectDisposedException
<C# Source> /root/godot/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs:73 @ nint Godot.GodotObject.GetPtr(Godot.GodotObject)
GodotObject.base.cs:73 @ nint Godot.GodotObject.GetPtr(Godot.GodotObject)
Node2D.cs:259 @ Godot.Vector2 Godot.Node2D.GetPosition()
Node2D.cs:21 @ Godot.Vector2 Godot.Node2D.get_Position()
CameraManager.cs:25 @ void CameraManager._Process(double)
Node.cs:2131 @ bool Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
CanvasItem.cs:1370 @ bool Godot.CanvasItem.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
Node2D.cs:522 @ bool Godot.Node2D.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
Camera2D.cs:908 @ bool Godot.Camera2D.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
CameraManager_ScriptMethods.generated.cs:58 @ bool CameraManager.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_variant_call_error*, Godot.NativeInterop.godot_variant*)
It says the CharacterMovement
object is missing. That’s a script attached to my Player
character. Calling FindPlayer
again after reloading the scene didn’t fix this problem. I’ve also tried this with and without the ProcessMode = ProcessModeEnum.Always
line. After reloading, I can still control the Player
character, but my camera just stays its final position before the reload, like it lost its target to track.
How do you code camera tracking around scene reloads?