From f69fba0d65b05bb5261742539e383febd0e57d90 Mon Sep 17 00:00:00 2001 From: Ninni Pipping Date: Sat, 4 Mar 2023 11:37:02 +0100 Subject: [PATCH] Add restrictions to MultiplayerSynchronizer editor and documentation --- .../doc_classes/MultiplayerSynchronizer.xml | 1 + .../doc_classes/SceneReplicationConfig.xml | 1 + .../multiplayer/editor/replication_editor.cpp | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml index 12a2b4ed193..8f7e9df4198 100644 --- a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml +++ b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml @@ -8,6 +8,7 @@ Visibility can be handled directly with [method set_visibility_for] or as-needed with [method add_visibility_filter] and [method update_visibility]. [MultiplayerSpawner]s will handle nodes according to visibility of synchronizers as long as the node at [member root_path] was spawned by one. Internally, [MultiplayerSynchronizer] uses [method MultiplayerAPI.object_configuration_add] to notify synchronization start passing the [Node] at [member root_path] as the [code]object[/code] and itself as the [code]configuration[/code], and uses [method MultiplayerAPI.object_configuration_remove] to notify synchronization end in a similar way. + [b]Note:[/b] Synchronization is not supported for [Object] type properties, like [Resource]. Properties that are unique to each peer, like the instance IDs of [Object]s (see [method Object.get_instance_id]) or [RID]s, will also not work in synchronization. diff --git a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml index 2c2ae385929..f1f0d158a98 100644 --- a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml +++ b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml @@ -14,6 +14,7 @@ Adds the property identified by the given [param path] to the list of the properties being synchronized, optionally passing an [param index]. + [b]Note:[/b] For details on restrictions and limitations on property synchronization, see [MultiplayerSynchronizer]. diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp index 7e70c12542c..04aa856bf98 100644 --- a/modules/multiplayer/editor/replication_editor.cpp +++ b/modules/multiplayer/editor/replication_editor.cpp @@ -195,6 +195,51 @@ ReplicationEditor::ReplicationEditor() { prop_selector = memnew(PropertySelector); add_child(prop_selector); + // Filter out properties that cannot be synchronized. + // * RIDs do not match across network. + // * Objects are too large for replication. + Vector types = { + Variant::BOOL, + Variant::INT, + Variant::FLOAT, + Variant::STRING, + + Variant::VECTOR2, + Variant::VECTOR2I, + Variant::RECT2, + Variant::RECT2I, + Variant::VECTOR3, + Variant::VECTOR3I, + Variant::TRANSFORM2D, + Variant::VECTOR4, + Variant::VECTOR4I, + Variant::PLANE, + Variant::QUATERNION, + Variant::AABB, + Variant::BASIS, + Variant::TRANSFORM3D, + Variant::PROJECTION, + + Variant::COLOR, + Variant::STRING_NAME, + Variant::NODE_PATH, + // Variant::RID, + // Variant::OBJECT, + Variant::SIGNAL, + Variant::DICTIONARY, + Variant::ARRAY, + + Variant::PACKED_BYTE_ARRAY, + Variant::PACKED_INT32_ARRAY, + Variant::PACKED_INT64_ARRAY, + Variant::PACKED_FLOAT32_ARRAY, + Variant::PACKED_FLOAT64_ARRAY, + Variant::PACKED_STRING_ARRAY, + Variant::PACKED_VECTOR2_ARRAY, + Variant::PACKED_VECTOR3_ARRAY, + Variant::PACKED_COLOR_ARRAY + }; + prop_selector->set_type_filter(types); prop_selector->connect("selected", callable_mp(this, &ReplicationEditor::_pick_node_property_selected)); HBoxContainer *hb = memnew(HBoxContainer); @@ -478,6 +523,24 @@ Ref ReplicationEditor::_get_class_icon(const Node *p_node) { return get_theme_icon(p_node->get_class(), "EditorIcons"); } +static bool can_sync(const Variant &p_var) { + switch (p_var.get_type()) { + case Variant::RID: + case Variant::OBJECT: + return false; + case Variant::ARRAY: { + const Array &arr = p_var; + if (arr.is_typed()) { + const uint32_t type = arr.get_typed_builtin(); + return (type != Variant::RID) && (type != Variant::OBJECT); + } + return true; + } + default: + return true; + } +} + void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, bool p_sync, bool p_watch) { String prop = String(p_property); TreeItem *item = tree->create_item(); @@ -499,6 +562,12 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, } item->set_text(0, String(node->get_name()) + ":" + subpath); icon = _get_class_icon(node); + bool valid = false; + Variant value = node->get(subpath, &valid); + if (valid && !can_sync(value)) { + item->set_icon(3, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); + item->set_tooltip_text(3, TTR("Property of this type not supported.")); + } } item->set_icon(0, icon); item->add_button(4, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));