-
-
Notifications
You must be signed in to change notification settings - Fork 23.4k
Closed
Milestone
Description
Tested versions
- Reproducible in 80a3d20 (the latest at time of writing available from a merged PR)
- Reproducible in fe38b57 (the build associated with the PR for FTI change)
- Not reproducible in ca15fcc (immediate preceding merged PR to FTI change)
System information
Godot v4.5.dev - Windows 11 - Single-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 (NVIDIA; 32.0.15.6094)
Issue description
I first noticed this following #104269 in my game, where I have a pool of RigidBody3D nodes that are relatively short-lived (visually), but may be added or removed from the scene tree regularly.
It seems that when allowed to exit the tree, these bodies then have some intense visual artifacts any time they come back.
2025-04-30.23-01-08.mp4
Steps to reproduce
Here's a small example of a situation I've noticed difficulty with:
extends Node;
const POOL_SIZE: int = 5;
var pool: Array[RigidBody3D] = [];
var lifetimes: PackedFloat32Array = [];
var pool_index: int = 0;
func _ready() -> void:
pool.resize(POOL_SIZE);
lifetimes.resize(POOL_SIZE);
var def: PackedScene = load("res://ball.tscn");
for i in POOL_SIZE:
pool[i] = def.instantiate();
return;
func _physics_process(delta: float) -> void:
for i in POOL_SIZE:
var ball: RigidBody3D = pool[i];
if !ball.is_inside_tree():
continue;
var lifetime: float = maxf(0.0, lifetimes[i] - delta);
lifetimes[i] = lifetime;
if (lifetime > 0.0):
continue;
ball.visible = false;
ball.freeze = true;
ball.linear_velocity = Vector3();
ball.angular_velocity = Vector3();
remove_child(ball);
return;
func get_random_vector() -> Vector3:
return Vector3(randf_range(-1.0, 1.0), randf_range(-1.0, 1.0), randf_range(-1.0, 1.0));
func add_ball() -> void:
var ball: RigidBody3D = pool[pool_index];;
ball.position = Vector3.UP * 2.5;
ball.visible = true;
ball.freeze = false;
if !ball.is_inside_tree():
add_child(ball);
ball.apply_central_impulse(get_random_vector() * 2.0);
ball.reset_physics_interpolation();
lifetimes[pool_index] = 2.0;
pool_index = wrapi(pool_index + 1, 0, POOL_SIZE);
return;
Minimal reproduction project (MRP)
lawnjelly