summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/vector3.cpp2
-rw-r--r--core/variant/container_type_validate.h5
-rw-r--r--doc/classes/@GlobalScope.xml24
-rw-r--r--doc/classes/BaseMaterial3D.xml44
-rw-r--r--doc/classes/CameraAttributesPhysical.xml1
-rw-r--r--doc/classes/CameraAttributesPractical.xml2
-rw-r--r--doc/classes/CharacterBody2D.xml4
-rw-r--r--doc/classes/Color.xml16
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/Decal.xml4
-rw-r--r--doc/classes/DirectionalLight2D.xml1
-rw-r--r--doc/classes/DisplayServer.xml7
-rw-r--r--doc/classes/Environment.xml14
-rw-r--r--doc/classes/Light2D.xml5
-rw-r--r--doc/classes/Light3D.xml7
-rw-r--r--doc/classes/NavigationServer3D.xml9
-rw-r--r--doc/classes/NinePatchRect.xml2
-rw-r--r--doc/classes/OmniLight3D.xml1
-rw-r--r--doc/classes/ProjectSettings.xml21
-rw-r--r--doc/classes/ReflectionProbe.xml1
-rw-r--r--doc/classes/RenderingDevice.xml2
-rw-r--r--doc/classes/SpotLight3D.xml1
-rw-r--r--doc/classes/String.xml13
-rw-r--r--doc/classes/StringName.xml14
-rw-r--r--doc/classes/TextureLayered.xml2
-rw-r--r--doc/classes/VoxelGI.xml1
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp9
-rw-r--r--drivers/gles3/storage/material_storage.cpp1
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp1
-rw-r--r--editor/animation_track_editor_plugins.cpp24
-rw-r--r--editor/editor_help.cpp4
-rw-r--r--editor/editor_settings.cpp3
-rw-r--r--editor/export/editor_export_platform.cpp4
-rw-r--r--editor/export/editor_export_platform_pc.cpp3
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp7
-rw-r--r--editor/plugins/script_editor_plugin.cpp82
-rw-r--r--editor/plugins/script_editor_plugin.h18
-rw-r--r--editor/plugins/text_editor.cpp71
-rw-r--r--editor/plugins/text_editor.h2
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp11
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp28
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp11
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--modules/csg/csg_shape.cpp24
-rw-r--r--modules/csg/csg_shape.h4
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml74
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp14
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd3
-rw-r--r--modules/gltf/gltf_document.cpp1
-rw-r--r--modules/multiplayer/scene_replication_interface.cpp6
-rw-r--r--modules/navigation/godot_navigation_server.cpp2
-rw-r--r--modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml2
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp5
-rw-r--r--scene/2d/tile_map.cpp7
-rw-r--r--scene/2d/tile_map.h1
-rw-r--r--scene/3d/decal.cpp2
-rw-r--r--scene/gui/code_edit.cpp2
-rw-r--r--scene/gui/popup.cpp11
-rw-r--r--scene/main/viewport.cpp18
-rw-r--r--scene/main/window.cpp13
-rw-r--r--scene/resources/mesh.cpp3
-rw-r--r--servers/navigation_server_3d.cpp1
-rw-r--r--servers/physics_2d/godot_step_2d.cpp1
-rw-r--r--servers/physics_2d/godot_step_2d.h1
-rw-r--r--servers/physics_3d/godot_step_3d.cpp1
-rw-r--r--servers/physics_3d/godot_step_3d.h1
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp1
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp1
-rw-r--r--servers/rendering/renderer_scene_cull.cpp1
-rw-r--r--servers/rendering/renderer_viewport.cpp1
-rw-r--r--servers/rendering/rendering_server_default.h1
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--servers/rendering_server.h1
78 files changed, 482 insertions, 216 deletions
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index d732f1e8b2..ae009fc4ef 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -108,7 +108,9 @@ Vector3 Vector3::octahedron_decode(const Vector2 &p_oct) {
}
Vector2 Vector3::octahedron_tangent_encode(const float sign) const {
+ const float bias = 1.0f / 32767.0f;
Vector2 res = this->octahedron_encode();
+ res.y = MAX(res.y, bias);
res.y = res.y * 0.5f + 0.5f;
res.y = sign >= 0.0f ? res.y : 1 - res.y;
return res;
diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h
index ad679db9d0..ffe1dc90a3 100644
--- a/core/variant/container_type_validate.h
+++ b/core/variant/container_type_validate.h
@@ -73,7 +73,7 @@ struct ContainerTypeValidate {
return type != p_type.type || class_name != p_type.class_name || script != p_type.script;
}
- // Coerces String and StringName into each other when needed.
+ // Coerces String and StringName into each other and int into float when needed.
_FORCE_INLINE_ bool validate(Variant &inout_variant, const char *p_operation = "use") const {
if (type == Variant::NIL) {
return true;
@@ -89,6 +89,9 @@ struct ContainerTypeValidate {
} else if (type == Variant::STRING_NAME && inout_variant.get_type() == Variant::STRING) {
inout_variant = StringName(inout_variant);
return true;
+ } else if (type == Variant::FLOAT && inout_variant.get_type() == Variant::INT) {
+ inout_variant = (float)inout_variant;
+ return true;
}
ERR_FAIL_V_MSG(false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(inout_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'.");
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 55810156a1..d5280cb548 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -803,7 +803,8 @@
Returns the result of [param base] raised to the power of [param exp].
In GDScript, this is the equivalent of the [code]**[/code] operator.
[codeblock]
- pow(2, 5) # Returns 32
+ pow(2, 5) # Returns 32.0
+ pow(4, 1.5) # Returns 8.0
[/codeblock]
</description>
</method>
@@ -1287,14 +1288,14 @@
Converts a formatted [param string] that was returned by [method var_to_str] to the original [Variant].
[codeblocks]
[gdscript]
- var a = '{ "a": 1, "b": 2 }' # a is a String
- var b = str_to_var(a) # b is a Dictionary
- print(b["a"]) # Prints 1
+ var data = '{ "a": 1, "b": 2 }' # data is a String
+ var dict = str_to_var(data) # dict is a Dictionary
+ print(dict["a"]) # Prints 1
[/gdscript]
[csharp]
- string a = "{ \"a\": 1, \"b\": 2 }"; // a is a string
- var b = GD.StrToVar(a).AsGodotDictionary(); // b is a Dictionary
- GD.Print(b["a"]); // Prints 1
+ string data = "{ \"a\": 1, \"b\": 2 }"; // data is a string
+ var dict = GD.StrToVar(data).AsGodotDictionary(); // dict is a Dictionary
+ GD.Print(dict["a"]); // Prints 1
[/csharp]
[/codeblocks]
</description>
@@ -2272,7 +2273,7 @@
Command (on macOS) or Meta/Windows key mask.
</constant>
<constant name="KEY_MASK_CTRL" value="268435456" enum="KeyModifierMask" is_bitfield="true">
- Ctrl key mask.
+ Control key mask.
</constant>
<constant name="KEY_MASK_KPAD" value="536870912" enum="KeyModifierMask" is_bitfield="true">
Keypad key mask.
@@ -2293,10 +2294,10 @@
Middle mouse button.
</constant>
<constant name="MOUSE_BUTTON_WHEEL_UP" value="4" enum="MouseButton">
- Mouse wheel up.
+ Mouse wheel scrolling up.
</constant>
<constant name="MOUSE_BUTTON_WHEEL_DOWN" value="5" enum="MouseButton">
- Mouse wheel down.
+ Mouse wheel scrolling down.
</constant>
<constant name="MOUSE_BUTTON_WHEEL_LEFT" value="6" enum="MouseButton">
Mouse wheel left button (only present on some mice).
@@ -2760,6 +2761,7 @@
Hints that a string property is a password, and every character is replaced with the secret character.
</constant>
<constant name="PROPERTY_HINT_MAX" value="37" enum="PropertyHint">
+ Represents the size of the [enum PropertyHint] enum.
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true">
The property is not stored, and does not display in the editor. This is the default for non-exported properties.
@@ -2818,7 +2820,7 @@
When duplicating a resource with [method Resource.duplicate], and this flag is set on a property of that resource, the property should never be duplicated, regardless of the [code]subresources[/code] bool parameter.
</constant>
<constant name="PROPERTY_USAGE_HIGH_END_GFX" value="2097152" enum="PropertyUsageFlags" is_bitfield="true">
- The property is only shown in the editor if modern renderers are supported (GLES3 is excluded).
+ The property is only shown in the editor if modern renderers are supported (the Compatibility rendering method is excluded).
</constant>
<constant name="PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT" value="4194304" enum="PropertyUsageFlags" is_bitfield="true">
</constant>
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 60225275f3..e72aa373f7 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -215,10 +215,11 @@
If [code]true[/code], the object is rendered at the same size regardless of distance.
</member>
<member name="grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled" default="false">
- If [code]true[/code], enables the vertex grow setting. See [member grow_amount].
+ If [code]true[/code], enables the vertex grow setting. This can be used to create mesh-based outlines using a second material pass and its [member cull_mode] set to [constant CULL_FRONT]. See also [member grow_amount].
+ [b]Note:[/b] Vertex growth cannot create new vertices, which means that visible gaps may occur in sharp corners. This can be alleviated by designing the mesh to use smooth normals exclusively using [url=https://wiki.polycount.com/wiki/Face_weighted_normals]face weighted normals[/url] in the 3D authoring software. In this case, grow will be able to join every outline together, just like in the original mesh.
</member>
<member name="grow_amount" type="float" setter="set_grow" getter="get_grow" default="0.0">
- Grows object vertices in the direction of their normals.
+ Grows object vertices in the direction of their normals. Only effective if [member grow] is [code]true[/code].
</member>
<member name="heightmap_deep_parallax" type="bool" setter="set_heightmap_deep_parallax" getter="is_heightmap_deep_parallax_enabled" default="false">
If [code]true[/code], uses parallax occlusion mapping to represent depth in the material instead of simple offset mapping (see [member heightmap_enabled]). This results in a more convincing depth effect, but is much more expensive on the GPU. Only enable this on materials where it makes a significant visual difference.
@@ -277,7 +278,7 @@
If [code]true[/code], depth testing is disabled and the object will be drawn in render order.
</member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
- If [code]true[/code], normal mapping is enabled.
+ If [code]true[/code], normal mapping is enabled. This has a slight performance cost, especially on mobile GPUs.
</member>
<member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale" default="1.0">
The strength of the normal map's effect.
@@ -344,7 +345,8 @@
Specifies the channel of the [member roughness_texture] in which the roughness information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
<member name="shading_mode" type="int" setter="set_shading_mode" getter="get_shading_mode" enum="BaseMaterial3D.ShadingMode" default="1">
- Sets whether the shading takes place per-pixel or per-vertex. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel.
+ Sets whether the shading takes place, per-pixel, per-vertex or unshaded. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel. Unshaded rendering is the fastest, but disables all interactions with lights.
+ [b]Note:[/b] Setting the shading mode vertex shading currently has no effect, as vertex shading is not implemented yet.
</member>
<member name="shadow_to_opacity" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], enables the "shadow to opacity" render mode where lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR.
@@ -388,7 +390,7 @@
Repeat flags for the texture. See [enum TextureFilter] for options.
</member>
<member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0">
- If [code]true[/code], transparency is enabled on the body. See also [member blend_mode].
+ If [code]true[/code], transparency is enabled on the body. Some transparency modes will disable shadow casting. Any transparency mode other than Disabled has a greater performance impact compared to opaque rendering. See also [member blend_mode].
</member>
<member name="use_particle_trails" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], enables parts of the shader required for [GPUParticles3D] trails to function. This also requires using a mesh with appropriate skinning, such as [RibbonTrailMesh] or [TubeTrailMesh]. Enabling this feature outside of materials used in [GPUParticles3D] meshes will break material rendering.
@@ -431,7 +433,7 @@
</member>
<member name="vertex_color_is_srgb" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], vertex colors are considered to be stored in sRGB color space and are converted to linear color space during rendering. If [code]false[/code], vertex colors are considered to be stored in linear color space and are rendered as-is. See also [member albedo_texture_force_srgb].
- [b]Note:[/b] Only effective when using the Vulkan Clustered or Vulkan Mobile backends.
+ [b]Note:[/b] Only effective when using the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="vertex_color_use_as_albedo" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the vertex color is used as albedo color.
@@ -523,31 +525,31 @@
Use [code]UV2[/code] with the detail texture.
</constant>
<constant name="TRANSPARENCY_DISABLED" value="0" enum="Transparency">
- The material will not use transparency.
+ The material will not use transparency. This is the fastest to render.
</constant>
<constant name="TRANSPARENCY_ALPHA" value="1" enum="Transparency">
- The material will use the texture's alpha values for transparency.
+ The material will use the texture's alpha values for transparency. This is the slowest to render, and disables shadow casting.
</constant>
<constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency">
- The material will cut off all values below a threshold, the rest will remain opaque. The opaque portions will be rendered in the depth prepass.
+ The material will cut off all values below a threshold, the rest will remain opaque. The opaque portions will be rendered in the depth prepass. This is faster to render than alpha blending, but slower than opaque rendering. This also supports casting shadows.
</constant>
<constant name="TRANSPARENCY_ALPHA_HASH" value="3" enum="Transparency">
- The material will cut off all values below a spatially-deterministic threshold, the rest will remain opaque.
+ The material will cut off all values below a spatially-deterministic threshold, the rest will remain opaque. This is faster to render than alpha blending, but slower than opaque rendering. This also supports casting shadows. Alpha hashing is suited for hair rendering.
</constant>
<constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="4" enum="Transparency">
- The material will use the texture's alpha value for transparency, but will discard fragments with an alpha of less than 0.99 during the depth prepass and fragments with an alpha less than 0.1 during the shadow pass.
+ The material will use the texture's alpha value for transparency, but will discard fragments with an alpha of less than 0.99 during the depth prepass and fragments with an alpha less than 0.1 during the shadow pass. This also supports casting shadows.
</constant>
<constant name="TRANSPARENCY_MAX" value="5" enum="Transparency">
Represents the size of the [enum Transparency] enum.
</constant>
<constant name="SHADING_MODE_UNSHADED" value="0" enum="ShadingMode">
- The object will not receive shadows.
+ The object will not receive shadows. This is the fastest to render, but it disables all interactions with lights.
</constant>
<constant name="SHADING_MODE_PER_PIXEL" value="1" enum="ShadingMode">
- The object will be shaded per pixel. Useful for realistic shading effect.
+ The object will be shaded per pixel. Useful for realistic shading effects.
</constant>
<constant name="SHADING_MODE_PER_VERTEX" value="2" enum="ShadingMode">
- The object will be shaded per vertex. Useful when you want cheaper shaders and do not care about visual quality.
+ The object will be shaded per vertex. Useful when you want cheaper shaders and do not care about visual quality. Not implemented yet (this mode will act like [constant SHADING_MODE_PER_PIXEL]).
</constant>
<constant name="SHADING_MODE_MAX" value="3" enum="ShadingMode">
Represents the size of the [enum ShadingMode] enum.
@@ -623,13 +625,13 @@
Objects will not write their depth to the depth buffer, even during the depth prepass (if enabled).
</constant>
<constant name="CULL_BACK" value="0" enum="CullMode">
- Default cull mode. The back of the object is culled when not visible. Back face triangles will be culled when facing the camera. This results in only the front side of triangles being drawn. For closed-surface meshes this means that only the exterior of the mesh will be visible.
+ Default cull mode. The back of the object is culled when not visible. Back face triangles will be culled when facing the camera. This results in only the front side of triangles being drawn. For closed-surface meshes, this means that only the exterior of the mesh will be visible.
</constant>
<constant name="CULL_FRONT" value="1" enum="CullMode">
- Front face triangles will be culled when facing the camera. This results in only the back side of triangles being drawn. For closed-surface meshes this means that the interior of the mesh will be drawn instead of the exterior.
+ Front face triangles will be culled when facing the camera. This results in only the back side of triangles being drawn. For closed-surface meshes, this means that the interior of the mesh will be drawn instead of the exterior.
</constant>
<constant name="CULL_DISABLED" value="2" enum="CullMode">
- No culling is performed.
+ No face culling is performed; both the front face and back face will be visible.
</constant>
<constant name="FLAG_DISABLE_DEPTH_TEST" value="0" enum="Flags">
Disables the depth test, so this object is drawn on top of all others drawn before it. This puts the object in the transparent draw pass where it is sorted based on distance to camera. Objects drawn after it in the draw order may cover it. This also disables writing to depth.
@@ -639,7 +641,7 @@
</constant>
<constant name="FLAG_SRGB_VERTEX_COLOR" value="2" enum="Flags">
Vertex colors are considered to be stored in sRGB color space and are converted to linear color space during rendering. See also [member vertex_color_is_srgb].
- [b]Note:[/b] Only effective when using the Vulkan Clustered or Vulkan Mobile backends.
+ [b]Note:[/b] Only effective when using the Forward+ and Mobile rendering methods.
</constant>
<constant name="FLAG_USE_POINT_SIZE" value="3" enum="Flags">
Uses point size to alter the size of primitive points. Also changes the albedo texture lookup to use [code]POINT_COORD[/code] instead of [code]UV[/code].
@@ -717,7 +719,7 @@
Toon blob which changes size based on roughness.
</constant>
<constant name="SPECULAR_DISABLED" value="2" enum="SpecularMode">
- No specular blob.
+ No specular blob. This is slightly faster to render than other specular modes.
</constant>
<constant name="BILLBOARD_DISABLED" value="0" enum="BillboardMode">
Billboard mode is disabled.
@@ -760,10 +762,10 @@
Smoothly fades the object out based on each pixel's distance from the camera using the alpha channel.
</constant>
<constant name="DISTANCE_FADE_PIXEL_DITHER" value="2" enum="DistanceFadeMode">
- Smoothly fades the object out based on each pixel's distance from the camera using a dither approach. Dithering discards pixels based on a set pattern to smoothly fade without enabling transparency. On certain hardware this can be faster than [constant DISTANCE_FADE_PIXEL_ALPHA].
+ Smoothly fades the object out based on each pixel's distance from the camera using a dithering approach. Dithering discards pixels based on a set pattern to smoothly fade without enabling transparency. On certain hardware, this can be faster than [constant DISTANCE_FADE_PIXEL_ALPHA].
</constant>
<constant name="DISTANCE_FADE_OBJECT_DITHER" value="3" enum="DistanceFadeMode">
- Smoothly fades the object out based on the object's distance from the camera using a dither approach. Dithering discards pixels based on a set pattern to smoothly fade without enabling transparency. On certain hardware this can be faster than [constant DISTANCE_FADE_PIXEL_ALPHA].
+ Smoothly fades the object out based on the object's distance from the camera using a dithering approach. Dithering discards pixels based on a set pattern to smoothly fade without enabling transparency. On certain hardware, this can be faster than [constant DISTANCE_FADE_PIXEL_ALPHA] and [constant DISTANCE_FADE_PIXEL_DITHER].
</constant>
</constants>
</class>
diff --git a/doc/classes/CameraAttributesPhysical.xml b/doc/classes/CameraAttributesPhysical.xml
index a61e735932..9512fd11a8 100644
--- a/doc/classes/CameraAttributesPhysical.xml
+++ b/doc/classes/CameraAttributesPhysical.xml
@@ -7,6 +7,7 @@
[CameraAttributesPhysical] is used to set rendering settings based on a physically-based camera's settings. It is responsible for exposure, auto-exposure, and depth of field.
When used in a [WorldEnvironment] it provides default settings for exposure, auto-exposure, and depth of field that will be used by all cameras without their own [CameraAttributes], including the editor camera. When used in a [Camera3D] it will override any [CameraAttributes] set in the [WorldEnvironment] and will override the [Camera3D]s [member Camera3D.far], [member Camera3D.near], [member Camera3D.fov], and [member Camera3D.keep_aspect] properties. When used in [VoxelGI] or [LightmapGI], only the exposure settings will be used.
The default settings are intended for use in an outdoor environment, tips for settings for use in an indoor environment can be found in each setting's documentation.
+ [b]Note:[/b] Depth of field blur is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CameraAttributesPractical.xml b/doc/classes/CameraAttributesPractical.xml
index 924b02fc79..cd914c9eb7 100644
--- a/doc/classes/CameraAttributesPractical.xml
+++ b/doc/classes/CameraAttributesPractical.xml
@@ -24,6 +24,7 @@
</member>
<member name="dof_blur_far_enabled" type="bool" setter="set_dof_blur_far_enabled" getter="is_dof_blur_far_enabled" default="false">
Enables depth of field blur for objects further than [member dof_blur_far_distance]. Strength of blur is controlled by [member dof_blur_amount] and modulated by [member dof_blur_far_transition].
+ [b]Note:[/b] Depth of field blur is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="dof_blur_far_transition" type="float" setter="set_dof_blur_far_transition" getter="get_dof_blur_far_transition" default="5.0">
When positive, distance over which (starting from [member dof_blur_far_distance]) blur effect will scale from 0 to [member dof_blur_amount]. When negative, uses physically-based scaling so depth of field effect will scale from 0 at [member dof_blur_far_distance] and will increase in a physically accurate way as objects get further from the [Camera3D].
@@ -33,6 +34,7 @@
</member>
<member name="dof_blur_near_enabled" type="bool" setter="set_dof_blur_near_enabled" getter="is_dof_blur_near_enabled" default="false">
Enables depth of field blur for objects closer than [member dof_blur_near_distance]. Strength of blur is controlled by [member dof_blur_amount] and modulated by [member dof_blur_near_transition].
+ [b]Note:[/b] Depth of field blur is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="dof_blur_near_transition" type="float" setter="set_dof_blur_near_transition" getter="get_dof_blur_near_transition" default="1.0">
When positive, distance over which blur effect will scale from 0 to [member dof_blur_amount], ending at [member dof_blur_near_distance]. When negative, uses physically-based scaling so depth of field effect will scale from 0 at [member dof_blur_near_distance] and will increase in a physically accurate way as objects get closer to the [Camera3D].
diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml
index 7395556d05..51cc752cae 100644
--- a/doc/classes/CharacterBody2D.xml
+++ b/doc/classes/CharacterBody2D.xml
@@ -71,10 +71,10 @@
print("Collided with: ", collision.collider.name)
[/gdscript]
[csharp]
- for (int i = 0; i &lt; GetSlideCount(); i++)
+ for (int i = 0; i &lt; GetSlideCollisionCount(); i++)
{
KinematicCollision2D collision = GetSlideCollision(i);
- GD.Print("Collided with: ", (collision.Collider as Node).Name);
+ GD.Print("Collided with: ", (collision.GetCollider() as Node).Name);
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index cee0e3ef7d..faa658971d 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -203,18 +203,18 @@
<return type="Color" />
<param index="0" name="hex" type="int" />
<description>
- Returns the [Color] associated with the provided [param hex] integer in 32-bit ARGB format (8 bits per channel, alpha channel first).
+ Returns the [Color] associated with the provided [param hex] integer in 32-bit RGBA format (8 bits per channel, alpha channel first).
In GDScript and C#, the [int] is best visualized with hexadecimal notation ([code]"0x"[/code] prefix).
[codeblocks]
[gdscript]
- var red = Color.hex(0xffff0000)
- var dark_cyan = Color.hex(0xff008b8b)
- var my_color = Color.hex(0xa4bbefd2)
+ var red = Color.hex(0xff0000ff)
+ var dark_cyan = Color.hex(0x008b8bff)
+ var my_color = Color.hex(0xbbefd2a4)
[/gdscript]
[csharp]
- var red = new Color(0xffff0000);
- var dark_cyan = new Color(0xff008b8b);
- var my_color = new Color(0xa4bbefd2);
+ var red = new Color(0xff0000ff);
+ var dark_cyan = new Color(0x008b8bff);
+ var my_color = new Color(0xbbefd2a4);
[/csharp]
[/codeblocks]
</description>
@@ -223,7 +223,7 @@
<return type="Color" />
<param index="0" name="hex" type="int" />
<description>
- Returns the [Color] associated with the provided [param hex] integer in 64-bit ARGB format (16 bits per channel, alpha channel first).
+ Returns the [Color] associated with the provided [param hex] integer in 64-bit RGBA format (16 bits per channel, alpha channel first).
In GDScript and C#, the [int] is best visualized with hexadecimal notation ([code]"0x"[/code] prefix).
</description>
</method>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 41c5b4fbe2..f45ddf2738 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -558,7 +558,7 @@
<return type="void" />
<description>
Steal the focus from another control and become the focused control (see [member focus_mode]).
- [b]Note[/b]: Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
+ [b]Note:[/b] Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
</description>
</method>
<method name="has_focus" qualifiers="const">
diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml
index b63f6e7252..ddfa64891d 100644
--- a/doc/classes/Decal.xml
+++ b/doc/classes/Decal.xml
@@ -8,6 +8,7 @@
They are made of an [AABB] and a group of [Texture2D]s specifying [Color], normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals are projected within their [AABB] so altering the orientation of the Decal affects the direction in which they are projected. By default, Decals are projected down (i.e. from positive Y to negative Y).
The [Texture2D]s associated with the Decal are automatically stored in a texture atlas which is used for drawing the decals so all decals can be drawn at once. Godot uses clustered decals, meaning they are stored in cluster data and drawn when the mesh is drawn, they are not drawn as a post-processing effect after.
[b]Note:[/b] Decals cannot affect an underlying material's transparency, regardless of its transparency mode (alpha blend, alpha scissor, alpha hash, opaque pre-pass). This means translucent or transparent areas of a material will remain translucent or transparent even if an opaque decal is applied on them.
+ [b]Note:[/b] Decals are only supported in the Forward+ and Mobile rendering methods, not Compatibility. When using the Mobile rendering method, only 8 decals can be displayed on each mesh resource. Attempting to display more than 8 decals on a single mesh resource will result in decals flickering in and out as the camera moves.
[b]Note:[/b] When using the Mobile rendering method, decals will only correctly affect meshes whose visibility AABB intersects with the decal's AABB. If using a shader to deform the mesh in a way that makes it go outside its AABB, [member GeometryInstance3D.extra_cull_margin] must be increased on the mesh. Otherwise, the decal may not be visible on the mesh.
</description>
<tutorials>
@@ -87,7 +88,8 @@
[b]Note:[/b] Setting [member normal_fade] to a value greater than [code]0.0[/code] has a small performance cost due to the added normal angle computations.
</member>
<member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(2, 2, 2)">
- Sets the size of the [AABB] used by the decal. The AABB goes from [code]-size/2[/code] to [code]size/2[/code].
+ Sets the size of the [AABB] used by the decal. All dimensions must be set to a value greater than zero (they will be clamped to [code]0.001[/code] if this is not the case). The AABB goes from [code]-size/2[/code] to [code]size/2[/code].
+ [b]Note:[/b] To improve culling efficiency of "hard surface" decals, set their [member upper_fade] and [member lower_fade] to [code]0.0[/code] and set the Y component of the [member size] as low as possible. This will reduce the decals' AABB size without affecting their appearance.
</member>
<member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
diff --git a/doc/classes/DirectionalLight2D.xml b/doc/classes/DirectionalLight2D.xml
index f825a9e082..eb710efda2 100644
--- a/doc/classes/DirectionalLight2D.xml
+++ b/doc/classes/DirectionalLight2D.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A directional light is a type of [Light2D] node that models an infinite number of parallel rays covering the entire scene. It is used for lights with strong intensity that are located far away from the scene (for example: to model sunlight or moonlight).
+ [b]Note:[/b] [DirectionalLight2D] does not support light cull masks (but it supports shadow cull masks). It will always light up 2D nodes, regardless of the 2D node's [member CanvasItem.light_mask].
</description>
<tutorials>
<link title="2D lights and shadows">$DOCS_URL/tutorials/2d/2d_lights_and_shadows.html</link>
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 8d2bbc4d29..fc5de1b771 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -1453,6 +1453,7 @@
Sets the V-Sync mode of the given window. See also [member ProjectSettings.display/window/vsync/vsync_mode].
See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
Depending on the platform and used renderer, the engine will fall back to [constant VSYNC_ENABLED] if the desired mode is not supported.
+ [b]Note:[/b] V-Sync modes other than [constant VSYNC_ENABLED] are only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</description>
</method>
<method name="window_set_window_buttons_offset">
@@ -1744,17 +1745,17 @@
[b]Note:[/b] This flag is implemented on macOS.
</constant>
<constant name="VSYNC_DISABLED" value="0" enum="VSyncMode">
- No vertical synchronization, which means the engine will display frames as fast as possible (tearing may be visible). Framerate is unlimited (nonwithstanding [member Engine.max_fps]).
+ No vertical synchronization, which means the engine will display frames as fast as possible (tearing may be visible). Framerate is unlimited (nonwithstanding [member Engine.max_fps]). Not supported when using the Compatibility rendering method.
</constant>
<constant name="VSYNC_ENABLED" value="1" enum="VSyncMode">
Default vertical synchronization mode, the image is displayed only on vertical blanking intervals (no tearing is visible). Framerate is limited by the monitor refresh rate (nonwithstanding [member Engine.max_fps]).
</constant>
<constant name="VSYNC_ADAPTIVE" value="2" enum="VSyncMode">
- Behaves like [constant VSYNC_DISABLED] when the framerate drops below the screen's refresh rate to reduce stuttering (tearing may be visible). Otherwise, vertical synchronization is enabled to avoid tearing. Framerate is limited by the monitor refresh rate (nonwithstanding [member Engine.max_fps]).
+ Behaves like [constant VSYNC_DISABLED] when the framerate drops below the screen's refresh rate to reduce stuttering (tearing may be visible). Otherwise, vertical synchronization is enabled to avoid tearing. Framerate is limited by the monitor refresh rate (nonwithstanding [member Engine.max_fps]). Not supported when using the Compatibility rendering method.
</constant>
<constant name="VSYNC_MAILBOX" value="3" enum="VSyncMode">
Displays the most recent image in the queue on vertical blanking intervals, while rendering to the other images (no tearing is visible). Framerate is unlimited (nonwithstanding [member Engine.max_fps]).
- Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag (also called "Fast" V-Sync mode). [constant VSYNC_MAILBOX] works best when at least twice as many frames as the display refresh rate are rendered.
+ Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag (also called "Fast" V-Sync mode). [constant VSYNC_MAILBOX] works best when at least twice as many frames as the display refresh rate are rendered. Not supported when using the Compatibility rendering method.
</constant>
<constant name="DISPLAY_HANDLE" value="0" enum="HandleType">
Display handle:
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 33b6a786ae..7ee1f2dfd4 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -46,6 +46,7 @@
</member>
<member name="adjustment_enabled" type="bool" setter="set_adjustment_enabled" getter="is_adjustment_enabled" default="false">
If [code]true[/code], enables the [code]adjustment_*[/code] properties provided by this resource. If [code]false[/code], modifications to the [code]adjustment_*[/code] properties will have no effect on the rendered scene.
+ [b]Note:[/b] Adjustments are only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="adjustment_saturation" type="float" setter="set_adjustment_saturation" getter="get_adjustment_saturation" default="1.0">
The global color saturation value of the rendered scene (default value is 1). Effective only if [code]adjustment_enabled[/code] is [code]true[/code].
@@ -118,6 +119,7 @@
</member>
<member name="glow_enabled" type="bool" setter="set_glow_enabled" getter="is_glow_enabled" default="false">
If [code]true[/code], the glow effect is enabled.
+ [b]Note:[/b] Glow is only supported in the Forward+ and Mobile rendering methods, not Compatibility. When using the Mobile rendering method, glow will look different due to the lower dynamic range available in the Mobile rendering method.
</member>
<member name="glow_hdr_luminance_cap" type="float" setter="set_glow_hdr_luminance_cap" getter="get_glow_hdr_luminance_cap" default="12.0">
The higher threshold of the HDR glow. Areas brighter than this threshold will be clamped for the purposes of the glow effect.
@@ -126,10 +128,10 @@
The bleed scale of the HDR glow.
</member>
<member name="glow_hdr_threshold" type="float" setter="set_glow_hdr_bleed_threshold" getter="get_glow_hdr_bleed_threshold" default="1.0">
- The lower threshold of the HDR glow. When using the OpenGL renderer (which doesn't support HDR), this needs to be below [code]1.0[/code] for glow to be visible. A value of [code]0.9[/code] works well in this case.
+ The lower threshold of the HDR glow. When using the Mobile rendering method (which only supports a lower dynamic range up to [code]2.0[/code]), this may need to be below [code]1.0[/code] for glow to be visible. A value of [code]0.9[/code] works well in this case. This value also needs to be decreased below [code]1.0[/code] when using glow in 2D, as 2D rendering is performed in SDR.
</member>
<member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" default="0.8">
- The overall brightness multiplier of the glow effect. When using the OpenGL renderer, this should be increased to [code]1.5[/code] to compensate for the lack of HDR rendering.
+ The overall brightness multiplier of the glow effect. When using the Mobile rendering method (which only supports a lower dynamic range up to [code]2.0[/code]), this should be increased to [code]1.5[/code] to compensate.
</member>
<member name="glow_levels/1" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
The intensity of the 1st level of glow. This is the most "local" level (least blurry).
@@ -166,7 +168,7 @@
If [code]true[/code], glow levels will be normalized so that summed together their intensities equal [code]1.0[/code].
</member>
<member name="glow_strength" type="float" setter="set_glow_strength" getter="get_glow_strength" default="1.0">
- The strength of the glow effect. This applies as the glow is blurred across the screen and increases the distance and intensity of the blur. When using the OpenGL renderer, this should be increased to 1.3 to compensate for the lack of HDR rendering.
+ The strength of the glow effect. This applies as the glow is blurred across the screen and increases the distance and intensity of the blur. When using the Mobile rendering method, this should be increased to compensate for the lower dynamic range.
</member>
<member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0">
The reflected (specular) light source.
@@ -184,6 +186,7 @@
</member>
<member name="sdfgi_enabled" type="bool" setter="set_sdfgi_enabled" getter="is_sdfgi_enabled" default="false">
If [code]true[/code], enables signed distance field global illumination for meshes that have their [member GeometryInstance3D.gi_mode] set to [constant GeometryInstance3D.GI_MODE_STATIC]. SDFGI is a real-time global illumination technique that works well with procedurally generated and user-built levels, including in situations where geometry is created during gameplay. The signed distance field is automatically generated around the camera as it moves. Dynamic lights are supported, but dynamic occluders and emissive surfaces are not.
+ [b]Note:[/b] SDFGI is only supported in the Forward+ rendering method, not Mobile or Compatibility.
[b]Performance:[/b] SDFGI is relatively demanding on the GPU and is not suited to low-end hardware such as integrated graphics (consider [LightmapGI] instead). To improve SDFGI performance, enable [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution] in the Project Settings.
[b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh.
</member>
@@ -230,6 +233,7 @@
</member>
<member name="ssao_enabled" type="bool" setter="set_ssao_enabled" getter="is_ssao_enabled" default="false">
If [code]true[/code], the screen-space ambient occlusion effect is enabled. This darkens objects' corners and cavities to simulate ambient light not reaching the entire object as in real life. This works well for small, dynamic objects, but baked lighting or ambient occlusion textures will do a better job at displaying ambient occlusion on large static objects. Godot uses a form of SSAO called Adaptive Screen Space Ambient Occlusion which is itself a form of Horizon Based Ambient Occlusion.
+ [b]Note:[/b] SSAO is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="ssao_horizon" type="float" setter="set_ssao_horizon" getter="get_ssao_horizon" default="0.06">
The threshold for considering whether a given point on a surface is occluded or not represented as an angle from the horizon mapped into the [code]0.0-1.0[/code] range. A value of [code]1.0[/code] results in no occlusion.
@@ -251,6 +255,7 @@
</member>
<member name="ssil_enabled" type="bool" setter="set_ssil_enabled" getter="is_ssil_enabled" default="false">
If [code]true[/code], the screen-space indirect lighting effect is enabled. Screen space indirect lighting is a form of indirect lighting that allows diffuse light to bounce between nearby objects. Screen-space indirect lighting works very similarly to screen-space ambient occlusion, in that it only affects a limited range. It is intended to be used along with a form of proper global illumination like SDFGI or [VoxelGI]. Screen-space indirect lighting is not affected by individual light's [member Light3D.light_indirect_energy].
+ [b]Note:[/b] SSIL is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="ssil_intensity" type="float" setter="set_ssil_intensity" getter="get_ssil_intensity" default="1.0">
The brightness multiplier for the screen-space indirect lighting effect. A higher value will result in brighter light.
@@ -269,6 +274,7 @@
</member>
<member name="ssr_enabled" type="bool" setter="set_ssr_enabled" getter="is_ssr_enabled" default="false">
If [code]true[/code], screen-space reflections are enabled. Screen-space reflections are more accurate than reflections from [VoxelGI]s or [ReflectionProbe]s, but are slower and can't reflect surfaces occluded by others.
+ [b]Note:[/b] SSR is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="ssr_fade_in" type="float" setter="set_ssr_fade_in" getter="get_ssr_fade_in" default="0.15">
The fade-in distance for screen-space reflections. Affects the area from the reflected material to the screen-space reflection). Only positive values are valid (negative values will be clamped to [code]0.0[/code]).
@@ -314,7 +320,7 @@
</member>
<member name="volumetric_fog_enabled" type="bool" setter="set_volumetric_fog_enabled" getter="is_volumetric_fog_enabled" default="false">
Enables the volumetric fog effect. Volumetric fog uses a screen-aligned froxel buffer to calculate accurate volumetric scattering in the short to medium range. Volumetric fog interacts with [FogVolume]s and lights to calculate localized and global fog. Volumetric fog uses a PBR single-scattering model based on extinction, scattering, and emission which it exposes to users as density, albedo, and emission.
- [b]Note:[/b] Volumetric fog is only available in the forward plus renderer. It is not available in the mobile renderer or the compatibility renderer.
+ [b]Note:[/b] Volumetric fog is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="volumetric_fog_gi_inject" type="float" setter="set_volumetric_fog_gi_inject" getter="get_volumetric_fog_gi_inject" default="1.0">
Scales the strength of Global Illumination used in the volumetric fog's albedo color. A value of [code]0.0[/code] means that Global Illumination will not impact the volumetric fog. [member volumetric_fog_gi_inject] has a small performance cost when set above [code]0.0[/code].
diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml
index 062d532464..9f1b1af60d 100644
--- a/doc/classes/Light2D.xml
+++ b/doc/classes/Light2D.xml
@@ -41,7 +41,8 @@
The Light2D's energy value. The larger the value, the stronger the light.
</member>
<member name="range_item_cull_mask" type="int" setter="set_item_cull_mask" getter="get_item_cull_mask" default="1">
- The layer mask. Only objects with a matching mask will be affected by the Light2D.
+ The layer mask. Only objects with a matching [member CanvasItem.light_mask] will be affected by the Light2D. See also [member shadow_item_cull_mask], which affects which objects can cast shadows.
+ [b]Note:[/b] [member range_item_cull_mask] is ignored by [DirectionalLight2D], which will always light a 2D node regardless of the 2D node's [member CanvasItem.light_mask].
</member>
<member name="range_layer_max" type="int" setter="set_layer_range_max" getter="get_layer_range_max" default="0">
Maximum layer value of objects that are affected by the Light2D.
@@ -68,7 +69,7 @@
Smoothing value for shadows. Higher values will result in softer shadows, at the cost of visible streaks that can appear in shadow rendering. [member shadow_filter_smooth] only has an effect if [member shadow_filter] is [constant SHADOW_FILTER_PCF5] or [constant SHADOW_FILTER_PCF13].
</member>
<member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask" default="1">
- The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching light mask will cast shadows.
+ The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching [member CanvasItem.light_mask] will cast shadows. See also [member range_item_cull_mask], which affects which objects can [i]receive[/i] the light.
</member>
</members>
<constants>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 95c39d535e..2a0b2da46c 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -54,8 +54,9 @@
If [code]true[/code], the light only appears in the editor and will not be visible at runtime.
</member>
<member name="light_angular_distance" type="float" setter="set_param" getter="get_param" default="0.0">
- The light's angular size in degrees. Increasing this will make shadows softer at greater distances. Only available for [DirectionalLight3D]s. For reference, the Sun from the Earth is approximately [code]0.5[/code].
+ The light's angular size in degrees. Increasing this will make shadows softer at greater distances (also called percentage-closer soft shadows, or PCSS). Only available for [DirectionalLight3D]s. For reference, the Sun from the Earth is approximately [code]0.5[/code]. Increasing this value above [code]0.0[/code] for lights with shadows enabled will have a noticeable performance cost due to PCSS.
[b]Note:[/b] [member light_angular_distance] is not affected by [member Node3D.scale] (the light's scale or its parent's scale).
+ [b]Note:[/b] PCSS for directional lights is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light3D.BakeMode" default="2">
The light's bake mode. This will affect the global illumination techniques that have an effect on the light's rendering. See [enum BakeMode].
@@ -89,10 +90,12 @@
<member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector">
[Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained-glass.
[b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for light projector textures is set globally with [member ProjectSettings.rendering/textures/light_projectors/filter].
+ [b]Note:[/b] Light projector textures are only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0">
- The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s. Increasing this value will make the light fade out slower and shadows appear blurrier. This can be used to simulate area lights to an extent.
+ The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s. Increasing this value will make the light fade out slower and shadows appear blurrier (also called percentage-closer soft shadows, or PCSS). This can be used to simulate area lights to an extent. Increasing this value above [code]0.0[/code] for lights with shadows enabled will have a noticeable performance cost due to PCSS.
[b]Note:[/b] [member light_size] is not affected by [member Node3D.scale] (the light's scale or its parent's scale).
+ [b]Note:[/b] PCSS for positional lights is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5">
The intensity of the specular blob in objects affected by the light. At [code]0[/code], the light becomes a pure diffuse light. When not baking emission, this can be used to avoid unrealistic reflections when placing lights above an emissive surface.
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml
index 16b850866a..1feb363999 100644
--- a/doc/classes/NavigationServer3D.xml
+++ b/doc/classes/NavigationServer3D.xml
@@ -422,15 +422,6 @@
Sets the map up direction.
</description>
</method>
- <method name="process">
- <return type="void" />
- <param index="0" name="delta_time" type="float" />
- <description>
- Process the collision avoidance agents.
- The result of this process is needed by the physics server, so this must be called in the main thread.
- [b]Note:[/b] This function is not thread safe.
- </description>
- </method>
<method name="query_path" qualifiers="const">
<return type="void" />
<param index="0" name="parameters" type="NavigationPathQueryParameters3D" />
diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml
index 1592718c4b..4b406385e1 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -68,11 +68,9 @@
</constant>
<constant name="AXIS_STRETCH_MODE_TILE" value="1" enum="AxisStretchMode">
Repeats the center texture across the NinePatchRect. This won't cause any visible distortion. The texture must be seamless for this to work without displaying artifacts between edges.
- [b]Note:[/b] Only supported when using the Vulkan renderer. When using the OpenGL renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH].
</constant>
<constant name="AXIS_STRETCH_MODE_TILE_FIT" value="2" enum="AxisStretchMode">
Repeats the center texture across the NinePatchRect, but will also stretch the texture to make sure each tile is visible in full. This may cause the texture to be distorted, but less than [constant AXIS_STRETCH_MODE_STRETCH]. The texture must be seamless for this to work without displaying artifacts between edges.
- [b]Note:[/b] Only supported when using the Vulkan renderer. When using the OpenGL renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH].
</constant>
</constants>
</class>
diff --git a/doc/classes/OmniLight3D.xml b/doc/classes/OmniLight3D.xml
index c0e10574c8..1df8c255dd 100644
--- a/doc/classes/OmniLight3D.xml
+++ b/doc/classes/OmniLight3D.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
An Omnidirectional light is a type of [Light3D] that emits light in all directions. The light is attenuated by distance and this attenuation can be configured by changing its energy, radius, and attenuation parameters.
+ [b]Note:[/b] When using the Mobile rendering method, only 8 omni lights can be displayed on each mesh resource. Attempting to display more than 8 omni lights on a single mesh resource will result in omni lights flickering in and out as the camera moves. When using the Compatibility rendering method, only 8 omni lights can be displayed on each mesh resource by default, but this can be increased by adjusting [member ProjectSettings.rendering/limits/opengl/max_lights_per_object].
[b]Note:[/b] When using the Mobile or Compatibility rendering methods, omni lights will only correctly affect meshes whose visibility AABB intersects with the light's AABB. If using a shader to deform the mesh in a way that makes it go outside its AABB, [member GeometryInstance3D.extra_cull_margin] must be increased on the mesh. Otherwise, the light may not be visible on the mesh.
</description>
<tutorials>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 0b589b4e57..986810edf2 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -704,7 +704,8 @@
<member name="display/window/vsync/vsync_mode" type="int" setter="" getter="" default="1">
Sets the V-Sync mode for the main game window.
See [enum DisplayServer.VSyncMode] for possible values and how they affect the behavior of your application.
- Depending on the platform and used renderer, the engine will fall back to [code]Enabled[/code] if the desired mode is not supported.
+ Depending on the platform and used renderer, the engine will fall back to [b]Enabled[/b] if the desired mode is not supported.
+ [b]Note:[/b] V-Sync modes other than [b]Enabled[/b] are only supported in the Forward+ and Mobile rendering methods, not Compatibility.
[b]Note:[/b] This property is only read when the project starts. To change the V-Sync mode at runtime, call [method DisplayServer.window_set_vsync_mode] instead.
</member>
<member name="dotnet/project/assembly_name" type="String" setter="" getter="" default="&quot;&quot;">
@@ -1931,13 +1932,16 @@
</member>
<member name="rendering/anti_aliasing/quality/msaa_2d" type="int" setter="" getter="" default="0">
Sets the number of MSAA samples to use for 2D/Canvas rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. This has no effect on shader-induced aliasing or texture aliasing.
+ [b]Note:[/b] MSAA is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="rendering/anti_aliasing/quality/msaa_3d" type="int" setter="" getter="" default="0">
Sets the number of MSAA samples to use for 3D rendering (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. See also bilinear scaling 3d [member rendering/scaling_3d/mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
+ [b]Note:[/b] MSAA is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0">
Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. The blurriness is partially counteracted by automatically using a negative mipmap LOD bias (see [member rendering/textures/default_filters/texture_mipmap_bias]).
Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled].
+ [b]Note:[/b] Screen-space antialiasing is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false">
If [code]true[/code], uses a fast post-processing filter to make banding significantly less visible in 3D. 2D rendering is [i]not[/i] affected by debanding unless the [member Environment.background_mode] is [constant Environment.BG_CANVAS].
@@ -1946,11 +1950,14 @@
</member>
<member name="rendering/anti_aliasing/quality/use_taa" type="bool" setter="" getter="" default="false">
Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. Enabling TAA can make the image blurrier, which is partially counteracted by automatically using a negative mipmap LOD bias (see [member rendering/textures/default_filters/texture_mipmap_bias]).
- [b]Note:[/b] The implementation is not complete yet, some visual instances such as particles and skinned meshes may show artifacts.
+ [b]Note:[/b] The implementation is not complete yet. Some visual instances such as particles and skinned meshes may show ghosting artifacts in motion.
+ [b]Note:[/b] TAA is only supported in the Forward+ rendering method, not Mobile or Compatibility.
</member>
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25">
</member>
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/enabled" type="bool" setter="" getter="" default="true">
+ If [code]true[/code], enables a spatial filter to limit roughness in areas with high-frequency detail. This can help reduce specular aliasing to an extent, though not as much as enabling [member rendering/anti_aliasing/quality/use_taa]. This filter has a small performance cost, so consider disabling it if it doesn't benefit your scene noticeably.
+ [b]Note:[/b] TAA is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
</member>
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18">
</member>
@@ -1968,7 +1975,7 @@
</member>
<member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true">
If [code]true[/code], performs a previous depth pass before rendering 3D materials. This increases performance significantly in scenes with high overdraw, when complex materials and lighting are used. However, in scenes with few occluded surfaces, the depth prepass may reduce performance. If your game is viewed from a fixed angle that makes it easy to avoid overdraw (such as top-down or side-scrolling perspective), consider disabling the depth prepass to improve performance. This setting can be changed at run-time to optimize performance depending on the scene currently being viewed.
- [b]Note:[/b] Only supported when using the Vulkan Clustered backend or the OpenGL backend. When using Vulkan Mobile there is no depth prepass performed.
+ [b]Note:[/b] Depth prepass is only supported when using the Forward+ or Compatibility rendering method. When using the Mobile rendering method, there is no depth prepass performed.
</member>
<member name="rendering/driver/threads/thread_model" type="int" setter="" getter="" default="1">
Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
@@ -2174,12 +2181,15 @@
</member>
<member name="rendering/limits/opengl/max_lights_per_object" type="int" setter="" getter="" default="8">
Max number of omnilights and spotlights renderable per object. At the default value of 8, this means that each surface can be affected by up to 8 omnilights and 8 spotlights. This is further limited by hardware support and [member rendering/limits/opengl/max_renderable_lights]. Setting this low will slightly reduce memory usage, may decrease shader compile times, and may result in faster rendering on low-end, mobile, or web devices.
+ [b]Note:[/b] This setting is only effective when using the Compatibility rendering method, not Forward+ and Mobile.
</member>
<member name="rendering/limits/opengl/max_renderable_elements" type="int" setter="" getter="" default="65536">
Max number of elements renderable in a frame. If more elements than this are visible per frame, they will not be drawn. Keep in mind elements refer to mesh surfaces and not meshes themselves. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
+ [b]Note:[/b] This setting is only effective when using the Compatibility rendering method, not Forward+ and Mobile.
</member>
<member name="rendering/limits/opengl/max_renderable_lights" type="int" setter="" getter="" default="32">
Max number of positional lights renderable in a frame. If more lights than this number are used, they will be ignored. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
+ [b]Note:[/b] This setting is only effective when using the Compatibility rendering method, not Forward+ and Mobile.
</member>
<member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000">
</member>
@@ -2271,7 +2281,8 @@
Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference.
</member>
<member name="rendering/scaling_3d/mode" type="int" setter="" getter="" default="0">
- Sets the scaling 3D mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. FSR should be used where possible.
+ Sets the scaling 3D mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially-aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. On particularly low-end GPUs, the added cost of FSR may not be worth it (compared to using bilinear scaling with a slightly higher resolution scale to match performance).
+ [b]Note:[/b] FSR is only effective when using the Forward+ rendering method, not Mobile or Compatibility. If using an incompatible rendering method, FSR will fall back to bilinear scaling.
</member>
<member name="rendering/scaling_3d/scale" type="float" setter="" getter="" default="1.0">
Scales the 3D render buffer based on the viewport size uses an image filter specified in [member rendering/scaling_3d/mode] to scale the output image to the full viewport size. Values lower than [code]1.0[/code] can be used to speed up 3D rendering at the cost of quality (undersampling). Values greater than [code]1.0[/code] are only valid for bilinear mode and can be used to improve 3D rendering quality at a high performance cost (supersampling). See also [member rendering/anti_aliasing/quality/msaa_3d] for multi-sample antialiasing, which is significantly cheaper but only smooths the edges of polygons.
@@ -2295,9 +2306,11 @@
</member>
<member name="rendering/shading/overrides/force_vertex_shading" type="bool" setter="" getter="" default="false">
If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices.
+ [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet.
</member>
<member name="rendering/shading/overrides/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true">
Lower-end override for [member rendering/shading/overrides/force_vertex_shading] on mobile devices, due to performance concerns or driver support.
+ [b]Note:[/b] This setting currently has no effect, as vertex shading is not implemented yet.
</member>
<member name="rendering/textures/decals/filter" type="int" setter="" getter="" default="3">
The filtering quality to use for [Decal] nodes. When using one of the anisotropic filtering modes, the anisotropic filtering level is controlled by [member rendering/textures/default_filters/anisotropic_filtering_level].
diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml
index e912925cd2..cc48e0612b 100644
--- a/doc/classes/ReflectionProbe.xml
+++ b/doc/classes/ReflectionProbe.xml
@@ -7,6 +7,7 @@
Captures its surroundings as a cubemap, and stores versions of it with increasing levels of blur to simulate different material roughnesses.
The [ReflectionProbe] is used to create high-quality reflections at a low performance cost (when [member update_mode] is [constant UPDATE_ONCE]). [ReflectionProbe]s can be blended together and with the rest of the scene smoothly. [ReflectionProbe]s can also be combined with [VoxelGI], SDFGI ([member Environment.sdfgi_enabled]) and screen-space reflections ([member Environment.ssr_enabled]) to get more accurate reflections in specific areas. [ReflectionProbe]s render all objects within their [member cull_mask], so updating them can be quite expensive. It is best to update them once with the important static objects and then leave them as-is.
[b]Note:[/b] Unlike [VoxelGI] and SDFGI, [ReflectionProbe]s only source their environment from a [WorldEnvironment] node. If you specify an [Environment] resource within a [Camera3D] node, it will be ignored by the [ReflectionProbe]. This can lead to incorrect lighting within the [ReflectionProbe].
+ [b]Note:[/b] Reflection probes are only supported in the Forward+ and Mobile rendering methods, not Compatibility. When using the Mobile rendering method, only 8 reflection probes can be displayed on each mesh resource. Attempting to display more than 8 reflection probes on a single mesh resource will result in reflection probes flickering in and out as the camera moves.
[b]Note:[/b] When using the Mobile rendering method, reflection probes will only correctly affect meshes whose visibility AABB intersects with the reflection probe's AABB. If using a shader to deform the mesh in a way that makes it go outside its AABB, [member GeometryInstance3D.extra_cull_margin] must be increased on the mesh. Otherwise, the reflection probe may not be visible on the mesh.
</description>
<tutorials>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index a09940d30e..64be8e6807 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -8,7 +8,7 @@
On startup, Godot creates a global [RenderingDevice] which can be retrieved using [method RenderingServer.get_rendering_device]. This global RenderingDevice performs drawing to the screen.
Internally, [RenderingDevice] is used in Godot to provide support for several modern low-level graphics APIs while reducing the amount of code duplication required.
[b]Local RenderingDevices:[/b] Using [method RenderingServer.create_local_rendering_device], you can create "secondary" rendering devices to perform drawing and GPU compute operations on separate threads.
- [b]Note:[/b] [RenderingDevice] is not available when running in headless mode or when using the OpenGL renderer.
+ [b]Note:[/b] [RenderingDevice] is not available when running in headless mode or when using the Compatibility rendering method.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SpotLight3D.xml b/doc/classes/SpotLight3D.xml
index 9dff742748..6bb4ae548c 100644
--- a/doc/classes/SpotLight3D.xml
+++ b/doc/classes/SpotLight3D.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A Spotlight is a type of [Light3D] node that emits lights in a specific direction, in the shape of a cone. The light is attenuated through the distance. This attenuation can be configured by changing the energy, radius and attenuation parameters of [Light3D].
+ [b]Note:[/b] When using the Mobile rendering method, only 8 spot lights can be displayed on each mesh resource. Attempting to display more than 8 spot lights on a single mesh resource will result in spot lights flickering in and out as the camera moves. When using the Compatibility rendering method, only 8 spot lights can be displayed on each mesh resource by default, but this can be increased by adjusting [member ProjectSettings.rendering/limits/opengl/max_lights_per_object].
[b]Note:[/b] When using the Mobile or Compatibility rendering methods, spot lights will only correctly affect meshes whose visibility AABB intersects with the light's AABB. If using a shader to deform the mesh in a way that makes it go outside its AABB, [member GeometryInstance3D.extra_cull_margin] must be increased on the mesh. Otherwise, the light may not be visible on the mesh.
</description>
<tutorials>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 792cd38741..8535dacda7 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -193,8 +193,8 @@
GD.Print("Team".Find("I")); // Prints -1
GD.Print("Potato".Find("t")); // Prints 2
- GD.print("Potato".Find("t", 3)); // Prints 4
- GD.print("Potato".Find("t", 5)); // Prints -1
+ GD.Print("Potato".Find("t", 3)); // Prints 4
+ GD.Print("Potato".Find("t", 5)); // Prints -1
[/csharp]
[/codeblocks]
[b]Note:[/b] If you just want to know whether the string contains [param what], use [method contains]. In GDScript, you may also use the [code]in[/code] operator.
@@ -230,6 +230,7 @@
print("User {id} is {name}.".format([["id", 42], ["name", "Godot"]]))
[/codeblock]
See also the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format string[/url] tutorial.
+ [b]Note:[/b] In C#, it's recommended to [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]interpolate strings with "$"[/url], instead.
</description>
</method>
<method name="get_base_dir" qualifiers="const">
@@ -480,7 +481,7 @@
var fruits = new string[] {"Apple", "Orange", "Pear", "Kiwi"};
// In C#, this method is static.
- GD.Print(string.Join(", ", fruits); // Prints "Apple, Orange, Pear, Kiwi"
+ GD.Print(string.Join(", ", fruits)); // Prints "Apple, Orange, Pear, Kiwi"
GD.Print(string.Join("---", fruits)); // Prints "Apple---Orange---Pear---Kiwi"
[/csharp]
[/codeblocks]
@@ -1047,8 +1048,7 @@
<return type="String" />
<param index="0" name="right" type="Variant" />
<description>
- Formats the [String], replacing the placeholders with one or more parameters.
- To pass multiple parameters, [param right] needs to be an [Array].
+ Formats the [String], replacing the placeholders with one or more parameters. To pass multiple parameters, [param right] needs to be an [Array].
[codeblock]
print("I caught %d fishes!" % 2) # Prints "I caught 2 fishes!"
@@ -1057,8 +1057,8 @@
var speed = 40.3485
print(my_message % [location, speed]) # Prints "Travelling to Deep Valley, at 40.35 km/h."
[/codeblock]
- In C#, there is no direct equivalent to this operator. Use the [method format] method, instead.
For more information, see the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format strings[/url] tutorial.
+ [b]Note:[/b] In C#, this operator is not available. Instead, see [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]how to interpolate strings with "$"[/url].
</description>
</operator>
<operator name="operator +">
@@ -1072,6 +1072,7 @@
<return type="String" />
<param index="0" name="right" type="StringName" />
<description>
+ Appends [param right] at the end of this [String], returning a [String]. This is also known as a string concatenation.
</description>
</operator>
<operator name="operator &lt;">
diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml
index c103fb2287..96b958a5b9 100644
--- a/doc/classes/StringName.xml
+++ b/doc/classes/StringName.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
[StringName]s are immutable strings designed for general-purpose representation of unique names (also called "string interning"). [StringName] ensures that only one instance of a given name exists (so two [StringName]s with the same value are the same object). Comparing them is much faster than with regular [String]s, because only the pointers are compared, not the whole strings.
- You will usually just pass a [String] to methods expecting a [StringName] and it will be automatically converted, but you may occasionally want to construct a [StringName] ahead of time with [StringName] or, in GDScript, the literal syntax [code]&amp;"example"[/code].
+ You will usually just pass a [String] to methods expecting a [StringName] and it will be automatically converted, but you may occasionally want to construct a [StringName] ahead of time with the [StringName] constructor or, in GDScript, the literal syntax [code]&amp;"example"[/code].
See also [NodePath], which is a similar concept specifically designed to store pre-parsed node paths.
Some string methods have corresponding variations. Variations suffixed with [code]n[/code] ([method countn], [method findn], [method replacen], etc.) are [b]case-insensitive[/b] (they make no distinction between uppercase and lowercase letters). Method variations prefixed with [code]r[/code] ([method rfind], [method rsplit], etc.) are reversed, and start from the end of the string, instead of the beginning.
[b]Note:[/b] In a boolean context, a [StringName] will evaluate to [code]false[/code] if it is empty ([code]StringName("")[/code]). Otherwise, a [StringName] will always evaluate to [code]true[/code].
@@ -176,8 +176,8 @@
GD.Print("Team".Find("I")); // Prints -1
GD.Print("Potato".Find("t")); // Prints 2
- GD.print("Potato".Find("t", 3)); // Prints 4
- GD.print("Potato".Find("t", 5)); // Prints -1
+ GD.Print("Potato".Find("t", 3)); // Prints 4
+ GD.Print("Potato".Find("t", 5)); // Prints -1
[/csharp]
[/codeblocks]
[b]Note:[/b] If you just want to know whether the string contains [param what], use [method contains]. In GDScript, you may also use the [code]in[/code] operator.
@@ -213,6 +213,7 @@
print("User {id} is {name}.".format([["id", 42], ["name", "Godot"]]))
[/codeblock]
See also the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format string[/url] tutorial.
+ [b]Note:[/b] In C#, it's recommended to [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]interpolate strings with "$"[/url], instead.
</description>
</method>
<method name="get_base_dir" qualifiers="const">
@@ -455,7 +456,7 @@
var fruits = new string[] {"Apple", "Orange", "Pear", "Kiwi"};
// In C#, this method is static.
- GD.Print(string.Join(", ", fruits); // Prints "Apple, Orange, Pear, Kiwi"
+ GD.Print(string.Join(", ", fruits)); // Prints "Apple, Orange, Pear, Kiwi"
GD.Print(string.Join("---", fruits)); // Prints "Apple---Orange---Pear---Kiwi"
[/csharp]
[/codeblocks]
@@ -954,18 +955,23 @@
<return type="String" />
<param index="0" name="right" type="Variant" />
<description>
+ Formats the [StringName], replacing the placeholders with one or more parameters, returning a [String]. To pass multiple parameters, [param right] needs to be an [Array].
+ For more information, see the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format strings[/url] tutorial.
+ [b]Note:[/b] In C#, this operator is not available. Instead, see [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]how to interpolate strings with "$"[/url].
</description>
</operator>
<operator name="operator +">
<return type="String" />
<param index="0" name="right" type="String" />
<description>
+ Appends [param right] at the end of this [StringName], returning a [String]. This is also known as a string concatenation.
</description>
</operator>
<operator name="operator +">
<return type="String" />
<param index="0" name="right" type="StringName" />
<description>
+ Appends [param right] at the end of this [StringName], returning a [String]. This is also known as a string concatenation.
</description>
</operator>
<operator name="operator &lt;">
diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml
index 8f6dff7acf..7a0940edd4 100644
--- a/doc/classes/TextureLayered.xml
+++ b/doc/classes/TextureLayered.xml
@@ -8,7 +8,7 @@
Data is set on a per-layer basis. For [Texture2DArray]s, the layer specifies the array layer.
All images need to have the same width, height and number of mipmap levels.
A [TextureLayered] can be loaded with [method ResourceLoader.load].
- Internally, Godot maps these files to their respective counterparts in the target rendering driver (Vulkan, GLES3).
+ Internally, Godot maps these files to their respective counterparts in the target rendering driver (Vulkan, OpenGL3).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VoxelGI.xml b/doc/classes/VoxelGI.xml
index 4347c5845f..cc78426736 100644
--- a/doc/classes/VoxelGI.xml
+++ b/doc/classes/VoxelGI.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
[VoxelGI]s are used to provide high-quality real-time indirect light and reflections to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [VoxelGI]s need to be baked before having a visible effect. However, once baked, dynamic objects will receive light from them. Furthermore, lights can be fully dynamic or baked.
+ [b]Note:[/b] [VoxelGI] is only supported in the Forward+ rendering method, not Mobile or Compatibility.
[b]Procedural generation:[/b] [VoxelGI] can be baked in an exported project, which makes it suitable for procedurally generated or user-built levels as long as all the geometry is generated in advance. For games where geometry is generated at any time during gameplay, SDFGI is more suitable (see [member Environment.sdfgi_enabled]).
[b]Performance:[/b] [VoxelGI] is relatively demanding on the GPU and is not suited to low-end hardware such as integrated graphics (consider [LightmapGI] instead). To improve performance, adjust [member ProjectSettings.rendering/global_illumination/voxel_gi/quality] and enable [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution] in the Project Settings. To provide a fallback for low-end hardware, consider adding an option to disable [VoxelGI] in your project's options menus. A [VoxelGI] node can be disabled by hiding it.
[b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh. To further prevent light leaks, you can also strategically place temporary [MeshInstance3D] nodes with their [member GeometryInstance3D.gi_mode] set to [constant GeometryInstance3D.GI_MODE_STATIC]. These temporary nodes can then be hidden after baking the [VoxelGI] node.
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 3c5441f3c4..2a524e8c3a 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -566,6 +566,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
uint32_t index = 0;
Item *current_clip = nullptr;
+ GLES3::CanvasShaderData *shader_data_cache = nullptr;
// Record Batches.
// First item always forms its own batch.
@@ -602,7 +603,6 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
}
}
- GLES3::CanvasShaderData *shader_data_cache = nullptr;
if (material != state.canvas_instance_batches[state.current_batch_index].material) {
_new_batch(batch_broken);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 2e3e6263ed..600aa908cc 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -306,6 +306,15 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+
+ if (p_screen_rect.position != Vector2()) {
+ // Viewport doesn't cover entire window so clear window to black before blitting.
+ Size2i win_size = DisplayServer::get_singleton()->window_get_size();
+ glViewport(0, 0, win_size.width, win_size.height);
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
Vector2i screen_rect_end = p_screen_rect.get_end();
glBlitFramebuffer(0, 0, rt->size.x, rt->size.y,
p_screen_rect.position.x, flip_y ? screen_rect_end.y : p_screen_rect.position.y, screen_rect_end.x, flip_y ? p_screen_rect.position.y : screen_rect_end.y,
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index aa8df606cf..2c530e3ae6 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -2881,6 +2881,7 @@ void MaterialStorage::material_set_render_priority(RID p_material, int priority)
if (material->data) {
material->data->set_render_priority(priority);
}
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
bool MaterialStorage::material_is_animated(RID p_material) {
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 36b34dd8a2..1adba019ba 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -1686,6 +1686,8 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
old_stride += multimesh->uses_colors ? 4 : 0;
old_stride += multimesh->uses_custom_data ? 4 : 0;
+ ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)old_stride));
+
for (int i = 0; i < multimesh->instances; i++) {
{
float *dataptr = w + i * old_stride;
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 9c9c39cc0e..ce66943328 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -806,6 +806,7 @@ void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image,
texture_set_data(p_texture, p_image, p_layer);
#ifdef TOOLS_ENABLED
Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND(!tex);
tex->image_cache_2d.unref();
#endif
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 2895aa9710..be4a070213 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -847,9 +847,14 @@ bool AnimationTrackEditTypeAudio::is_key_selectable_by_distance() const {
void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), p_index);
-
if (!stream.is_valid()) {
- AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right);
+ AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); // Draw diamond.
+ return;
+ }
+
+ float len = stream->get_length();
+ if (len == 0) {
+ AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); // Draw diamond.
return;
}
@@ -871,16 +876,10 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
float fh = int(font->get_height(font_size) * 1.5);
- float len = stream->get_length();
-
Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream);
float preview_len = preview->get_length();
- if (len == 0) {
- len = preview_len;
- }
-
int pixel_total_len = len * p_pixels_sec;
len -= end_ofs;
@@ -1044,16 +1043,13 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) {
continue;
}
- float start_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), i);
- float end_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), i);
float len = stream->get_length();
-
if (len == 0) {
- Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream);
- float preview_len = preview->get_length();
- len = preview_len;
+ continue;
}
+ float start_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), i);
+ float end_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), i);
len -= end_ofs;
len -= start_ofs;
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 0c7ea33b54..acbc3ce0dc 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1540,6 +1540,10 @@ void EditorHelp::_update_doc() {
if (cd.properties[i].overridden) {
continue;
}
+ // Ignore undocumented private.
+ if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.strip_edges().is_empty()) {
+ continue;
+ }
property_line[cd.properties[i].name] = class_desc->get_paragraph_count() - 2;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index dd84f3b9e1..23e32dcbd8 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -384,9 +384,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
if (score > 0 && score >= best_score) {
best = locale;
best_score = score;
- if (score == 10) {
- break; // Exact match, skip the rest.
- }
}
}
if (best_score == 0) {
diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp
index a46484bb0e..96a8cc8b91 100644
--- a/editor/export/editor_export_platform.cpp
+++ b/editor/export/editor_export_platform.cpp
@@ -1513,7 +1513,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b
f = FileAccess::open(p_path, FileAccess::WRITE);
if (f.is_null()) {
DirAccess::remove_file_or_error(tmppath);
- add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file to read from path \"%s\"."), tmppath));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file for writing at path \"%s\"."), p_path));
return ERR_CANT_CREATE;
}
} else {
@@ -1521,7 +1521,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b
f = FileAccess::open(p_path, FileAccess::READ_WRITE);
if (f.is_null()) {
DirAccess::remove_file_or_error(tmppath);
- add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open executable file from path \"%s\"."), tmppath));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file for reading-writing at path \"%s\"."), p_path));
return ERR_FILE_CANT_OPEN;
}
diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp
index bbfd73be5e..7f934bc45b 100644
--- a/editor/export/editor_export_platform_pc.cpp
+++ b/editor/export/editor_export_platform_pc.cpp
@@ -33,6 +33,9 @@
#include "core/config/project_settings.h"
void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
+ if (p_preset->get("texture_format/bptc")) {
+ r_features->push_back("bptc");
+ }
if (p_preset->get("texture_format/s3tc")) {
r_features->push_back("s3tc");
}
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index b001b4f766..fc1d8936d5 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -3392,7 +3392,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
VIEW_DISPLAY_SHADELESS,
VIEW_DISPLAY_LIGHTING,
VIEW_DISPLAY_NORMAL_BUFFER,
- VIEW_DISPLAY_WIREFRAME,
VIEW_DISPLAY_DEBUG_SHADOW_ATLAS,
VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS,
VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO,
@@ -3422,7 +3421,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
Viewport::DEBUG_DRAW_UNSHADED,
Viewport::DEBUG_DRAW_LIGHTING,
Viewport::DEBUG_DRAW_NORMAL_BUFFER,
- Viewport::DEBUG_DRAW_WIREFRAME,
Viewport::DEBUG_DRAW_SHADOW_ATLAS,
Viewport::DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS,
Viewport::DEBUG_DRAW_VOXEL_GI_ALBEDO,
@@ -3445,9 +3443,7 @@ void Node3DEditorViewport::_menu_option(int p_option) {
Viewport::DEBUG_DRAW_MOTION_VECTORS,
};
- int idx = 0;
-
- while (display_options[idx] != VIEW_MAX) {
+ for (int idx = 0; display_options[idx] != VIEW_MAX; idx++) {
int id = display_options[idx];
int item_idx = view_menu->get_popup()->get_item_index(id);
if (item_idx != -1) {
@@ -3461,7 +3457,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
if (id == p_option) {
viewport->set_debug_draw(debug_draw_modes[idx]);
}
- idx++;
}
} break;
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 74d82aa4a2..6d747ba6a8 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
#include "core/io/file_access.h"
+#include "core/io/json.h"
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -209,6 +210,27 @@ Ref<EditorSyntaxHighlighter> EditorPlainTextSyntaxHighlighter::_create() const {
return syntax_highlighter;
}
+////
+
+void EditorJSONSyntaxHighlighter::_update_cache() {
+ highlighter->set_text_edit(text_edit);
+ highlighter->clear_keyword_colors();
+ highlighter->clear_member_keyword_colors();
+ highlighter->clear_color_regions();
+
+ highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color"));
+ highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color"));
+
+ const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
+ highlighter->add_color_region("\"", "\"", string_color);
+}
+
+Ref<EditorSyntaxHighlighter> EditorJSONSyntaxHighlighter::_create() const {
+ Ref<EditorJSONSyntaxHighlighter> syntax_highlighter;
+ syntax_highlighter.instantiate();
+ return syntax_highlighter;
+}
+
////////////////////////////////////////////////////////////////////////////////
/*** SCRIPT EDITOR ****/
@@ -702,9 +724,10 @@ void ScriptEditor::_open_recent_script(int p_idx) {
if (FileAccess::exists(path)) {
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ ResourceLoader::get_recognized_extensions_for_type("JSON", &extensions);
if (extensions.find(path.get_extension())) {
- Ref<Script> scr = ResourceLoader::load(path);
+ Ref<Resource> scr = ResourceLoader::load(path);
if (scr.is_valid()) {
edit(scr, true);
return;
@@ -1182,6 +1205,7 @@ void ScriptEditor::_menu_option(int p_option) {
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ ResourceLoader::get_recognized_extensions_for_type("JSON", &extensions);
bool built_in = !path.is_resource_file();
if (extensions.find(path.get_extension()) || built_in) {
@@ -1196,7 +1220,7 @@ void ScriptEditor::_menu_option(int p_option) {
}
}
- Ref<Script> scr = ResourceLoader::load(path);
+ Ref<Resource> scr = ResourceLoader::load(path);
if (!scr.is_valid()) {
EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
file_dialog_option = -1;
@@ -2319,12 +2343,23 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col,
}
se->add_syntax_highlighter(highlighter);
- if (scr != nullptr && !highlighter_set) {
- PackedStringArray languages = highlighter->_get_supported_languages();
+ if (highlighter_set) {
+ continue;
+ }
+
+ PackedStringArray languages = highlighter->_get_supported_languages();
+ // If script try language, else use extension.
+ if (scr != nullptr) {
if (languages.has(scr->get_language()->get_name())) {
se->set_syntax_highlighter(highlighter);
highlighter_set = true;
}
+ continue;
+ }
+
+ if (languages.has(p_resource->get_path().get_extension())) {
+ se->set_syntax_highlighter(highlighter);
+ highlighter_set = true;
}
}
@@ -2536,6 +2571,14 @@ void ScriptEditor::reload_scripts(bool p_refresh_only) {
scr->reload(true);
}
+ Ref<JSON> json = edited_res;
+ if (json != nullptr) {
+ Ref<JSON> rel_json = ResourceLoader::load(json->get_path(), json->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
+ ERR_CONTINUE(!rel_json.is_valid());
+ json->parse(rel_json->get_parsed_text(), true);
+ json->set_last_modified_time(rel_json->get_last_modified_time());
+ }
+
Ref<TextFile> text_file = edited_res;
if (text_file.is_valid()) {
text_file->reload_from_file();
@@ -2564,8 +2607,9 @@ void ScriptEditor::open_text_file_create_dialog(const String &p_base_path, const
Ref<Resource> ScriptEditor::open_file(const String &p_file) {
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ ResourceLoader::get_recognized_extensions_for_type("JSON", &extensions);
if (extensions.find(p_file.get_extension())) {
- Ref<Script> scr = ResourceLoader::load(p_file);
+ Ref<Resource> scr = ResourceLoader::load(p_file);
if (!scr.is_valid()) {
EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
return Ref<Resource>();
@@ -2866,8 +2910,8 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
if (file.is_empty() || !FileAccess::exists(file)) {
continue;
}
- if (ResourceLoader::exists(file, "Script")) {
- Ref<Script> scr = ResourceLoader::load(file);
+ if (ResourceLoader::exists(file, "Script") || ResourceLoader::exists(file, "JSON")) {
+ Ref<Resource> scr = ResourceLoader::load(file);
if (scr.is_valid()) {
return true;
}
@@ -2947,7 +2991,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
continue;
}
- if (!ResourceLoader::exists(file, "Script") && !textfile_extensions.has(file.get_extension())) {
+ if (!ResourceLoader::exists(file, "Script") && !ResourceLoader::exists(file, "JSON") && !textfile_extensions.has(file.get_extension())) {
continue;
}
@@ -3105,6 +3149,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
HashSet<String> loaded_scripts;
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ ResourceLoader::get_recognized_extensions_for_type("JSON", &extensions);
for (int i = 0; i < scripts.size(); i++) {
String path = scripts[i];
@@ -3123,7 +3168,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
loaded_scripts.insert(path);
if (extensions.find(path.get_extension())) {
- Ref<Script> scr = ResourceLoader::load(path);
+ Ref<Resource> scr = ResourceLoader::load(path);
if (!scr.is_valid()) {
continue;
}
@@ -3477,6 +3522,12 @@ void ScriptEditor::_open_script_request(const String &p_path) {
return;
}
+ Ref<JSON> json = ResourceLoader::load(p_path);
+ if (json.is_valid()) {
+ script_editor->edit(json, false);
+ return;
+ }
+
Error err;
Ref<TextFile> text_file = script_editor->_load_text_file(p_path, &err);
if (text_file.is_valid()) {
@@ -3539,7 +3590,8 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb
return;
} else {
Ref<Script> scr = res;
- if (scr.is_valid()) {
+ Ref<JSON> json = res;
+ if (scr.is_valid() || json.is_valid()) {
edit(scr);
ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor());
@@ -3942,6 +3994,10 @@ ScriptEditor::ScriptEditor() {
add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
tab_container->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles")));
+
+ Ref<EditorJSONSyntaxHighlighter> json_syntax_highlighter;
+ json_syntax_highlighter.instantiate();
+ register_syntax_highlighter(json_syntax_highlighter);
}
ScriptEditor::~ScriptEditor() {
@@ -3963,6 +4019,8 @@ void ScriptEditorPlugin::edit(Object *p_object) {
}
}
script_editor->edit(p_script);
+ } else if (Object::cast_to<JSON>(p_object)) {
+ script_editor->edit(Object::cast_to<JSON>(p_object));
} else if (Object::cast_to<TextFile>(p_object)) {
script_editor->edit(Object::cast_to<TextFile>(p_object));
}
@@ -3977,6 +4035,10 @@ bool ScriptEditorPlugin::handles(Object *p_object) const {
return true;
}
+ if (Object::cast_to<JSON>(p_object)) {
+ return true;
+ }
+
return p_object->is_class("Script");
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 988d07621c..f8e684ae34 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -96,6 +96,24 @@ public:
virtual Ref<EditorSyntaxHighlighter> _create() const override;
};
+class EditorJSONSyntaxHighlighter : public EditorSyntaxHighlighter {
+ GDCLASS(EditorJSONSyntaxHighlighter, EditorSyntaxHighlighter)
+
+private:
+ Ref<CodeHighlighter> highlighter;
+
+public:
+ virtual void _update_cache() override;
+ virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override { return highlighter->get_line_syntax_highlighting(p_line); }
+
+ virtual PackedStringArray _get_supported_languages() const override { return PackedStringArray{ "json" }; }
+ virtual String _get_name() const override { return TTR("JSON"); }
+
+ virtual Ref<EditorSyntaxHighlighter> _create() const override;
+
+ EditorJSONSyntaxHighlighter() { highlighter.instantiate(); }
+};
+
///////////////////////////////////////////////////////////////////////////////
class ScriptEditorQuickOpen : public ConfirmationDialog {
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index a376699e54..ceb170d7d8 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -30,6 +30,7 @@
#include "text_editor.h"
+#include "core/io/json.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@@ -67,12 +68,12 @@ void TextEditor::_load_theme_settings() {
String TextEditor::get_name() {
String name;
- name = text_file->get_path().get_file();
+ name = edited_res->get_path().get_file();
if (name.is_empty()) {
// This appears for newly created built-in text_files before saving the scene.
name = TTR("[unsaved]");
- } else if (text_file->is_built_in()) {
- const String &text_file_name = text_file->get_name();
+ } else if (edited_res->is_built_in()) {
+ const String &text_file_name = edited_res->get_name();
if (!text_file_name.is_empty()) {
// If the built-in text_file has a custom resource name defined,
// display the built-in text_file name as follows: `ResourceName (scene_file.tscn)`
@@ -88,20 +89,29 @@ String TextEditor::get_name() {
}
Ref<Texture2D> TextEditor::get_theme_icon() {
- return EditorNode::get_singleton()->get_object_icon(text_file.ptr(), "");
+ return EditorNode::get_singleton()->get_object_icon(edited_res.ptr(), "TextFile");
}
Ref<Resource> TextEditor::get_edited_resource() const {
- return text_file;
+ return edited_res;
}
void TextEditor::set_edited_resource(const Ref<Resource> &p_res) {
- ERR_FAIL_COND(text_file.is_valid());
+ ERR_FAIL_COND(edited_res.is_valid());
ERR_FAIL_COND(p_res.is_null());
- text_file = p_res;
+ edited_res = p_res;
+
+ Ref<TextFile> text_file = edited_res;
+ if (text_file != nullptr) {
+ code_editor->get_text_editor()->set_text(text_file->get_text());
+ }
+
+ Ref<JSON> json_file = edited_res;
+ if (json_file != nullptr) {
+ code_editor->get_text_editor()->set_text(json_file->get_parsed_text());
+ }
- code_editor->get_text_editor()->set_text(text_file->get_text());
code_editor->get_text_editor()->clear_undo_history();
code_editor->get_text_editor()->tag_saved_version();
@@ -118,6 +128,8 @@ void TextEditor::enable_editor(Control *p_shortcut_context) {
_load_theme_settings();
+ _validate_script();
+
if (p_shortcut_context) {
for (int i = 0; i < edit_hb->get_child_count(); ++i) {
Control *c = cast_to<Control>(edit_hb->get_child(i));
@@ -143,7 +155,7 @@ PackedInt32Array TextEditor::get_breakpoints() {
}
void TextEditor::reload_text() {
- ERR_FAIL_COND(text_file.is_null());
+ ERR_FAIL_COND(edited_res.is_null());
CodeEdit *te = code_editor->get_text_editor();
int column = te->get_caret_column();
@@ -151,7 +163,16 @@ void TextEditor::reload_text() {
int h = te->get_h_scroll();
int v = te->get_v_scroll();
- te->set_text(text_file->get_text());
+ Ref<TextFile> text_file = edited_res;
+ if (text_file != nullptr) {
+ te->set_text(text_file->get_text());
+ }
+
+ Ref<JSON> json_file = edited_res;
+ if (json_file != nullptr) {
+ te->set_text(json_file->get_parsed_text());
+ }
+
te->set_caret_line(row);
te->set_caret_column(column);
te->set_h_scroll(h);
@@ -166,6 +187,20 @@ void TextEditor::reload_text() {
void TextEditor::_validate_script() {
emit_signal(SNAME("name_changed"));
emit_signal(SNAME("edited_script_changed"));
+
+ Ref<JSON> json_file = edited_res;
+ if (json_file != nullptr) {
+ CodeEdit *te = code_editor->get_text_editor();
+
+ te->set_line_background_color(code_editor->get_error_pos().x, Color(0, 0, 0, 0));
+ code_editor->set_error("");
+
+ if (json_file->parse(te->get_text(), true) != OK) {
+ code_editor->set_error(json_file->get_error_message());
+ code_editor->set_error_pos(json_file->get_error_line(), 0);
+ te->set_line_background_color(code_editor->get_error_pos().x, EDITOR_GET("text_editor/theme/highlighting/mark_color"));
+ }
+ }
}
void TextEditor::_update_bookmark_list() {
@@ -204,13 +239,22 @@ void TextEditor::_bookmark_item_pressed(int p_idx) {
}
void TextEditor::apply_code() {
- text_file->set_text(code_editor->get_text_editor()->get_text());
+ Ref<TextFile> text_file = edited_res;
+ if (text_file != nullptr) {
+ text_file->set_text(code_editor->get_text_editor()->get_text());
+ }
+
+ Ref<JSON> json_file = edited_res;
+ if (json_file != nullptr) {
+ json_file->parse(code_editor->get_text_editor()->get_text(), true);
+ }
+ code_editor->get_text_editor()->get_syntax_highlighter()->update_cache();
}
bool TextEditor::is_unsaved() {
const bool unsaved =
code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() ||
- text_file->get_path().is_empty(); // In memory.
+ edited_res->get_path().is_empty(); // In memory.
return unsaved;
}
@@ -431,7 +475,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
}
static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
- if (Object::cast_to<TextFile>(*p_resource)) {
+ if (Object::cast_to<TextFile>(*p_resource) || Object::cast_to<JSON>(*p_resource)) {
return memnew(TextEditor);
}
return nullptr;
@@ -656,4 +700,5 @@ TextEditor::~TextEditor() {
}
void TextEditor::validate() {
+ this->code_editor->validate_script();
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 6db81508b3..85e0fee627 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -41,7 +41,7 @@ class TextEditor : public ScriptEditorBase {
private:
CodeTextEditor *code_editor = nullptr;
- Ref<TextFile> text_file;
+ Ref<Resource> edited_res;
bool editor_enabled = false;
HBoxContainer *edit_hb = nullptr;
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index fd651dd507..43c6d1a48b 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -404,13 +404,16 @@ void TileAtlasView::_draw_background_right() {
}
void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id) {
- ERR_FAIL_COND(!p_tile_set);
- ERR_FAIL_COND(!p_tile_set_atlas_source);
+ tile_set = p_tile_set;
+ tile_set_atlas_source = p_tile_set_atlas_source;
+
+ if (!tile_set) {
+ return;
+ }
+
ERR_FAIL_COND(p_source_id < 0);
ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_atlas_source);
- tile_set = p_tile_set;
- tile_set_atlas_source = p_tile_set_atlas_source;
source_id = p_source_id;
// Show or hide the view.
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 8277e473fd..04a09a97e7 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -571,14 +571,14 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
case DRAG_TYPE_PAINT: {
HashMap<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_last_mouse_pos, mpos, drag_erasing);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
- continue;
- }
Vector2i coords = E.key;
if (!drag_modified.has(coords)) {
drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
+ if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
+ continue;
+ }
+ tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
- tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
_fix_invalid_tiles_in_tile_map_selection();
} break;
@@ -588,14 +588,14 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!drag_modified.has(line[i])) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
- continue;
- }
Vector2i coords = E.key;
if (!drag_modified.has(coords)) {
drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
+ if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
+ continue;
+ }
+ tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
- tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
}
}
@@ -684,14 +684,14 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!drag_modified.has(line[i])) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
- continue;
- }
Vector2i coords = E.key;
if (!drag_modified.has(coords)) {
drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
+ if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
+ continue;
+ }
+ tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
- tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
}
}
@@ -2141,7 +2141,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
scatter_controls_container = memnew(HBoxContainer);
scatter_label = memnew(Label);
- scatter_label->set_tooltip_text(TTR("Defines the probability of painting nothing instead of a randomly selected tile."));
+ scatter_label->set_tooltip_text(TTR("Modifies the chance of painting nothing instead of a randomly selected tile."));
scatter_label->set_text(TTR("Scattering:"));
scatter_controls_container->add_child(scatter_label);
@@ -2149,7 +2149,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
scatter_spinbox->set_min(0.0);
scatter_spinbox->set_max(1000);
scatter_spinbox->set_step(0.001);
- scatter_spinbox->set_tooltip_text(TTR("Defines the probability of painting nothing instead of a randomly selected tile."));
+ scatter_spinbox->set_tooltip_text(TTR("Modifies the chance of painting nothing instead of a randomly selected tile."));
scatter_spinbox->get_line_edit()->add_theme_constant_override("minimum_character_width", 4);
scatter_spinbox->connect("value_changed", callable_mp(this, &TileMapEditorTilesPlugin::_on_scattering_spinbox_changed));
scatter_controls_container->add_child(scatter_spinbox);
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index 912fdb03a9..e56541b50d 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -120,10 +120,9 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_bind_methods() {
}
void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::edit(Ref<TileSet> p_tile_set, TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id) {
- ERR_FAIL_COND(!p_tile_set.is_valid());
ERR_FAIL_COND(!p_tile_set_atlas_source);
ERR_FAIL_COND(p_source_id < 0);
- ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_atlas_source);
+ ERR_FAIL_COND(p_tile_set.is_valid() && p_tile_set->get_source(p_source_id) != p_tile_set_atlas_source);
if (p_tile_set == tile_set && p_tile_set_atlas_source == tile_set_atlas_source && p_source_id == source_id) {
return;
@@ -611,6 +610,10 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() {
tile_data_editors_tree->clear();
+ if (tile_set.is_null()) {
+ return;
+ }
+
TreeItem *root = tile_data_editors_tree->create_item();
TreeItem *group;
@@ -919,6 +922,10 @@ void TileSetAtlasSourceEditor::_update_atlas_view() {
alternative_tiles_control->get_child(i)->queue_free();
}
+ if (tile_set.is_null()) {
+ return;
+ }
+
Vector2i pos;
Vector2 texture_region_base_size = tile_set_atlas_source->get_texture_region_size();
int texture_region_base_size_min = MIN(texture_region_base_size.x, texture_region_base_size.y);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 5d66be3853..dc019d8e7c 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1359,6 +1359,8 @@ void ProjectList::load_projects() {
create_project_item_control(i);
}
+ sort_projects();
+
set_v_scroll(0);
update_icons_async();
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 13c7a8202c..afb8e62eea 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -1255,6 +1255,30 @@ Vector3 CSGBox3D::get_size() const {
return size;
}
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+bool CSGBox3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "width") {
+ size.x = p_value;
+ _make_dirty();
+ update_gizmos();
+ return true;
+ } else if (p_name == "height") {
+ size.y = p_value;
+ _make_dirty();
+ update_gizmos();
+ return true;
+ } else if (p_name == "depth") {
+ size.z = p_value;
+ _make_dirty();
+ update_gizmos();
+ return true;
+ } else {
+ return false;
+ }
+}
+#endif
+
void CSGBox3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index 9012c37679..c244107bfb 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -248,6 +248,10 @@ class CSGBox3D : public CSGPrimitive3D {
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
public:
void set_size(const Vector3 &p_size);
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 923b2fe30d..0b7e4e50e6 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -4,7 +4,7 @@
Built-in GDScript functions.
</brief_description>
<description>
- A list of GDScript-specific utility functions accessed in any script.
+ A list of GDScript-specific utility functions and annotations accessible from any script.
For the list of the global functions and constants see [@GlobalScope].
</description>
<tutorials>
@@ -20,7 +20,7 @@
<description>
Returns a [Color] constructed from red ([param r8]), green ([param g8]), blue ([param b8]), and optionally alpha ([param a8]) integer channels, each divided by [code]255.0[/code] for their final value.
[codeblock]
- var red = Color8(255, 0, 0) # Same as Color(1, 0, 0)
+ var red = Color8(255, 0, 0) # Same as Color(1, 0, 0).
var dark_blue = Color8(0, 0, 51) # Same as Color(0, 0, 0.2).
var my_color = Color8(306, 255, 0, 102) # Same as Color(1.2, 1, 0, 0.4).
[/codeblock]
@@ -37,10 +37,10 @@
[codeblock]
# Imagine we always want speed to be between 0 and 20.
var speed = -10
- assert(speed &lt; 20) # True, the program will continue
- assert(speed &gt;= 0) # False, the program will stop
- assert(speed &gt;= 0 and speed &lt; 20) # You can also combine the two conditional statements in one check
- assert(speed &lt; 20, "the speed limit is 20") # Show a message
+ assert(speed &lt; 20) # True, the program will continue.
+ assert(speed &gt;= 0) # False, the program will stop.
+ assert(speed &gt;= 0 and speed &lt; 20) # You can also combine the two conditional statements in one check.
+ assert(speed &lt; 20, "the speed limit is 20") # Show a message.
[/codeblock]
</description>
</method>
@@ -140,7 +140,7 @@
<param index="0" name="path" type="String" />
<description>
Returns a [Resource] from the filesystem located at the absolute [param path]. Unless it's already referenced elsewhere (such as in another script or in the scene), the resource is loaded from disk on function call, which might cause a slight delay, especially when loading large scenes. To avoid unnecessary delays when loading something multiple times, either store the resource in a variable or use [method preload].
- [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
+ [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing "Copy Path", or by dragging the file from the FileSystem dock into the current script.
[codeblock]
# Load a scene called "main" located in the root of the project directory and cache it in a variable.
var main = load("res://main.tscn") # main will contain a PackedScene resource.
@@ -155,7 +155,7 @@
<param index="0" name="path" type="String" />
<description>
Returns a [Resource] from the filesystem located at [param path]. During run-time, the resource is loaded when the script is being parsed. This function effectively acts as a reference to that resource. Note that this function requires [param path] to be a constant [String]. If you want to load a resource from a dynamic/variable path, use [method load].
- [b]Note:[/b] Resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
+ [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the Assets Panel and choosing "Copy Path", or by dragging the file from the FileSystem dock into the current script.
[codeblock]
# Create instance of a scene.
var diamond = preload("res://diamond.tscn").instantiate()
@@ -259,10 +259,12 @@
<annotation name="@export">
<return type="void" />
<description>
- Mark the following property as exported (editable in the Inspector dock and saved to disk). To control the type of the exported property use the type hint notation.
+ Mark the following property as exported (editable in the Inspector dock and saved to disk). To control the type of the exported property, use the type hint notation.
[codeblock]
+ @export var string = ""
@export var int_number = 5
@export var float_number: float = 5
+ @export var image : Image
[/codeblock]
</description>
</annotation>
@@ -273,20 +275,20 @@
Define a new category for the following exported properties. This helps to organize properties in the Inspector dock.
See also [constant PROPERTY_USAGE_CATEGORY].
[codeblock]
- @export_category("My Properties")
- @export var number = 3
- @export var string = ""
+ @export_category("Statistics")
+ @export var hp = 30
+ @export var speed = 1.25
[/codeblock]
- [b]Note:[/b] Categories in the property list are supposed to indicate different base types, so the use of this annotation is not encouraged. See [annotation @export_group] and [annotation @export_subgroup] instead.
+ [b]Note:[/b] Categories in the Inspector dock's list usually divide properties coming from different classes (Node, Node2D, Sprite, etc.). For better clarity, it's recommended to use [annotation @export_group] and [annotation @export_subgroup], instead.
</description>
</annotation>
<annotation name="@export_color_no_alpha">
<return type="void" />
<description>
- Export a [Color] property without transparency (its alpha fixed as [code]1.0[/code]).
+ Export a [Color] property without allowing its transparency ([member Color.a]) to be edited.
See also [constant PROPERTY_HINT_COLOR_NO_ALPHA].
[codeblock]
- @export_color_no_alpha var modulate_color: Color
+ @export_color_no_alpha var dye_color : Color
[/codeblock]
</description>
</annotation>
@@ -296,7 +298,7 @@
Export a [String] property as a path to a directory. The path will be limited to the project folder and its subfolders. See [annotation @export_global_dir] to allow picking from the entire filesystem.
See also [constant PROPERTY_HINT_DIR].
[codeblock]
- @export_dir var sprite_folder: String
+ @export_dir var sprite_folder_path: String
[/codeblock]
</description>
</annotation>
@@ -343,8 +345,8 @@
If [param filter] is provided, only matching files will be available for picking.
See also [constant PROPERTY_HINT_FILE].
[codeblock]
- @export_file var sound_effect_file: String
- @export_file("*.txt") var notes_file: String
+ @export_file var sound_effect_path: String
+ @export_file("*.txt") var notes_path: String
[/codeblock]
</description>
</annotation>
@@ -436,10 +438,10 @@
<annotation name="@export_global_dir">
<return type="void" />
<description>
- Export a [String] property as a path to a directory. The path can be picked from the entire filesystem. See [annotation @export_dir] to limit it to the project folder and its subfolders.
+ Export a [String] property as an absolute path to a directory. The path can be picked from the entire filesystem. See [annotation @export_dir] to limit it to the project folder and its subfolders.
See also [constant PROPERTY_HINT_GLOBAL_DIR].
[codeblock]
- @export_global_dir var sprite_folder: String
+ @export_global_dir var sprite_folder_path: String
[/codeblock]
</description>
</annotation>
@@ -447,12 +449,12 @@
<return type="void" />
<param index="0" name="filter" type="String" default="&quot;&quot;" />
<description>
- Export a [String] property as a path to a file. The path can be picked from the entire filesystem. See [annotation @export_file] to limit it to the project folder and its subfolders.
+ Export a [String] property as an absolute path to a file. The path can be picked from the entire filesystem. See [annotation @export_file] to limit it to the project folder and its subfolders.
If [param filter] is provided, only matching files will be available for picking.
See also [constant PROPERTY_HINT_GLOBAL_FILE].
[codeblock]
- @export_global_file var sound_effect_file: String
- @export_global_file("*.txt") var notes_file: String
+ @export_global_file var sound_effect_path: String
+ @export_global_file("*.txt") var notes_path: String
[/codeblock]
</description>
</annotation>
@@ -466,13 +468,13 @@
Groups cannot be nested, use [annotation @export_subgroup] to add subgroups within groups.
See also [constant PROPERTY_USAGE_GROUP].
[codeblock]
- @export_group("My Properties")
- @export var number = 3
- @export var string = ""
+ @export_group("Racer Properties")
+ @export var nickname = "Nick"
+ @export var age = 26
- @export_group("Prefixed Properties", "prefix_")
- @export var prefix_number = 3
- @export var prefix_string = ""
+ @export_group("Car Properties", "car_")
+ @export var car_label = "Speedy"
+ @export var car_number = 3
@export_group("", "")
@export var ungrouped_number = 3
@@ -544,13 +546,13 @@
Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. Subgroups work exactly like groups, except they need a parent group to exist. See [annotation @export_group].
See also [constant PROPERTY_USAGE_SUBGROUP].
[codeblock]
- @export_group("My Properties")
- @export var number = 3
- @export var string = ""
+ @export_group("Racer Properties")
+ @export var nickname = "Nick"
+ @export var age = 26
- @export_subgroup("My Prefixed Properties", "prefix_")
- @export var prefix_number = 3
- @export var prefix_string = ""
+ @export_subgroup("Car Properties", "car_")
+ @export var car_label = "Speedy"
+ @export var car_number = 3
[/codeblock]
[b]Note:[/b] Subgroups cannot be nested, they only provide one extra level of depth. Just like the next group ends the previous group, so do the subsequent subgroups.
</description>
@@ -571,7 +573,7 @@
<annotation name="@onready">
<return type="void" />
<description>
- Mark the following property as assigned on [Node]'s ready state change. Values for these properties are not assigned immediately upon the node's creation, and instead are computed and stored right before [method Node._ready].
+ Mark the following property as assigned when the [Node] is ready. Values for these properties are not assigned immediately when the node is initialized ([method Object._init]), and instead are computed and stored right before [method Node._ready].
[codeblock]
@onready var character_name: Label = $Label
[/codeblock]
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index de0dacece3..8d09249125 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -4278,11 +4278,15 @@ Variant GDScriptAnalyzer::make_variable_default_value(GDScriptParser::VariableNo
}
} else {
GDScriptParser::DataType datatype = p_variable->get_datatype();
- if (datatype.is_hard_type() && datatype.kind == GDScriptParser::DataType::BUILTIN && datatype.builtin_type != Variant::OBJECT) {
- if (datatype.builtin_type == Variant::ARRAY && datatype.has_container_element_type()) {
- result = make_array_from_element_datatype(datatype.get_container_element_type());
- } else {
- VariantInternal::initialize(&result, datatype.builtin_type);
+ if (datatype.is_hard_type()) {
+ if (datatype.kind == GDScriptParser::DataType::BUILTIN && datatype.builtin_type != Variant::OBJECT) {
+ if (datatype.builtin_type == Variant::ARRAY && datatype.has_container_element_type()) {
+ result = make_array_from_element_datatype(datatype.get_container_element_type());
+ } else {
+ VariantInternal::initialize(&result, datatype.builtin_type);
+ }
+ } else if (datatype.kind == GDScriptParser::DataType::ENUM) {
+ result = 0;
}
}
}
diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
index 092ae49d00..7416ecd87a 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
+++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd
@@ -86,7 +86,8 @@ func test():
var typed_int := 556
var converted_floats: Array[float] = [typed_int]
- assert(str(converted_floats) == '[556]')
+ converted_floats.push_back(498)
+ assert(str(converted_floats) == '[556, 498]')
assert(converted_floats.get_typed_builtin() == TYPE_FLOAT)
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 028028a103..e3ba290eb2 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3285,7 +3285,6 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
tex.instantiate();
tex->set_name(img->get_name());
tex->set_keep_compressed_buffer(true);
- p_state->source_images.push_back(img);
tex->create_from_image(img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
p_state->images.push_back(tex);
p_state->source_images.push_back(img);
diff --git a/modules/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp
index 3466cb10df..68b6bc4a24 100644
--- a/modules/multiplayer/scene_replication_interface.cpp
+++ b/modules/multiplayer/scene_replication_interface.cpp
@@ -742,6 +742,7 @@ Error SceneReplicationInterface::on_sync_receive(int p_from, const uint8_t *p_bu
ofs += 4;
uint32_t size = decode_uint32(&p_buffer[ofs]);
ofs += 4;
+ ERR_FAIL_COND_V(size > uint32_t(p_buffer_len - ofs), ERR_INVALID_DATA);
MultiplayerSynchronizer *sync = nullptr;
if (net_id & 0x80000000) {
sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_path_cache()->get_cached_object(p_from, net_id & 0x7FFFFFFF));
@@ -756,14 +757,15 @@ Error SceneReplicationInterface::on_sync_receive(int p_from, const uint8_t *p_bu
}
Node *node = sync->get_root_node();
if (sync->get_multiplayer_authority() != p_from || !node) {
- ERR_CONTINUE(true);
+ // Not valid for me.
+ ofs += size;
+ ERR_CONTINUE_MSG(true, "Ignoring sync data from non-authority or for missing node.");
}
if (!sync->update_inbound_sync_time(time)) {
// State is too old.
ofs += size;
continue;
}
- ERR_FAIL_COND_V(size > uint32_t(p_buffer_len - ofs), ERR_BUG);
const List<NodePath> props = sync->get_replication_config()->get_sync_properties();
Vector<Variant> vars;
vars.resize(props.size());
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index c3cb1c5f13..79e8c3a6d6 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -757,7 +757,7 @@ COMMAND_1(free, RID, p_object) {
agent_owner.free(p_object);
} else {
- ERR_FAIL_COND("Invalid ID.");
+ ERR_FAIL_COND("Attempted to free a NavigationServer RID that did not exist (or was already freed).");
}
}
diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
index aaeb2025ee..e0d17277ef 100644
--- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
+++ b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
@@ -16,7 +16,7 @@
<param index="1" name="tls_client_options" type="TLSOptions" default="null" />
<description>
Starts a new multiplayer client connecting to the given [param url]. TLS certificates will be verified against the hostname when connecting using the [code]wss://[/code] protocol. You can pass the optional [param tls_client_options] parameter to customize the trusted certification authorities, or disable the common name verification. See [method TLSOptions.client] and [method TLSOptions.client_unsafe].
- [b]Note[/b]: It is recommended to specify the scheme part of the URL, i.e. the [param url] should start with either [code]ws://[/code] or [code]wss://[/code].
+ [b]Note:[/b] It is recommended to specify the scheme part of the URL, i.e. the [param url] should start with either [code]ws://[/code] or [code]wss://[/code].
</description>
</method>
<method name="create_server">
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 525c62fbf2..5d70af56bd 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -4936,6 +4936,11 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
win_rect.position = wpos;
}
+ // Position and size hints are set from these values before they are updated to the actual
+ // window size, so we need to initialize them here.
+ wd.position = win_rect.position;
+ wd.size = win_rect.size;
+
{
wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), win_rect.position.x, win_rect.position.y, win_rect.size.width > 0 ? win_rect.size.width : 1, win_rect.size.height > 0 ? win_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 2e0b16388f..11e59d9858 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -754,8 +754,9 @@ TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() {
void TileMap::set_navigation_map(int p_layer, RID p_map) {
ERR_FAIL_INDEX(p_layer, (int)layers.size());
-
+ ERR_FAIL_COND_MSG(!is_inside_tree(), "A TileMap navigation map can only be changed while inside the SceneTree.");
layers[p_layer].navigation_map = p_map;
+ layers[p_layer].uses_world_navigation_map = p_map == get_world_2d()->get_navigation_map();
}
RID TileMap::get_navigation_map(int p_layer) const {
@@ -1111,10 +1112,12 @@ void TileMap::_navigation_update_layer(int p_layer) {
if (p_layer == 0 && is_inside_tree()) {
// Use the default World2D navigation map for the first layer when empty.
layers[p_layer].navigation_map = get_world_2d()->get_navigation_map();
+ layers[p_layer].uses_world_navigation_map = true;
} else {
RID new_layer_map = NavigationServer2D::get_singleton()->map_create();
NavigationServer2D::get_singleton()->map_set_active(new_layer_map, true);
layers[p_layer].navigation_map = new_layer_map;
+ layers[p_layer].uses_world_navigation_map = false;
}
}
}
@@ -1124,7 +1127,7 @@ void TileMap::_navigation_cleanup_layer(int p_layer) {
ERR_FAIL_NULL(NavigationServer2D::get_singleton());
if (layers[p_layer].navigation_map.is_valid()) {
- if (is_inside_tree() && layers[p_layer].navigation_map == get_world_2d()->get_navigation_map()) {
+ if (layers[p_layer].uses_world_navigation_map) {
// Do not delete the World2D default navigation map.
return;
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 62d7612be2..e9c1cb0c11 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -212,6 +212,7 @@ private:
HashMap<Vector2i, TileMapQuadrant> quadrant_map;
SelfList<TileMapQuadrant>::List dirty_quadrant_list;
RID navigation_map;
+ bool uses_world_navigation_map = false;
};
LocalVector<TileMapLayer> layers;
int selected_layer = -1;
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index e122adcc8c..6f2717fd41 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -31,7 +31,7 @@
#include "decal.h"
void Decal::set_size(const Vector3 &p_size) {
- size = p_size;
+ size = Vector3(MAX(0.001, p_size.x), MAX(0.001, p_size.y), MAX(0.001, p_size.z));
RS::get_singleton()->decal_set_size(decal, p_size);
update_gizmos();
}
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index b084cb5bea..e2f7ec860c 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -2856,7 +2856,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
const int caret_line = get_caret_line();
const int caret_column = get_caret_column();
const String line = get_line(caret_line);
- ERR_FAIL_INDEX_MSG(caret_column - 1, line.length(), "Caret column exceeds line length.");
+ ERR_FAIL_INDEX_MSG(caret_column, line.length() + 1, "Caret column exceeds line length.");
if (caret_column > 0 && line[caret_column - 1] == '(' && !code_completion_forced) {
cancel_code_completion();
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 2ea1b93810..432004dedc 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -36,7 +36,7 @@
void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> key = p_event;
- if (key.is_valid() && key->is_pressed() && key->get_keycode() == Key::ESCAPE) {
+ if (get_flag(FLAG_POPUP) && key.is_valid() && key->is_pressed() && key->get_keycode() == Key::ESCAPE) {
_close_pressed();
}
}
@@ -102,12 +102,17 @@ void Popup::_notification(int p_what) {
}
} break;
- case NOTIFICATION_WM_CLOSE_REQUEST:
- case NOTIFICATION_APPLICATION_FOCUS_OUT: {
+ case NOTIFICATION_WM_CLOSE_REQUEST: {
if (!is_in_edited_scene_root()) {
_close_pressed();
}
} break;
+
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
+ if (!is_in_edited_scene_root() && get_flag(FLAG_POPUP)) {
+ _close_pressed();
+ }
+ } break;
}
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 23b7c072be..126b1d54fc 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -166,6 +166,24 @@ ViewportTexture::~ViewportTexture() {
}
void Viewport::_sub_window_update_order() {
+ if (gui.sub_windows.size() < 2) {
+ return;
+ }
+
+ if (!gui.sub_windows[gui.sub_windows.size() - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) {
+ int index = gui.sub_windows.size() - 1;
+
+ while (index > 0 && gui.sub_windows[index - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) {
+ --index;
+ }
+
+ if (index != (gui.sub_windows.size() - 1)) {
+ SubWindow sw = gui.sub_windows[gui.sub_windows.size() - 1];
+ gui.sub_windows.remove_at(gui.sub_windows.size() - 1);
+ gui.sub_windows.insert(index, sw);
+ }
+ }
+
for (int i = 0; i < gui.sub_windows.size(); i++) {
RS::get_singleton()->canvas_item_set_draw_index(gui.sub_windows[i].canvas_item, i);
}
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 663dd586c0..b79a9ba444 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -569,6 +569,12 @@ void Window::_update_from_window() {
void Window::_clear_window() {
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
+ DisplayServer::get_singleton()->window_set_rect_changed_callback(Callable(), window_id);
+ DisplayServer::get_singleton()->window_set_window_event_callback(Callable(), window_id);
+ DisplayServer::get_singleton()->window_set_input_event_callback(Callable(), window_id);
+ DisplayServer::get_singleton()->window_set_input_text_callback(Callable(), window_id);
+ DisplayServer::get_singleton()->window_set_drop_files_callback(Callable(), window_id);
+
if (transient_parent && transient_parent->window_id != DisplayServer::INVALID_WINDOW_ID) {
DisplayServer::get_singleton()->window_set_transient(window_id, DisplayServer::INVALID_WINDOW_ID);
}
@@ -978,17 +984,13 @@ void Window::_update_viewport_size() {
Size2 margin;
Size2 offset;
- //black bars and margin
+
if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.x < video_mode.x) {
margin.x = Math::round((video_mode.x - screen_size.x) / 2.0);
- //RenderingServer::get_singleton()->black_bars_set_margins(margin.x, 0, margin.x, 0);
offset.x = Math::round(margin.x * viewport_size.y / screen_size.y);
} else if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.y < video_mode.y) {
margin.y = Math::round((video_mode.y - screen_size.y) / 2.0);
- //RenderingServer::get_singleton()->black_bars_set_margins(0, margin.y, 0, margin.y);
offset.y = Math::round(margin.y * viewport_size.x / screen_size.x);
- } else {
- //RenderingServer::get_singleton()->black_bars_set_margins(0, 0, 0, 0);
}
switch (content_scale_mode) {
@@ -1115,6 +1117,7 @@ void Window::_notification(int p_what) {
position = DisplayServer::get_singleton()->window_get_position(window_id);
size = DisplayServer::get_singleton()->window_get_size(window_id);
}
+ _update_window_size(); // Inform DisplayServer of minimum and maximum size.
_update_viewport_size(); // Then feed back to the viewport.
_update_window_callbacks();
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index cf9baa2907..a7b53244e2 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -526,6 +526,9 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
vc = indices.size();
ir = indices.ptrw();
has_indices = true;
+ } else {
+ // Ensure there are enough vertices to construct at least one triangle.
+ ERR_FAIL_COND_V(vertices.size() % 3 != 0, Ref<ArrayMesh>());
}
HashMap<Vector3, Vector3> normal_accum;
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 02460bdb18..fbe97b9acb 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -115,7 +115,6 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free);
ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active);
- ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer3D::process);
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 3b5fbbced8..bbaec8be2b 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -30,6 +30,7 @@
#include "godot_step_2d.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/os.h"
#define BODY_ISLAND_COUNT_RESERVE 128
diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h
index 75eeba4a3d..c08c6379de 100644
--- a/servers/physics_2d/godot_step_2d.h
+++ b/servers/physics_2d/godot_step_2d.h
@@ -33,7 +33,6 @@
#include "godot_space_2d.h"
-#include "core/object/worker_thread_pool.h"
#include "core/templates/local_vector.h"
class GodotStep2D {
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index 4119c58897..d09a3b4e6d 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -32,6 +32,7 @@
#include "godot_joint_3d.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/os.h"
#define BODY_ISLAND_COUNT_RESERVE 128
diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h
index be7266b264..1c9b0af422 100644
--- a/servers/physics_3d/godot_step_3d.h
+++ b/servers/physics_3d/godot_step_3d.h
@@ -33,7 +33,6 @@
#include "godot_space_3d.h"
-#include "core/object/worker_thread_pool.h"
#include "core/templates/local_vector.h"
class GodotStep3D {
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index b273345ab3..6d5e55ee6a 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -30,6 +30,7 @@
#include "render_forward_clustered.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index f9529de6dd..45fe067a6f 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -30,6 +30,7 @@
#include "render_forward_mobile.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 5776414b14..efd961fd89 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1110,6 +1110,8 @@ float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const {
}
TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) {
+ ERR_FAIL_COND_V_MSG(p_image_size.width <= 0, TypedArray<Image>(), "Image width must be greater than 0.");
+ ERR_FAIL_COND_V_MSG(p_image_size.height <= 0, TypedArray<Image>(), "Image height must be greater than 0.");
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tf.width = p_image_size.width; // Always 64x64
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 533a912a34..c85ece6366 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -33,6 +33,7 @@
#include "core/io/compression.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
+#include "core/object/worker_thread_pool.h"
#include "core/version.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index d631a89dd2..6f67d628a9 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -2803,6 +2803,7 @@ void MaterialStorage::material_set_render_priority(RID p_material, int priority)
if (material->data) {
material->data->set_render_priority(priority);
}
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
bool MaterialStorage::material_is_animated(RID p_material) {
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 7d2cd12959..813c1fa4ff 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -31,6 +31,7 @@
#include "renderer_scene_cull.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/os.h"
#include "rendering_server_default.h"
#include "rendering_server_globals.h"
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index c725d93a82..0e2a3c682d 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -31,6 +31,7 @@
#include "renderer_viewport.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "renderer_canvas_cull.h"
#include "renderer_scene_cull.h"
#include "rendering_server_globals.h"
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 4f52a63b2f..a3bdf7d146 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -31,6 +31,7 @@
#ifndef RENDERING_SERVER_DEFAULT_H
#define RENDERING_SERVER_DEFAULT_H
+#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/hash_map.h"
#include "renderer_canvas_cull.h"
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 848b6d01d4..05b1a8f87a 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -31,6 +31,7 @@
#include "rendering_server.h"
#include "core/config/project_settings.h"
+#include "core/object/worker_thread_pool.h"
#include "core/variant/typed_array.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering/shader_language.h"
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 1f9bff7c3f..b53b7d2ff9 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -35,7 +35,6 @@
#include "core/math/geometry_3d.h"
#include "core/math/transform_2d.h"
#include "core/object/class_db.h"
-#include "core/object/worker_thread_pool.h"
#include "core/templates/rid.h"
#include "core/variant/typed_array.h"
#include "core/variant/variant.h"