Repository: godotengine/godot
File: scene/3d/ray_cast_3d.cpp (C++)

Code before:
	}

	exclude_parent_body = p_exclude_parent_body;

	if (!is_inside_tree()) {
		return;
	}

	if (Object::cast_to<CollisionObject3D>(get_parent())) {
		if (exclude_parent_body) {
			exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
		} else {
			exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
		}
	}
}

bool RayCast3D::get_exclude_parent_body() const {
	return exclude_parent_body;
}

void RayCast3D::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_ENTER_TREE: {
			if (enabled && !Engine::get_singleton()->is_editor_hint()) {
				set_physics_process_internal(true);
			} else {
				set_physics_process_internal(false);
			}

			if (get_tree()->is_debugging_collisions_hint()) {
				_update_debug_shape();
			}

			if (Object::cast_to<CollisionObject3D>(get_parent())) {
				if (exclude_parent_body) {
					exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
				} else {
					exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
				}
			}

		} break;
		case NOTIFICATION_EXIT_TREE: {
			if (enabled) {
				set_physics_process_internal(false);
			}

			if (debug_shape) {
				_clear_debug_shape();
			}

Review comment (bug):
I would rather move that to the part of code that sets the color in the debug material, so the object property is not modified depending on settings. It would be also cleaner to use something like black color as the value to set the default color.

So to make things simple you could have an update method similar to the one for debug vertices, like:
```
void RayCast3D::_update_debug_shape_material(bool p_check_collision) {
	if (!debug_material.is_valid()) {
		Ref<StandardMaterial3D> line_material = memnew(StandardMaterial3D);
		line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
		line_material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);

		debug_material = line_material;
	}

	Color color = debug_shape_color;
	if (color == Color()) {
		// Use the default debug shape color defined in the Project Settings.
		color = get_tree()->get_debug_collisions_color();
	}

	if (p_check_collision && collided) {
		// Mix the base color with an highlight color to show collision.
		if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) {
			// If base color is already quite reddish, hightlight collision with a greener color
			color = Color(0.0, 1.0, 0.0, color.a);
		} else {
			// Else, hightlight collision with a more red color.
			color = Color(1.0, 0, 0, color.a);
		}
	}

	Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material);
	line_material->set_albedo(color);
}
```

`p_check_collision` can be used to use the same method to set the color on hit in-game, it would be false by default.

Code after:
void RayCast3D::set_exclude_parent_body(bool p_exclude_parent_body) {
	if (exclude_parent_body == p_exclude_parent_body) {
		return;
	}

	exclude_parent_body = p_exclude_parent_body;

	if (!is_inside_tree()) {
		return;
	}

	if (Object::cast_to<CollisionObject3D>(get_parent())) {
		if (exclude_parent_body) {
			exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
		} else {
			exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
		}
	}
}

bool RayCast3D::get_exclude_parent_body() const {
	return exclude_parent_body;
}

void RayCast3D::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_ENTER_TREE: {
			if (Engine::get_singleton()->is_editor_hint()) {
				_update_debug_shape_vertices();
			}
			if (enabled && !Engine::get_singleton()->is_editor_hint()) {
				set_physics_process_internal(true);
			} else {
				set_physics_process_internal(false);
			}

			if (get_tree()->is_debugging_collisions_hint()) {
				_update_debug_shape();
			}

			if (Object::cast_to<CollisionObject3D>(get_parent())) {
				if (exclude_parent_body) {
					exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
				} else {
					exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
				}
			}

		} break;
		case NOTIFICATION_EXIT_TREE: {
			if (enabled) {