Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visibility_condition to allow Editor Only nodes. #77301

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/classes/CanvasItem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,9 @@
<member name="use_parent_material" type="bool" setter="set_use_parent_material" getter="get_use_parent_material" default="false">
If [code]true[/code], the parent [CanvasItem]'s [member material] property is used as this one's material.
</member>
<member name="visibility_condition" type="int" setter="set_visibility_condition" getter="get_visibility_condition" enum="CanvasItem.ConditionalVisibilityMode" default="0">
Overrides this [CanvasItem]'s visibility based upon if the project is running or in editor.
</member>
<member name="visibility_layer" type="int" setter="set_visibility_layer" getter="get_visibility_layer" default="1">
The rendering layer in which this [CanvasItem] is rendered by [Viewport] nodes. A [Viewport] will render a [CanvasItem] if it and all its parents share a layer with the [Viewport]'s canvas cull mask.
</member>
Expand Down Expand Up @@ -658,6 +661,15 @@
<constant name="NOTIFICATION_WORLD_2D_CHANGED" value="36">
The [CanvasItem]'s active [World2D] changed.
</constant>
<constant name="CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER" value="0" enum="ConditionalVisibilityMode">
The [CanvasItem] will be shown both in editor and in the running project.
</constant>
<constant name="CONDITIONAL_VISIBILITY_EDITOR_ONLY" value="1" enum="ConditionalVisibilityMode">
The [CanvasItem] will only be shown in editor.
</constant>
<constant name="CONDITIONAL_VISIBILITY_RUNNER_ONLY" value="2" enum="ConditionalVisibilityMode">
The [CanvasItem] will only be shown in the running project.
</constant>
<constant name="TEXTURE_FILTER_PARENT_NODE" value="0" enum="TextureFilter">
The [CanvasItem] will inherit the filter from its parent.
</constant>
Expand Down
12 changes: 12 additions & 0 deletions doc/classes/Node3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@
<member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)">
Local space [Transform3D] of this node, with respect to the parent node.
</member>
<member name="visibility_condition" type="int" setter="set_visibility_condition" getter="get_visibility_condition" enum="Node3D.ConditionalVisibilityMode" default="0">
Overrides this [Node3D]'s visibility based upon if the project is running or in editor.
</member>
<member name="visibility_parent" type="NodePath" setter="set_visibility_parent" getter="get_visibility_parent" default="NodePath(&quot;&quot;)">
Defines the visibility range parent for this node and its subtree. The visibility parent must be a GeometryInstance3D. Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependent instances will not take the hidden node or its ancestors into account.
</member>
Expand Down Expand Up @@ -356,5 +359,14 @@
<constant name="ROTATION_EDIT_MODE_BASIS" value="2" enum="RotationEditMode">
The rotation is edited using a [Basis]. In this mode, [member scale] can't be edited separately.
</constant>
<constant name="CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER" value="0" enum="ConditionalVisibilityMode">
The [Node3D] will be shown both in editor and in the running project.
</constant>
<constant name="CONDITIONAL_VISIBILITY_EDITOR_ONLY" value="1" enum="ConditionalVisibilityMode">
The [Node3D] will only be shown in editor.
</constant>
<constant name="CONDITIONAL_VISIBILITY_RUNNER_ONLY" value="2" enum="ConditionalVisibilityMode">
The [Node3D] will only be shown in the running project.
</constant>
</constants>
</class>
3 changes: 3 additions & 0 deletions doc/classes/SceneTree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@
If [code]true[/code], collision shapes will be visible when running the game from the editor for debugging purposes.
[b]Note:[/b] This property is not designed to be changed at run-time. Changing the value of [member debug_collisions_hint] while the project is running will not have the desired effect.
</member>
<member name="debug_editor_only_nodes_hint" type="bool" setter="set_debug_editor_only_nodes_hint" getter="is_debug_editor_only_nodes_hint" default="false">
If [code]true[/code], Nodes with their [code]visibility_condition[/code] set to "Editor Only" will be shown in the running project.
</member>
<member name="debug_navigation_hint" type="bool" setter="set_debug_navigation_hint" getter="is_debugging_navigation_hint" default="false">
If [code]true[/code], navigation polygons will be visible when running the game from the editor for debugging purposes.
[b]Note:[/b] This property is not designed to be changed at run-time. Changing the value of [member debug_navigation_hint] while the project is running will not have the desired effect.
Expand Down
5 changes: 5 additions & 0 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,18 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back(itos(OS::get_singleton()->get_process_id()));

bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false);
bool debug_editor_only_nodes = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_editor_only_nodes", false);
bool debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false);
bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
bool debug_avoidance = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_avoidance", false);
if (debug_collisions) {
args.push_back("--debug-collisions");
}

if (debug_editor_only_nodes) {
args.push_back("--debug-editor-only-nodes");
}

if (debug_paths) {
args.push_back("--debug-paths");
}
Expand Down
9 changes: 9 additions & 0 deletions editor/plugins/debugger_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) {
debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISIONS);
debug_menu->set_item_tooltip(-1,
TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project."));
debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_editor_only_nodes", TTR("Visible Editor Only Nodes")), RUN_DEBUG_EDITOR_ONLY_NODES);
debug_menu->set_item_tooltip(-1,
TTR("When this option is enabled, Nodes with visibility_condition set to Editor Only will be shown in the running project."));
debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_paths", TTR("Visible Paths")), RUN_DEBUG_PATHS);
debug_menu->set_item_tooltip(-1,
TTR("When this option is enabled, curve resources used by path nodes will be visible in the running project."));
Expand Down Expand Up @@ -158,6 +161,12 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISIONS), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisions", !ischecked);

} break;
case RUN_DEBUG_EDITOR_ONLY_NODES: {
bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_EDITOR_ONLY_NODES));
debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_EDITOR_ONLY_NODES), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_editor_only_nodes", !ischecked);

} break;
case RUN_DEBUG_PATHS: {
bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_PATHS));
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/debugger_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class DebuggerEditorPlugin : public EditorPlugin {
RUN_FILE_SERVER,
RUN_LIVE_DEBUG,
RUN_DEBUG_COLLISIONS,
RUN_DEBUG_EDITOR_ONLY_NODES,
RUN_DEBUG_PATHS,
RUN_DEBUG_NAVIGATION,
RUN_DEBUG_AVOIDANCE,
Expand Down
7 changes: 7 additions & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ static Vector2 init_custom_pos;
static bool use_debug_profiler = false;
#ifdef DEBUG_ENABLED
static bool debug_collisions = false;
static bool debug_editor_only_nodes = false;
static bool debug_paths = false;
static bool debug_navigation = false;
static bool debug_avoidance = false;
Expand Down Expand Up @@ -457,6 +458,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --single-threaded-scene Scene tree runs in single-threaded mode. Sub-thread groups are disabled and run on the main thread.\n");
#if defined(DEBUG_ENABLED)
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
OS::get_singleton()->print(" --debug-editor-only-nodes Show editor only Nodes when running the scene.\n");
OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
OS::get_singleton()->print(" --debug-avoidance Show navigation avoidance debug visuals when running the scene.\n");
Expand Down Expand Up @@ -1360,6 +1362,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#if defined(DEBUG_ENABLED)
} else if (I->get() == "--debug-collisions") {
debug_collisions = true;
} else if (I->get() == "--debug-editor-only-nodes") {
debug_editor_only_nodes = true;
} else if (I->get() == "--debug-paths") {
debug_paths = true;
} else if (I->get() == "--debug-navigation") {
Expand Down Expand Up @@ -2928,6 +2932,9 @@ bool Main::start() {
if (debug_collisions) {
sml->set_debug_collisions_hint(true);
}
if (debug_editor_only_nodes) {
sml->set_debug_editor_only_nodes_hint(true);
}
if (debug_paths) {
sml->set_debug_paths_hint(true);
}
Expand Down
43 changes: 42 additions & 1 deletion scene/3d/node_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ void Node3D::_propagate_transform_changed_deferred() {
}
}

bool Node3D::_is_visibility_condition_met() const {
const bool override_editor_only = get_tree() && get_tree()->is_debug_editor_only_nodes_hint();

switch (get_visibility_condition()) {
case CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER:
return true;
case CONDITIONAL_VISIBILITY_EDITOR_ONLY:
return Engine::get_singleton()->is_editor_hint() || override_editor_only;
case CONDITIONAL_VISIBILITY_RUNNER_ONLY:
return !Engine::get_singleton()->is_editor_hint();
default:
return true;
}
}

void Node3D::_propagate_transform_changed(Node3D *p_origin) {
if (!is_inside_tree()) {
return;
Expand Down Expand Up @@ -791,17 +806,36 @@ void Node3D::set_visible(bool p_visible) {
_propagate_visibility_changed();
}

void Node3D::set_visibility_condition(ConditionalVisibilityMode p_visibility_condition) {
ERR_MAIN_THREAD_GUARD;
if (data.visibility_condition == p_visibility_condition) {
return;
}

data.visibility_condition = p_visibility_condition;

if (!is_inside_tree()) {
return;
}
_propagate_visibility_changed();
}

bool Node3D::is_visible() const {
ERR_READ_THREAD_GUARD_V(false);
return data.visible;
}

Node3D::ConditionalVisibilityMode Node3D::get_visibility_condition() const {
ERR_READ_THREAD_GUARD_V(CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER);
return data.visibility_condition;
}

bool Node3D::is_visible_in_tree() const {
ERR_READ_THREAD_GUARD_V(false); // Since visibility can only be changed from main thread, this is safe to call.
const Node3D *s = this;

while (s) {
if (!s->data.visible) {
if (!s->data.visible || !s->_is_visibility_condition_met()) {
return false;
}
s = s->data.parent;
Expand Down Expand Up @@ -1146,6 +1180,8 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_visible_in_tree"), &Node3D::is_visible_in_tree);
ClassDB::bind_method(D_METHOD("show"), &Node3D::show);
ClassDB::bind_method(D_METHOD("hide"), &Node3D::hide);
ClassDB::bind_method(D_METHOD("get_visibility_condition"), &Node3D::get_visibility_condition);
ClassDB::bind_method(D_METHOD("set_visibility_condition", "visibility_condition"), &Node3D::set_visibility_condition);

ClassDB::bind_method(D_METHOD("set_notify_local_transform", "enable"), &Node3D::set_notify_local_transform);
ClassDB::bind_method(D_METHOD("is_local_transform_notification_enabled"), &Node3D::is_local_transform_notification_enabled);
Expand Down Expand Up @@ -1183,6 +1219,10 @@ void Node3D::_bind_methods() {
BIND_ENUM_CONSTANT(ROTATION_EDIT_MODE_QUATERNION);
BIND_ENUM_CONSTANT(ROTATION_EDIT_MODE_BASIS);

BIND_ENUM_CONSTANT(CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER);
BIND_ENUM_CONSTANT(CONDITIONAL_VISIBILITY_EDITOR_ONLY);
BIND_ENUM_CONSTANT(CONDITIONAL_VISIBILITY_RUNNER_ONLY);

ADD_GROUP("Transform", "");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NO_EDITOR), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "suffix:m", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
Expand All @@ -1201,6 +1241,7 @@ void Node3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "global_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_rotation_degrees", "get_global_rotation_degrees");
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_condition", PROPERTY_HINT_ENUM, "Editor and Runner,Editor Only,Runner Only"), "set_visibility_condition", "get_visibility_condition");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");

ADD_SIGNAL(MethodInfo("visibility_changed"));
Expand Down
12 changes: 12 additions & 0 deletions scene/3d/node_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ class Node3D : public Node {
ROTATION_EDIT_MODE_BASIS,
};

enum ConditionalVisibilityMode {
CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER,
CONDITIONAL_VISIBILITY_EDITOR_ONLY,
CONDITIONAL_VISIBILITY_RUNNER_ONLY,
};

private:
// For the sake of ease of use, Node3D can operate with Transforms (Basis+Origin), Quaternion/Scale and Euler Rotation/Scale.
// Transform and Quaternion are stored in data.local_transform Basis (so quaternion is not really stored, but converted back/forth from 3x3 matrix on demand).
Expand Down Expand Up @@ -116,6 +122,7 @@ class Node3D : public Node {
bool notify_transform = false;

bool visible = true;
ConditionalVisibilityMode visibility_condition = CONDITIONAL_VISIBILITY_EDITOR_AND_RUNNER;
bool disable_scale = false;

#ifdef TOOLS_ENABLED
Expand Down Expand Up @@ -145,6 +152,8 @@ class Node3D : public Node {
void _update_visibility_parent(bool p_update_root);
void _propagate_transform_changed_deferred();

bool _is_visibility_condition_met() const;

protected:
_FORCE_INLINE_ void set_ignore_transform_notification(bool p_ignore) { data.ignore_notification = p_ignore; }

Expand Down Expand Up @@ -266,9 +275,11 @@ class Node3D : public Node {
void set_identity();

void set_visible(bool p_visible);
void set_visibility_condition(ConditionalVisibilityMode p_visibility_condition);
void show();
void hide();
bool is_visible() const;
ConditionalVisibilityMode get_visibility_condition() const;
bool is_visible_in_tree() const;

void force_update_transform();
Expand All @@ -280,5 +291,6 @@ class Node3D : public Node {
};

VARIANT_ENUM_CAST(Node3D::RotationEditMode)
VARIANT_ENUM_CAST(Node3D::ConditionalVisibilityMode);

#endif // NODE_3D_H
Loading