summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/core_constants.cpp2
-rw-r--r--core/multiplayer/multiplayer.h2
-rw-r--r--doc/classes/@GlobalScope.xml4
-rw-r--r--doc/classes/Node.xml2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp85
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp8
-rw-r--r--scene/3d/audio_stream_player_3d.cpp3
7 files changed, 100 insertions, 6 deletions
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index a53929a3af..ea1304f5ba 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -645,7 +645,7 @@ void register_global_constants() {
// rpc
BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_DISABLED", Multiplayer::RPC_MODE_DISABLED);
BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY_PEER", Multiplayer::RPC_MODE_ANY_PEER);
- BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTH", Multiplayer::RPC_MODE_AUTHORITY);
+ BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTHORITY", Multiplayer::RPC_MODE_AUTHORITY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE", Multiplayer::TRANSFER_MODE_UNRELIABLE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE_ORDERED", Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED);
diff --git a/core/multiplayer/multiplayer.h b/core/multiplayer/multiplayer.h
index 5eb968171a..f4c965b0f8 100644
--- a/core/multiplayer/multiplayer.h
+++ b/core/multiplayer/multiplayer.h
@@ -46,7 +46,7 @@ enum TransferMode {
enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_ANY_PEER, // Any peer can call this RPC
- RPC_MODE_AUTHORITY, // / Only the node's multiplayer authority (server by default) can call this RPC
+ RPC_MODE_AUTHORITY, // Only the node's multiplayer authority (server by default) can call this RPC
};
struct RPCConfig {
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 5f81c80887..43101d6e5e 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2640,8 +2640,8 @@
<constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not.
</constant>
- <constant name="RPC_MODE_AUTH" value="2" enum="RPCMode">
- Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(auth)[/code] annotation. See [method Node.set_multiplayer_authority].
+ <constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode">
+ Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(authority)[/code] annotation. See [method Node.set_multiplayer_authority].
</constant>
<constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode">
Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index e9000d4356..966e24c537 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -637,7 +637,7 @@
<argument index="3" name="transfer_mode" type="int" enum="TransferMode" default="2" />
<argument index="4" name="channel" type="int" default="0" />
<description>
- Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum RPCMode] and [enum TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(auth)[/code]). By default, methods are not exposed to networking (and RPCs).
+ Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum RPCMode] and [enum TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(authority)[/code]). By default, methods are not exposed to networking (and RPCs).
</description>
</method>
<method name="rpc_id" qualifiers="vararg">
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 37922dd5c9..64aeb9f2a8 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -1497,6 +1497,9 @@ AudioStreamPlayer3DGizmoPlugin::AudioStreamPlayer3DGizmoPlugin() {
create_icon_material("stream_player_3d_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("Gizmo3DSamplePlayer"), SNAME("EditorIcons")));
create_material("stream_player_3d_material_primary", gizmo_color);
create_material("stream_player_3d_material_secondary", gizmo_color * Color(1, 1, 1, 0.35));
+ // Enable vertex colors for the billboard material as the gizmo color depends on the
+ // AudioStreamPlayer3D attenuation type and source (Unit Size or Max Distance).
+ create_material("stream_player_3d_material_billboard", Color(1, 1, 1), true, false, true);
create_handle_material("handles");
}
@@ -1580,6 +1583,88 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
+ if (player->get_attenuation_model() != AudioStreamPlayer3D::ATTENUATION_DISABLED || player->get_max_distance() > CMP_EPSILON) {
+ // Draw a circle to represent sound volume attenuation.
+ // Use only a billboard circle to represent radius.
+ // This helps distinguish AudioStreamPlayer3D gizmos from OmniLight3D gizmos.
+ const Ref<Material> lines_billboard_material = get_material("stream_player_3d_material_billboard", p_gizmo);
+
+ // Soft distance cap varies depending on attenuation model, as some will fade out more aggressively than others.
+ // Multipliers were empirically determined through testing.
+ float soft_multiplier;
+ switch (player->get_attenuation_model()) {
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
+ soft_multiplier = 12.0;
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
+ soft_multiplier = 4.0;
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
+ soft_multiplier = 3.25;
+ break;
+ default:
+ // Ensures Max Distance's radius visualization is not capped by Unit Size
+ // (when the attenuation mode is Disabled).
+ soft_multiplier = 10000.0;
+ break;
+ }
+
+ // Draw the distance at which the sound can be reasonably heard.
+ // This can be either a hard distance cap with the Max Distance property (if set above 0.0),
+ // or a soft distance cap with the Unit Size property (sound never reaches true zero).
+ // When Max Distance is 0.0, `r` represents the distance above which the
+ // sound can't be heard in *most* (but not all) scenarios.
+ float r;
+ if (player->get_max_distance() > CMP_EPSILON) {
+ r = MIN(player->get_unit_size() * soft_multiplier, player->get_max_distance());
+ } else {
+ r = player->get_unit_size() * soft_multiplier;
+ }
+ Vector<Vector3> points_billboard;
+
+ for (int i = 0; i < 120; i++) {
+ // Create a circle.
+ const float ra = Math::deg2rad((float)(i * 3));
+ const float rb = Math::deg2rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
+
+ // Draw a billboarded circle.
+ points_billboard.push_back(Vector3(a.x, a.y, 0));
+ points_billboard.push_back(Vector3(b.x, b.y, 0));
+ }
+
+ Color color;
+ switch (player->get_attenuation_model()) {
+ // Pick cold colors for all attenuation models (except Disabled),
+ // so that soft caps can be easily distinguished from hard caps
+ // (which use warm colors).
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
+ color = Color(0.4, 0.8, 1);
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
+ color = Color(0.4, 0.5, 1);
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
+ color = Color(0.4, 0.2, 1);
+ break;
+ default:
+ // Disabled attenuation mode.
+ // This is never reached when Max Distance is 0, but the
+ // hue-inverted form of this color will be used if Max Distance is greater than 0.
+ color = Color(1, 1, 1);
+ break;
+ }
+
+ if (player->get_max_distance() > CMP_EPSILON) {
+ // Sound is hard-capped by max distance. The attenuation model still matters,
+ // so invert the hue of the color that was chosen above.
+ color.set_h(color.get_h() + 0.5);
+ }
+
+ p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
+ }
+
if (player->is_emission_angle_enabled()) {
const float pc = player->get_emission_angle();
const float ofs = -Math::cos(Math::deg2rad(pc));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index cbdb1e520a..a0ca219c61 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -8126,7 +8126,13 @@ void Node3DEditorPlugin::edit(Object *p_object) {
}
bool Node3DEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("Node3D");
+ if (p_object->is_class("Node3D")) {
+ return true;
+ } else {
+ // This ensures that gizmos are cleared when selecting a non-Node3D node.
+ const_cast<Node3DEditorPlugin *>(this)->edit((Object *)nullptr);
+ return false;
+ }
}
Dictionary Node3DEditorPlugin::get_state() const {
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 18a9cc5c8b..7c1fb3779f 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -541,6 +541,7 @@ float AudioStreamPlayer3D::get_unit_db() const {
void AudioStreamPlayer3D::set_unit_size(float p_volume) {
unit_size = p_volume;
+ update_gizmos();
}
float AudioStreamPlayer3D::get_unit_size() const {
@@ -669,6 +670,7 @@ void AudioStreamPlayer3D::_bus_layout_changed() {
void AudioStreamPlayer3D::set_max_distance(float p_metres) {
ERR_FAIL_COND(p_metres < 0.0);
max_distance = p_metres;
+ update_gizmos();
}
float AudioStreamPlayer3D::get_max_distance() const {
@@ -729,6 +731,7 @@ float AudioStreamPlayer3D::get_attenuation_filter_db() const {
void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) {
ERR_FAIL_INDEX((int)p_model, 4);
attenuation_model = p_model;
+ update_gizmos();
}
AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const {