summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml7
-rw-r--r--core/extension/extension_api_dump.cpp131
-rw-r--r--core/extension/gdextension.cpp22
-rw-r--r--core/extension/gdextension.h24
-rw-r--r--core/extension/gdextension_interface.cpp16
-rw-r--r--core/extension/gdextension_interface.h20
-rw-r--r--core/io/image.cpp13
-rw-r--r--core/object/object.cpp2
-rw-r--r--doc/classes/@GlobalScope.xml2
-rw-r--r--doc/classes/AABB.xml2
-rw-r--r--doc/classes/AESContext.xml4
-rw-r--r--doc/classes/AStar2D.xml9
-rw-r--r--doc/classes/AStar3D.xml6
-rw-r--r--doc/classes/AStarGrid2D.xml7
-rw-r--r--doc/classes/AcceptDialog.xml4
-rw-r--r--doc/classes/AnimatableBody2D.xml7
-rw-r--r--doc/classes/AnimatableBody3D.xml8
-rw-r--r--doc/classes/AnimationNode.xml34
-rw-r--r--doc/classes/AnimationNodeAdd2.xml4
-rw-r--r--doc/classes/AnimationNodeAdd3.xml9
-rw-r--r--doc/classes/AnimationNodeBlend2.xml3
-rw-r--r--doc/classes/AnimationNodeBlend3.xml11
-rw-r--r--doc/classes/AnimationNodeBlendSpace1D.xml2
-rw-r--r--doc/classes/AnimationNodeBlendSpace2D.xml2
-rw-r--r--doc/classes/AnimationNodeBlendTree.xml22
-rw-r--r--doc/classes/AnimationNodeOneShot.xml2
-rw-r--r--doc/classes/AnimationNodeStateMachine.xml20
-rw-r--r--doc/classes/AnimationNodeSub2.xml15
-rw-r--r--doc/classes/AnimationNodeTimeSeek.xml2
-rw-r--r--doc/classes/AnimationNodeTransition.xml4
-rw-r--r--doc/classes/Area2D.xml7
-rw-r--r--doc/classes/Area3D.xml10
-rw-r--r--doc/classes/Array.xml5
-rw-r--r--doc/classes/AspectRatioContainer.xml6
-rw-r--r--doc/classes/AudioStreamPlaybackPolyphonic.xml2
-rw-r--r--doc/classes/BaseButton.xml4
-rw-r--r--doc/classes/Basis.xml10
-rw-r--r--doc/classes/BoxContainer.xml6
-rw-r--r--doc/classes/BoxShape3D.xml6
-rw-r--r--doc/classes/Button.xml7
-rw-r--r--doc/classes/ButtonGroup.xml6
-rw-r--r--doc/classes/Callable.xml2
-rw-r--r--doc/classes/CanvasItem.xml12
-rw-r--r--doc/classes/CanvasLayer.xml7
-rw-r--r--doc/classes/CanvasModulate.xml4
-rw-r--r--doc/classes/CapsuleShape2D.xml6
-rw-r--r--doc/classes/CapsuleShape3D.xml6
-rw-r--r--doc/classes/CenterContainer.xml6
-rw-r--r--doc/classes/CharacterBody2D.xml7
-rw-r--r--doc/classes/CharacterBody3D.xml8
-rw-r--r--doc/classes/CheckBox.xml6
-rw-r--r--doc/classes/CheckButton.xml4
-rw-r--r--doc/classes/CircleShape2D.xml6
-rw-r--r--doc/classes/ClassDB.xml2
-rw-r--r--doc/classes/CodeEdit.xml6
-rw-r--r--doc/classes/CodeHighlighter.xml4
-rw-r--r--doc/classes/CollisionObject2D.xml4
-rw-r--r--doc/classes/CollisionObject3D.xml6
-rw-r--r--doc/classes/CollisionPolygon2D.xml7
-rw-r--r--doc/classes/CollisionPolygon3D.xml7
-rw-r--r--doc/classes/CollisionShape2D.xml5
-rw-r--r--doc/classes/CollisionShape3D.xml7
-rw-r--r--doc/classes/Color.xml8
-rw-r--r--doc/classes/ColorPicker.xml6
-rw-r--r--doc/classes/ColorPickerButton.xml4
-rw-r--r--doc/classes/ColorRect.xml14
-rw-r--r--doc/classes/ConcavePolygonShape2D.xml14
-rw-r--r--doc/classes/ConcavePolygonShape3D.xml14
-rw-r--r--doc/classes/ConeTwistJoint3D.xml6
-rw-r--r--doc/classes/ConfirmationDialog.xml4
-rw-r--r--doc/classes/Container.xml7
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/ConvexPolygonShape2D.xml11
-rw-r--r--doc/classes/ConvexPolygonShape3D.xml11
-rw-r--r--doc/classes/Crypto.xml6
-rw-r--r--doc/classes/CylinderShape3D.xml6
-rw-r--r--doc/classes/DampedSpringJoint2D.xml4
-rw-r--r--doc/classes/Dictionary.xml8
-rw-r--r--doc/classes/DirAccess.xml6
-rw-r--r--doc/classes/DisplayServer.xml132
-rw-r--r--doc/classes/EditorFileDialog.xml2
-rw-r--r--doc/classes/EditorInterface.xml2
-rw-r--r--doc/classes/EditorNode3DGizmoPlugin.xml2
-rw-r--r--doc/classes/EditorProperty.xml4
-rw-r--r--doc/classes/EditorResourcePreview.xml4
-rw-r--r--doc/classes/EditorSettings.xml5
-rw-r--r--doc/classes/EditorSyntaxHighlighter.xml4
-rw-r--r--doc/classes/Engine.xml2
-rw-r--r--doc/classes/FileAccess.xml8
-rw-r--r--doc/classes/FileDialog.xml4
-rw-r--r--doc/classes/FileSystemDock.xml4
-rw-r--r--doc/classes/FlowContainer.xml6
-rw-r--r--doc/classes/Font.xml4
-rw-r--r--doc/classes/FontFile.xml6
-rw-r--r--doc/classes/FontVariation.xml4
-rw-r--r--doc/classes/Generic6DOFJoint3D.xml5
-rw-r--r--doc/classes/Geometry2D.xml4
-rw-r--r--doc/classes/Geometry3D.xml4
-rw-r--r--doc/classes/Gradient.xml15
-rw-r--r--doc/classes/GradientTexture2D.xml3
-rw-r--r--doc/classes/GraphEdit.xml7
-rw-r--r--doc/classes/GraphNode.xml9
-rw-r--r--doc/classes/GridContainer.xml9
-rw-r--r--doc/classes/GrooveJoint2D.xml4
-rw-r--r--doc/classes/HBoxContainer.xml6
-rw-r--r--doc/classes/HFlowContainer.xml5
-rw-r--r--doc/classes/HScrollBar.xml4
-rw-r--r--doc/classes/HSeparator.xml4
-rw-r--r--doc/classes/HSlider.xml5
-rw-r--r--doc/classes/HSplitContainer.xml6
-rw-r--r--doc/classes/HTTPClient.xml2
-rw-r--r--doc/classes/HashingContext.xml4
-rw-r--r--doc/classes/HeightMapShape3D.xml6
-rw-r--r--doc/classes/HingeJoint3D.xml4
-rw-r--r--doc/classes/Input.xml6
-rw-r--r--doc/classes/InputEvent.xml6
-rw-r--r--doc/classes/InputEventAction.xml6
-rw-r--r--doc/classes/InputEventFromWindow.xml2
-rw-r--r--doc/classes/InputEventGesture.xml5
-rw-r--r--doc/classes/InputEventJoypadButton.xml4
-rw-r--r--doc/classes/InputEventJoypadMotion.xml6
-rw-r--r--doc/classes/InputEventKey.xml8
-rw-r--r--doc/classes/InputEventMIDI.xml4
-rw-r--r--doc/classes/InputEventMagnifyGesture.xml7
-rw-r--r--doc/classes/InputEventMouse.xml4
-rw-r--r--doc/classes/InputEventMouseButton.xml5
-rw-r--r--doc/classes/InputEventMouseMotion.xml5
-rw-r--r--doc/classes/InputEventPanGesture.xml5
-rw-r--r--doc/classes/InputEventScreenDrag.xml6
-rw-r--r--doc/classes/InputEventScreenTouch.xml7
-rw-r--r--doc/classes/InputEventShortcut.xml4
-rw-r--r--doc/classes/InputEventWithModifiers.xml6
-rw-r--r--doc/classes/InputMap.xml4
-rw-r--r--doc/classes/ItemList.xml8
-rw-r--r--doc/classes/Joint2D.xml4
-rw-r--r--doc/classes/Joint3D.xml4
-rw-r--r--doc/classes/KinematicCollision2D.xml6
-rw-r--r--doc/classes/KinematicCollision3D.xml6
-rw-r--r--doc/classes/Label.xml5
-rw-r--r--doc/classes/Label3D.xml4
-rw-r--r--doc/classes/LabelSettings.xml4
-rw-r--r--doc/classes/LineEdit.xml21
-rw-r--r--doc/classes/LinkButton.xml4
-rw-r--r--doc/classes/MarginContainer.xml8
-rw-r--r--doc/classes/MenuBar.xml4
-rw-r--r--doc/classes/MenuButton.xml5
-rw-r--r--doc/classes/Mesh.xml8
-rw-r--r--doc/classes/MissingNode.xml3
-rw-r--r--doc/classes/MissingResource.xml3
-rw-r--r--doc/classes/Mutex.xml15
-rw-r--r--doc/classes/NavigationAgent2D.xml7
-rw-r--r--doc/classes/NavigationAgent3D.xml7
-rw-r--r--doc/classes/NavigationLink2D.xml4
-rw-r--r--doc/classes/NavigationLink3D.xml4
-rw-r--r--doc/classes/NavigationMesh.xml2
-rw-r--r--doc/classes/NavigationPathQueryParameters2D.xml4
-rw-r--r--doc/classes/NavigationPathQueryParameters3D.xml4
-rw-r--r--doc/classes/NavigationPathQueryResult2D.xml4
-rw-r--r--doc/classes/NavigationPathQueryResult3D.xml4
-rw-r--r--doc/classes/NavigationPolygon.xml2
-rw-r--r--doc/classes/NavigationRegion2D.xml6
-rw-r--r--doc/classes/NavigationRegion3D.xml4
-rw-r--r--doc/classes/NavigationServer2D.xml14
-rw-r--r--doc/classes/NavigationServer3D.xml12
-rw-r--r--doc/classes/NinePatchRect.xml4
-rw-r--r--doc/classes/Node.xml2
-rw-r--r--doc/classes/NodePath.xml3
-rw-r--r--doc/classes/OS.xml8
-rw-r--r--doc/classes/Object.xml12
-rw-r--r--doc/classes/OptimizedTranslation.xml4
-rw-r--r--doc/classes/OptionButton.xml6
-rw-r--r--doc/classes/PackedDataContainerRef.xml2
-rw-r--r--doc/classes/Panel.xml6
-rw-r--r--doc/classes/PanelContainer.xml6
-rw-r--r--doc/classes/PhysicsBody2D.xml4
-rw-r--r--doc/classes/PhysicsBody3D.xml6
-rw-r--r--doc/classes/PhysicsDirectBodyState2D.xml4
-rw-r--r--doc/classes/PhysicsDirectBodyState2DExtension.xml3
-rw-r--r--doc/classes/PhysicsDirectBodyState3D.xml4
-rw-r--r--doc/classes/PhysicsDirectBodyState3DExtension.xml3
-rw-r--r--doc/classes/PhysicsDirectSpaceState2D.xml4
-rw-r--r--doc/classes/PhysicsDirectSpaceState2DExtension.xml3
-rw-r--r--doc/classes/PhysicsDirectSpaceState3D.xml4
-rw-r--r--doc/classes/PhysicsDirectSpaceState3DExtension.xml3
-rw-r--r--doc/classes/PhysicsMaterial.xml4
-rw-r--r--doc/classes/PhysicsPointQueryParameters2D.xml4
-rw-r--r--doc/classes/PhysicsPointQueryParameters3D.xml4
-rw-r--r--doc/classes/PhysicsRayQueryParameters2D.xml4
-rw-r--r--doc/classes/PhysicsRayQueryParameters3D.xml4
-rw-r--r--doc/classes/PhysicsServer2D.xml8
-rw-r--r--doc/classes/PhysicsServer2DExtension.xml3
-rw-r--r--doc/classes/PhysicsServer2DManager.xml4
-rw-r--r--doc/classes/PhysicsServer3D.xml11
-rw-r--r--doc/classes/PhysicsServer3DExtension.xml3
-rw-r--r--doc/classes/PhysicsServer3DManager.xml4
-rw-r--r--doc/classes/PhysicsServer3DRenderingServerHandler.xml1
-rw-r--r--doc/classes/PhysicsShapeQueryParameters2D.xml4
-rw-r--r--doc/classes/PhysicsShapeQueryParameters3D.xml4
-rw-r--r--doc/classes/PhysicsTestMotionParameters2D.xml4
-rw-r--r--doc/classes/PhysicsTestMotionParameters3D.xml4
-rw-r--r--doc/classes/PhysicsTestMotionResult2D.xml4
-rw-r--r--doc/classes/PhysicsTestMotionResult3D.xml4
-rw-r--r--doc/classes/PinJoint2D.xml4
-rw-r--r--doc/classes/PinJoint3D.xml4
-rw-r--r--doc/classes/Plane.xml4
-rw-r--r--doc/classes/Popup.xml4
-rw-r--r--doc/classes/PopupMenu.xml9
-rw-r--r--doc/classes/PopupPanel.xml5
-rw-r--r--doc/classes/ProgressBar.xml4
-rw-r--r--doc/classes/ProjectSettings.xml8
-rw-r--r--doc/classes/Projection.xml4
-rw-r--r--doc/classes/RDPipelineColorBlendStateAttachment.xml4
-rw-r--r--doc/classes/RID.xml2
-rw-r--r--doc/classes/RandomNumberGenerator.xml7
-rw-r--r--doc/classes/Range.xml16
-rw-r--r--doc/classes/RayCast2D.xml11
-rw-r--r--doc/classes/RayCast3D.xml11
-rw-r--r--doc/classes/Rect2.xml2
-rw-r--r--doc/classes/Rect2i.xml2
-rw-r--r--doc/classes/RectangleShape2D.xml6
-rw-r--r--doc/classes/ReferenceRect.xml6
-rw-r--r--doc/classes/RenderingDevice.xml6
-rw-r--r--doc/classes/RenderingServer.xml10
-rw-r--r--doc/classes/Resource.xml4
-rw-r--r--doc/classes/ResourceImporter.xml4
-rw-r--r--doc/classes/ResourceLoader.xml4
-rw-r--r--doc/classes/ResourcePreloader.xml2
-rw-r--r--doc/classes/ResourceSaver.xml6
-rw-r--r--doc/classes/ResourceUID.xml7
-rw-r--r--doc/classes/RichTextEffect.xml4
-rw-r--r--doc/classes/RichTextLabel.xml8
-rw-r--r--doc/classes/RigidBody2D.xml12
-rw-r--r--doc/classes/RigidBody3D.xml10
-rw-r--r--doc/classes/SceneState.xml4
-rw-r--r--doc/classes/ScriptCreateDialog.xml2
-rw-r--r--doc/classes/ScriptEditor.xml1
-rw-r--r--doc/classes/ScriptEditorBase.xml2
-rw-r--r--doc/classes/ScrollBar.xml4
-rw-r--r--doc/classes/ScrollContainer.xml8
-rw-r--r--doc/classes/SegmentShape2D.xml5
-rw-r--r--doc/classes/Semaphore.xml13
-rw-r--r--doc/classes/SeparationRayShape2D.xml5
-rw-r--r--doc/classes/SeparationRayShape3D.xml5
-rw-r--r--doc/classes/Separator.xml4
-rw-r--r--doc/classes/Shape2D.xml5
-rw-r--r--doc/classes/Shape3D.xml5
-rw-r--r--doc/classes/ShapeCast2D.xml9
-rw-r--r--doc/classes/ShapeCast3D.xml9
-rw-r--r--doc/classes/Signal.xml2
-rw-r--r--doc/classes/Skeleton3D.xml6
-rw-r--r--doc/classes/Slider.xml5
-rw-r--r--doc/classes/SliderJoint3D.xml4
-rw-r--r--doc/classes/SoftBody3D.xml6
-rw-r--r--doc/classes/SphereShape3D.xml6
-rw-r--r--doc/classes/SpinBox.xml4
-rw-r--r--doc/classes/SplitContainer.xml6
-rw-r--r--doc/classes/SpringArm3D.xml7
-rw-r--r--doc/classes/StaticBody2D.xml10
-rw-r--r--doc/classes/StaticBody3D.xml11
-rw-r--r--doc/classes/StreamPeer.xml8
-rw-r--r--doc/classes/StreamPeerBuffer.xml4
-rw-r--r--doc/classes/StreamPeerGZIP.xml4
-rw-r--r--doc/classes/StreamPeerTCP.xml4
-rw-r--r--doc/classes/StreamPeerTLS.xml4
-rw-r--r--doc/classes/String.xml4
-rw-r--r--doc/classes/StringName.xml10
-rw-r--r--doc/classes/StyleBox.xml6
-rw-r--r--doc/classes/StyleBoxEmpty.xml4
-rw-r--r--doc/classes/StyleBoxFlat.xml8
-rw-r--r--doc/classes/StyleBoxLine.xml4
-rw-r--r--doc/classes/StyleBoxTexture.xml4
-rw-r--r--doc/classes/SubViewport.xml5
-rw-r--r--doc/classes/SubViewportContainer.xml8
-rw-r--r--doc/classes/SurfaceTool.xml2
-rw-r--r--doc/classes/SyntaxHighlighter.xml7
-rw-r--r--doc/classes/SystemFont.xml4
-rw-r--r--doc/classes/TabBar.xml4
-rw-r--r--doc/classes/TabContainer.xml9
-rw-r--r--doc/classes/TextEdit.xml4
-rw-r--r--doc/classes/TextLine.xml2
-rw-r--r--doc/classes/TextParagraph.xml2
-rw-r--r--doc/classes/TextServer.xml6
-rw-r--r--doc/classes/TextServerExtension.xml4
-rw-r--r--doc/classes/TextServerManager.xml12
-rw-r--r--doc/classes/TextureRect.xml4
-rw-r--r--doc/classes/Theme.xml4
-rw-r--r--doc/classes/ThemeDB.xml4
-rw-r--r--doc/classes/Thread.xml2
-rw-r--r--doc/classes/Time.xml2
-rw-r--r--doc/classes/Transform2D.xml4
-rw-r--r--doc/classes/Transform3D.xml4
-rw-r--r--doc/classes/Translation.xml4
-rw-r--r--doc/classes/TranslationServer.xml18
-rw-r--r--doc/classes/Tree.xml6
-rw-r--r--doc/classes/TreeItem.xml8
-rw-r--r--doc/classes/UndoRedo.xml10
-rw-r--r--doc/classes/VBoxContainer.xml6
-rw-r--r--doc/classes/VFlowContainer.xml5
-rw-r--r--doc/classes/VScrollBar.xml4
-rw-r--r--doc/classes/VSeparator.xml4
-rw-r--r--doc/classes/VSlider.xml5
-rw-r--r--doc/classes/VSplitContainer.xml6
-rw-r--r--doc/classes/Variant.xml5
-rw-r--r--doc/classes/Vector2.xml4
-rw-r--r--doc/classes/Vector2i.xml4
-rw-r--r--doc/classes/Vector3.xml4
-rw-r--r--doc/classes/Vector3i.xml4
-rw-r--r--doc/classes/Vector4.xml4
-rw-r--r--doc/classes/Vector4i.xml5
-rw-r--r--doc/classes/VehicleBody3D.xml9
-rw-r--r--doc/classes/VehicleWheel3D.xml6
-rw-r--r--doc/classes/VideoStreamPlayer.xml4
-rw-r--r--doc/classes/Viewport.xml4
-rw-r--r--doc/classes/ViewportTexture.xml12
-rw-r--r--doc/classes/WeakRef.xml4
-rw-r--r--doc/classes/Window.xml28
-rw-r--r--doc/classes/World2D.xml4
-rw-r--r--doc/classes/World3D.xml4
-rw-r--r--doc/classes/WorldBoundaryShape2D.xml5
-rw-r--r--doc/classes/WorldBoundaryShape3D.xml5
-rw-r--r--doc/classes/XMLParser.xml3
-rw-r--r--doc/classes/bool.xml86
-rw-r--r--doc/classes/float.xml8
-rw-r--r--doc/classes/int.xml2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp4
-rw-r--r--drivers/gles3/shader_gles3.cpp15
-rw-r--r--drivers/gles3/shader_gles3.h10
-rw-r--r--drivers/gles3/shaders/canvas.glsl12
-rw-r--r--drivers/gles3/storage/material_storage.cpp123
-rw-r--r--drivers/gles3/storage/texture_storage.cpp55
-rw-r--r--drivers/gles3/storage/texture_storage.h2
-rw-r--r--editor/code_editor.cpp1
-rw-r--r--editor/create_dialog.cpp17
-rw-r--r--editor/editor_builders.py1
-rw-r--r--editor/editor_data.cpp18
-rw-r--r--editor/editor_data.h6
-rw-r--r--editor/editor_help.cpp2
-rw-r--r--editor/editor_inspector.cpp20
-rw-r--r--editor/editor_inspector.h1
-rw-r--r--editor/editor_interface.h4
-rw-r--r--editor/editor_log.cpp1
-rw-r--r--editor/editor_node.cpp164
-rw-r--r--editor/editor_node.h7
-rw-r--r--editor/editor_properties.cpp103
-rw-r--r--editor/editor_properties_array_dict.cpp12
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/editor_themes.cpp5
-rw-r--r--editor/icons/2D.svg2
-rw-r--r--editor/icons/3D.svg2
-rw-r--r--editor/icons/AspectRatioContainer.svg2
-rw-r--r--editor/icons/AtlasTexture.svg2
-rw-r--r--editor/icons/Back.svg2
-rw-r--r--editor/icons/BoxContainer.svg2
-rw-r--r--editor/icons/BoxMesh.svg2
-rw-r--r--editor/icons/Bucket.svg2
-rw-r--r--editor/icons/Camera2D.svg2
-rw-r--r--editor/icons/Camera3D.svg2
-rw-r--r--editor/icons/CameraAttributes.svg2
-rw-r--r--editor/icons/CameraTexture.svg2
-rw-r--r--editor/icons/CapsuleMesh.svg2
-rw-r--r--editor/icons/CapsuleShape2D.svg2
-rw-r--r--editor/icons/CapsuleShape3D.svg2
-rw-r--r--editor/icons/Checkerboard.svg2
-rw-r--r--editor/icons/ClippedCamera3D.svg2
-rw-r--r--editor/icons/Collapse.svg2
-rw-r--r--editor/icons/CollisionPolygon3D.svg2
-rw-r--r--editor/icons/CollisionShape3D.svg2
-rw-r--r--editor/icons/Container.svg2
-rw-r--r--editor/icons/ContainerLayout.svg2
-rw-r--r--editor/icons/ControlAlignFullRect.svg2
-rw-r--r--editor/icons/ConvexPolygonShape2D.svg2
-rw-r--r--editor/icons/ConvexPolygonShape3D.svg2
-rw-r--r--editor/icons/Curve2D.svg2
-rw-r--r--editor/icons/Curve3D.svg2
-rw-r--r--editor/icons/CurveClose.svg2
-rw-r--r--editor/icons/CurveConstant.svg2
-rw-r--r--editor/icons/CurveCreate.svg2
-rw-r--r--editor/icons/CurveCurve.svg2
-rw-r--r--editor/icons/CurveEdit.svg2
-rw-r--r--editor/icons/CurveIn.svg2
-rw-r--r--editor/icons/CurveInOut.svg2
-rw-r--r--editor/icons/CurveLinear.svg2
-rw-r--r--editor/icons/CurveOutIn.svg2
-rw-r--r--editor/icons/CylinderMesh.svg2
-rw-r--r--editor/icons/DebugSkipBreakpointsOff.svg2
-rw-r--r--editor/icons/EditInternal.svg2
-rw-r--r--editor/icons/EditorFileDialog.svg2
-rw-r--r--editor/icons/Environment.svg2
-rw-r--r--editor/icons/Error.svg2
-rw-r--r--editor/icons/ErrorWarning.svg2
-rw-r--r--editor/icons/Favorites.svg2
-rw-r--r--editor/icons/File.svg2
-rw-r--r--editor/icons/FileBigThumb.svg2
-rw-r--r--editor/icons/FileBroken.svg2
-rw-r--r--editor/icons/FileBrokenBigThumb.svg2
-rw-r--r--editor/icons/FileDead.svg2
-rw-r--r--editor/icons/FileDeadBigThumb.svg2
-rw-r--r--editor/icons/FileDeadMediumThumb.svg2
-rw-r--r--editor/icons/FileDialog.svg2
-rw-r--r--editor/icons/FileMediumThumb.svg2
-rw-r--r--editor/icons/GPUParticlesCollisionSphere3D.svg2
-rw-r--r--editor/icons/Gizmo3DSamplePlayer.svg2
-rw-r--r--editor/icons/GizmoAudioListener3D.svg2
-rw-r--r--editor/icons/GizmoCPUParticles3D.svg2
-rw-r--r--editor/icons/GizmoDirectionalLight.svg2
-rw-r--r--editor/icons/GizmoGPUParticles3D.svg2
-rw-r--r--editor/icons/GizmoLight.svg2
-rw-r--r--editor/icons/GizmoLightmapGI.svg2
-rw-r--r--editor/icons/GizmoReflectionProbe.svg2
-rw-r--r--editor/icons/GizmoSpotLight.svg2
-rw-r--r--editor/icons/GizmoVoxelGI.svg2
-rw-r--r--editor/icons/Gradient.svg2
-rw-r--r--editor/icons/GraphNode.svg2
-rw-r--r--editor/icons/GuiHsplitter.svg2
-rw-r--r--editor/icons/GuiProgressBar.svg2
-rw-r--r--editor/icons/GuiProgressFill.svg2
-rw-r--r--editor/icons/GuiScrollGrabber.svg2
-rw-r--r--editor/icons/GuiScrollGrabberHl.svg2
-rw-r--r--editor/icons/GuiScrollGrabberPressed.svg2
-rw-r--r--editor/icons/GuiSpace.svg2
-rw-r--r--editor/icons/GuiTab.svg2
-rw-r--r--editor/icons/GuiViewportHdiagsplitter.svg2
-rw-r--r--editor/icons/GuiViewportVdiagsplitter.svg2
-rw-r--r--editor/icons/GuiViewportVhsplitter.svg2
-rw-r--r--editor/icons/GuiVsplitter.svg2
-rw-r--r--editor/icons/HBoxContainer.svg2
-rw-r--r--editor/icons/HeightMapShape3D.svg2
-rw-r--r--editor/icons/History.svg2
-rw-r--r--editor/icons/ImmediateMesh.svg2
-rw-r--r--editor/icons/ImportFail.svg2
-rw-r--r--editor/icons/InputEventAction.svg1
-rw-r--r--editor/icons/InputEventJoypadButton.svg1
-rw-r--r--editor/icons/InputEventJoypadMotion.svg1
-rw-r--r--editor/icons/InputEventKey.svg1
-rw-r--r--editor/icons/InputEventMIDI.svg1
-rw-r--r--editor/icons/InputEventMagnifyGesture.svg1
-rw-r--r--editor/icons/InputEventMouseButton.svg1
-rw-r--r--editor/icons/InputEventMouseMotion.svg1
-rw-r--r--editor/icons/InputEventPanGesture.svg1
-rw-r--r--editor/icons/InputEventScreenDrag.svg1
-rw-r--r--editor/icons/InputEventScreenTouch.svg1
-rw-r--r--editor/icons/InputEventShortcut.svg1
-rw-r--r--editor/icons/InstanceOptions.svg2
-rw-r--r--editor/icons/InterpCubic.svg2
-rw-r--r--editor/icons/InterpCubicAngle.svg2
-rw-r--r--editor/icons/InterpLinear.svg2
-rw-r--r--editor/icons/InterpLinearAngle.svg2
-rw-r--r--editor/icons/InterpRaw.svg2
-rw-r--r--editor/icons/InterpWrapClamp.svg2
-rw-r--r--editor/icons/InterpWrapLoop.svg2
-rw-r--r--editor/icons/JoyAxis.svg2
-rw-r--r--editor/icons/JoyButton.svg2
-rw-r--r--editor/icons/Joypad.svg2
-rw-r--r--editor/icons/KeyAnimation.svg2
-rw-r--r--editor/icons/KeyAudio.svg2
-rw-r--r--editor/icons/KeyBezierHandle.svg2
-rw-r--r--editor/icons/KeyBezierPoint.svg2
-rw-r--r--editor/icons/KeyBezierSelected.svg2
-rw-r--r--editor/icons/KeyBlendShape.svg2
-rw-r--r--editor/icons/KeyCall.svg2
-rw-r--r--editor/icons/KeyEasedSelected.svg2
-rw-r--r--editor/icons/KeySelected.svg2
-rw-r--r--editor/icons/KeyValue.svg2
-rw-r--r--editor/icons/KeyValueEased.svg2
-rw-r--r--editor/icons/KeyXPosition.svg2
-rw-r--r--editor/icons/KeyXRotation.svg2
-rw-r--r--editor/icons/KeyXScale.svg2
-rw-r--r--editor/icons/KeyXform.svg1
-rw-r--r--editor/icons/KeyboardPhysical.svg2
-rw-r--r--editor/icons/Line.svg2
-rw-r--r--editor/icons/MainPlay.svg2
-rw-r--r--editor/icons/MaterialPreviewCube.svg2
-rw-r--r--editor/icons/MaterialPreviewCubeOff.svg2
-rw-r--r--editor/icons/MaterialPreviewSphere.svg2
-rw-r--r--editor/icons/MaterialPreviewSphereOff.svg2
-rw-r--r--editor/icons/Mesh.svg2
-rw-r--r--editor/icons/MeshInstance2D.svg2
-rw-r--r--editor/icons/MeshInstance3D.svg2
-rw-r--r--editor/icons/MissingNode.svg2
-rw-r--r--editor/icons/MissingResource.svg2
-rw-r--r--editor/icons/Navigation2D.svg1
-rw-r--r--editor/icons/Navigation3D.svg1
-rw-r--r--editor/icons/NavigationPolygon.svg2
-rw-r--r--editor/icons/New.svg2
-rw-r--r--editor/icons/PlaneMesh.svg2
-rw-r--r--editor/icons/PlayStart.svg2
-rw-r--r--editor/icons/PlayStartBackwards.svg2
-rw-r--r--editor/icons/PluginScript.svg2
-rw-r--r--editor/icons/PreviewEnvironment.svg2
-rw-r--r--editor/icons/PrismMesh.svg2
-rw-r--r--editor/icons/Progress1.svg2
-rw-r--r--editor/icons/Progress2.svg2
-rw-r--r--editor/icons/Progress3.svg2
-rw-r--r--editor/icons/Progress4.svg2
-rw-r--r--editor/icons/Progress5.svg2
-rw-r--r--editor/icons/Progress6.svg2
-rw-r--r--editor/icons/Progress7.svg2
-rw-r--r--editor/icons/Progress8.svg2
-rw-r--r--editor/icons/QuadMesh.svg2
-rw-r--r--editor/icons/Range.svg2
-rw-r--r--editor/icons/Reload.svg2
-rw-r--r--editor/icons/ReloadSmall.svg2
-rw-r--r--editor/icons/ReverseGradient.svg2
-rw-r--r--editor/icons/RibbonTrailMesh.svg2
-rw-r--r--editor/icons/RotateLeft.svg2
-rw-r--r--editor/icons/RotateRight.svg2
-rw-r--r--editor/icons/Script.svg2
-rw-r--r--editor/icons/ScriptCreate.svg2
-rw-r--r--editor/icons/ScriptCreateDialog.svg2
-rw-r--r--editor/icons/ScriptExtend.svg2
-rw-r--r--editor/icons/ScriptRemove.svg2
-rw-r--r--editor/icons/SeparationRayShape3D.svg2
-rw-r--r--editor/icons/Shortcut.svg2
-rw-r--r--editor/icons/SphereMesh.svg2
-rw-r--r--editor/icons/TextEdit.svg2
-rw-r--r--editor/icons/TextFile.svg2
-rw-r--r--editor/icons/TrackContinuous.svg2
-rw-r--r--editor/icons/TransitionEnd.svg2
-rw-r--r--editor/icons/TransitionEndAuto.svg2
-rw-r--r--editor/icons/TransitionEndAutoBig.svg2
-rw-r--r--editor/icons/TransitionEndBig.svg2
-rw-r--r--editor/icons/TransitionImmediate.svg2
-rw-r--r--editor/icons/TransitionImmediateAuto.svg2
-rw-r--r--editor/icons/TransitionImmediateAutoBig.svg2
-rw-r--r--editor/icons/TransitionImmediateBig.svg2
-rw-r--r--editor/icons/TransitionSync.svg2
-rw-r--r--editor/icons/TransitionSyncAuto.svg2
-rw-r--r--editor/icons/TransitionSyncAutoBig.svg2
-rw-r--r--editor/icons/TransitionSyncBig.svg2
-rw-r--r--editor/icons/TubeTrailMesh.svg2
-rw-r--r--editor/icons/VBoxContainer.svg2
-rw-r--r--editor/icons/VisualShaderNodeColorOp.svg2
-rw-r--r--editor/icons/VisualShaderNodeColorUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeFloatFunc.svg2
-rw-r--r--editor/icons/VisualShaderNodeFloatOp.svg2
-rw-r--r--editor/icons/VisualShaderNodeFloatUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeIntFunc.svg2
-rw-r--r--editor/icons/VisualShaderNodeIntOp.svg2
-rw-r--r--editor/icons/VisualShaderNodeIntUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorFunc.svg2
-rw-r--r--editor/icons/Warning.svg2
-rw-r--r--editor/icons/World2D.svg2
-rw-r--r--editor/icons/WorldEnvironment.svg2
-rw-r--r--editor/icons/XRCamera3D.svg2
-rw-r--r--editor/import/post_import_plugin_skeleton_rest_fixer.cpp90
-rw-r--r--editor/import/resource_importer_texture.cpp43
-rw-r--r--editor/import/resource_importer_texture.h2
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp6
-rw-r--r--editor/plugins/control_editor_plugin.cpp6
-rw-r--r--editor/plugins/curve_editor_plugin.cpp1205
-rw-r--r--editor/plugins/curve_editor_plugin.h139
-rw-r--r--editor/plugins/font_config_plugin.cpp12
-rw-r--r--editor/plugins/gradient_editor.cpp13
-rw-r--r--editor/plugins/gradient_editor.h4
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.cpp255
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.h36
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp11
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp5
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp6
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp2
-rw-r--r--editor/progress_dialog.cpp16
-rw-r--r--editor/progress_dialog.h1
-rw-r--r--editor/scene_tree_dock.cpp7
-rw-r--r--main/main.cpp2
-rw-r--r--misc/extension_api_validation/4.0-stable.expected220
-rw-r--r--modules/csg/icons/CSGBox3D.svg2
-rw-r--r--modules/csg/icons/CSGCapsule3D.svg2
-rw-r--r--modules/csg/icons/CSGCombiner3D.svg2
-rw-r--r--modules/csg/icons/CSGCylinder3D.svg2
-rw-r--r--modules/csg/icons/CSGMesh3D.svg2
-rw-r--r--modules/csg/icons/CSGPolygon3D.svg2
-rw-r--r--modules/csg/icons/CSGSphere3D.svg2
-rw-r--r--modules/csg/icons/CSGTorus3D.svg2
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml2
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.cpp8
-rw-r--r--modules/gltf/doc_classes/GLTFDocumentExtension.xml21
-rw-r--r--modules/gltf/doc_classes/GLTFState.xml13
-rw-r--r--modules/gltf/doc_classes/GLTFTexture.xml3
-rw-r--r--modules/gltf/extensions/gltf_document_extension.cpp18
-rw-r--r--modules/gltf/extensions/gltf_document_extension.h4
-rw-r--r--modules/gltf/extensions/gltf_document_extension_texture_webp.cpp68
-rw-r--r--modules/gltf/extensions/gltf_document_extension_texture_webp.h47
-rw-r--r--modules/gltf/extensions/physics/gltf_physics_body.cpp5
-rw-r--r--modules/gltf/gltf_document.cpp377
-rw-r--r--modules/gltf/gltf_document.h2
-rw-r--r--modules/gltf/gltf_state.cpp10
-rw-r--r--modules/gltf/gltf_state.h2
-rw-r--r--modules/gltf/register_types.cpp2
-rw-r--r--modules/gltf/structures/gltf_texture.h2
-rw-r--r--modules/multiplayer/doc_classes/SceneReplicationConfig.xml4
-rw-r--r--modules/noise/icons/NoiseTexture.svg1
-rw-r--r--modules/noise/icons/NoiseTexture2D.svg1
-rw-r--r--modules/text_server_adv/doc_classes/TextServerAdvanced.xml3
-rw-r--r--modules/text_server_fb/doc_classes/TextServerFallback.xml4
-rw-r--r--modules/webp/image_loader_webp.cpp4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt19
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java31
-rw-r--r--platform/android/java_godot_view_wrapper.cpp13
-rw-r--r--platform/android/java_godot_view_wrapper.h1
-rw-r--r--platform/android/os_android.cpp10
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp47
-rw-r--r--platform/uwp/os_uwp.cpp3
-rw-r--r--platform/windows/os_windows.cpp10
-rw-r--r--scene/animation/animation_blend_tree.cpp41
-rw-r--r--scene/animation/animation_blend_tree.h20
-rw-r--r--scene/animation/animation_player.cpp4
-rw-r--r--scene/animation/animation_tree.cpp2
-rw-r--r--scene/gui/button.cpp23
-rw-r--r--scene/gui/button.h1
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/menu_bar.cpp16
-rw-r--r--scene/gui/popup.cpp1
-rw-r--r--scene/gui/popup_menu.cpp114
-rw-r--r--scene/gui/popup_menu.h10
-rw-r--r--scene/gui/texture_button.cpp57
-rw-r--r--scene/gui/texture_button.h3
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/main/window.cpp2
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/curve.cpp7
-rw-r--r--scene/resources/curve.h7
-rw-r--r--scene/resources/gradient.cpp25
-rw-r--r--scene/resources/gradient.h109
-rw-r--r--scene/resources/texture.cpp5
-rw-r--r--scene/resources/texture.h1
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp8
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl12
-rw-r--r--servers/text_server.cpp58
-rw-r--r--tests/core/io/test_image.h21
637 files changed, 4041 insertions, 2619 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 1050f259a0..2b642100c7 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -15,9 +15,9 @@ body:
attributes:
label: Godot version
description: >
- Specify the Git commit hash if using a development or non-official build.
+ Specify the Godot version, including the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
- placeholder: 3.3.stable, 4.0.dev (3041becc6)
+ placeholder: 3.5.stable, 4.0.dev (3041becc6)
validations:
required: true
@@ -29,7 +29,8 @@ body:
- For issues that are likely OS-specific and/or graphics-related, please specify the CPU model and architecture.
- For graphics-related issues, specify the GPU model, driver version, and the rendering backend (GLES2, GLES3, Vulkan).
- **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information.
- placeholder: Windows 10, Intel Core i5-7200U, GLES3, Intel HD Graphics 620 (27.20.100.9616)
+ - **Starting from Godot 4.1, you can copy this information to your clipboard by using *Help > Copy System Info* at the top of the editor window.**
+ placeholder: Windows 10 - Godot v4.0.3.stable - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 970 (nvidia, 510.85.02) - Intel Core i7-10700KF CPU @ 3.80GHz (16 Threads)
validations:
required: true
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 0bcc8a44e8..c67867f65d 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -1065,7 +1065,57 @@ void GDExtensionAPIDump::generate_extension_json_file(const String &p_path) {
fa->store_string(text);
}
-static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_new_api, const String &p_base_array, const String &p_name_field, const Vector<String> &p_fields_to_compare, bool p_compare_hashes, const String &p_outer_class = String(), bool p_compare_operators = false) {
+static bool compare_value(const String &p_path, const String &p_field, const Variant &p_old_value, const Variant &p_new_value, bool p_allow_name_change) {
+ bool failed = false;
+ String path = p_path + "/" + p_field;
+ if (p_old_value.get_type() == Variant::ARRAY && p_new_value.get_type() == Variant::ARRAY) {
+ Array old_array = p_old_value;
+ Array new_array = p_new_value;
+ if (!compare_value(path, "size", old_array.size(), new_array.size(), p_allow_name_change)) {
+ failed = true;
+ }
+ for (int i = 0; i < old_array.size() && i < new_array.size(); i++) {
+ if (!compare_value(path, itos(i), old_array[i], new_array[i], p_allow_name_change)) {
+ failed = true;
+ }
+ }
+ } else if (p_old_value.get_type() == Variant::DICTIONARY && p_new_value.get_type() == Variant::DICTIONARY) {
+ Dictionary old_dict = p_old_value;
+ Dictionary new_dict = p_new_value;
+ Array old_keys = old_dict.keys();
+ for (int i = 0; i < old_keys.size(); i++) {
+ Variant key = old_keys[i];
+ if (!new_dict.has(key)) {
+ failed = true;
+ print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, key));
+ continue;
+ }
+ if (p_allow_name_change && key == "name") {
+ continue;
+ }
+ if (!compare_value(path, key, old_dict[key], new_dict[key], p_allow_name_change)) {
+ failed = true;
+ }
+ }
+ Array new_keys = old_dict.keys();
+ for (int i = 0; i < new_keys.size(); i++) {
+ Variant key = new_keys[i];
+ if (!old_dict.has(key)) {
+ failed = true;
+ print_error(vformat("Validate extension JSON: Error: Field '%s': %s was added with value %s.", p_path, key, new_dict[key]));
+ }
+ }
+ } else {
+ bool equal = Variant::evaluate(Variant::OP_EQUAL, p_old_value, p_new_value);
+ if (!equal) {
+ print_error(vformat("Validate extension JSON: Error: Field '%s': %s changed value in new API, from %s to %s.", p_path, p_field, p_old_value.get_construct_string(), p_new_value.get_construct_string()));
+ return false;
+ }
+ }
+ return !failed;
+}
+
+static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_new_api, const String &p_base_array, const String &p_name_field, const Vector<String> &p_fields_to_compare, bool p_compare_hashes, const String &p_outer_class = String(), bool p_compare_operators = false, bool p_compare_enum_value = false) {
String base_array = p_outer_class + p_base_array;
if (!p_old_api.has(p_base_array)) {
return true; // May just not have this array and its still good. Probably added recently.
@@ -1077,7 +1127,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
for (int i = 0; i < new_api.size(); i++) {
Dictionary elem = new_api[i];
- ERR_FAIL_COND_V_MSG(!elem.has(p_name_field), false, "Validate extension JSON: Element of base_array '" + base_array + "' is missing field '" + p_name_field + "'. This is a bug.");
+ ERR_FAIL_COND_V_MSG(!elem.has(p_name_field), false, vformat("Validate extension JSON: Element of base_array '%s' is missing field '%s'. This is a bug.", base_array, p_name_field));
String name = elem[p_name_field];
if (p_compare_operators && elem.has("right_type")) {
name += " " + String(elem["right_type"]);
@@ -1090,7 +1140,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
Dictionary old_elem = old_api[i];
if (!old_elem.has(p_name_field)) {
failed = true;
- print_error("Validate extension JSON: JSON file: element of base array '" + base_array + "' is missing the field: '" + p_name_field + "'.");
+ print_error(vformat("Validate extension JSON: JSON file: element of base array '%s' is missing the field: '%s'.", base_array, p_name_field));
continue;
}
String name = old_elem[p_name_field];
@@ -1099,7 +1149,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
}
if (!new_api_assoc.has(name)) {
failed = true;
- print_error("Validate extension JSON: API was removed: " + base_array + "/" + name);
+ print_error(vformat("Validate extension JSON: API was removed: %s/%s", base_array, name));
continue;
}
@@ -1119,19 +1169,31 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
field = field.substr(1, field.length());
}
+ bool enum_values = field.begins_with("$");
+ if (enum_values) {
+ // Meaning this field is a list of enum values.
+ field = field.substr(1, field.length());
+ }
+
+ bool allow_name_change = field.begins_with("@");
+ if (allow_name_change) {
+ // Meaning that when structurally comparing the old and new value, the dictionary entry 'name' may change.
+ field = field.substr(1, field.length());
+ }
+
Variant old_value;
if (!old_elem.has(field)) {
if (optional) {
if (new_elem.has(field)) {
failed = true;
- print_error("Validate extension JSON: JSON file: Field was added in a way that breaks compatibility '" + base_array + "/" + name + "': " + field);
+ print_error(vformat("Validate extension JSON: JSON file: Field was added in a way that breaks compatibility '%s/%s': %s", base_array, name, field));
}
} else if (added && new_elem.has(field)) {
// Should be ok, field now exists, should not be verified in prior versions where it does not.
} else {
failed = true;
- print_error("Validate extension JSON: JSON file: Missing filed in '" + base_array + "/" + name + "': " + field);
+ print_error(vformat("Validate extension JSON: JSON file: Missing field in '%s/%s': %s", base_array, name, field));
}
continue;
} else {
@@ -1140,17 +1202,24 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
if (!new_elem.has(field)) {
failed = true;
- ERR_PRINT("Validate extension JSON: Missing filed in current API '" + base_array + "/" + name + "': " + field + ". This is a bug.");
+ ERR_PRINT(vformat("Validate extension JSON: Missing field in current API '%s/%s': %s. This is a bug.", base_array, name, field));
continue;
}
Variant new_value = new_elem[field];
- bool equal = Variant::evaluate(Variant::OP_EQUAL, old_value, new_value);
- if (!equal) {
+ if (p_compare_enum_value && name.ends_with("_MAX")) {
+ if (static_cast<int64_t>(new_value) > static_cast<int64_t>(old_value)) {
+ // Ignore the _MAX value of an enum increasing.
+ continue;
+ }
+ }
+ if (enum_values) {
+ if (!compare_dict_array(old_elem, new_elem, field, "name", { "value" }, false, base_array + "/" + name + "/", false, true)) {
+ failed = true;
+ }
+ } else if (!compare_value(base_array + "/" + name, field, old_value, new_value, allow_name_change)) {
failed = true;
- print_error("Validate extension JSON: Error: Field '" + base_array + "/" + name + "': " + field + " changed value in new API, from " + old_value.get_construct_string() + " to " + new_value.get_construct_string() + ".");
- continue;
}
}
@@ -1161,7 +1230,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
}
failed = true;
- print_error("Validate extension JSON: JSON file: element of base array '" + base_array + "' is missing the field: 'hash'.");
+ print_error(vformat("Validate extension JSON: JSON file: element of base array '%s' is missing the field: 'hash'.", base_array));
continue;
}
@@ -1169,7 +1238,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
if (!new_elem.has("hash")) {
failed = true;
- print_error("Validate extension JSON: Error: Field '" + base_array + "' is missing the field: 'hash'.");
+ print_error(vformat("Validate extension JSON: Error: Field '%s' is missing the field: 'hash'.", base_array));
continue;
}
@@ -1190,7 +1259,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
if (!hash_found) {
failed = true;
- print_error("Validate extension JSON: Error: Hash mismatch for '" + base_array + "/" + name + "'. This means that the function has changed and no compatibility function was provided.");
+ print_error(vformat("Validate extension JSON: Error: Hash changed for '%s/%s', from %08X to %08X. This means that the function has changed and no compatibility function was provided.", base_array, name, old_hash, new_hash));
continue;
}
}
@@ -1210,7 +1279,7 @@ static bool compare_sub_dict_array(HashSet<String> &r_removed_classes_registered
for (int i = 0; i < new_api.size(); i++) {
Dictionary elem = new_api[i];
- ERR_FAIL_COND_V_MSG(!elem.has(p_outer_name), false, "Validate extension JSON: Element of base_array '" + p_outer + "' is missing field '" + p_outer_name + "'. This is a bug.");
+ ERR_FAIL_COND_V_MSG(!elem.has(p_outer_name), false, vformat("Validate extension JSON: Element of base_array '%s' is missing field '%s'. This is a bug.", p_outer, p_outer_name));
new_api_assoc.insert(elem[p_outer_name], elem);
}
@@ -1220,14 +1289,14 @@ static bool compare_sub_dict_array(HashSet<String> &r_removed_classes_registered
Dictionary old_elem = old_api[i];
if (!old_elem.has(p_outer_name)) {
failed = true;
- print_error("Validate extension JSON: JSON file: element of base array '" + p_outer + "' is missing the field: '" + p_outer_name + "'.");
+ print_error(vformat("Validate extension JSON: JSON file: element of base array '%s' is missing the field: '%s'.", p_outer, p_outer_name));
continue;
}
String name = old_elem[p_outer_name];
if (!new_api_assoc.has(name)) {
failed = true;
if (!r_removed_classes_registered.has(name)) {
- print_error("Validate extension JSON: API was removed: " + p_outer + "/" + name);
+ print_error(vformat("Validate extension JSON: API was removed: %s/%s", p_outer, name));
r_removed_classes_registered.insert(name);
}
continue;
@@ -1247,7 +1316,7 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
Error error;
String text = FileAccess::get_file_as_string(p_path, &error);
if (error != OK) {
- ERR_PRINT("Validate extension JSON: Could not open file '" + p_path + "'.");
+ ERR_PRINT(vformat("Validate extension JSON: Could not open file '%s'.", p_path));
return error;
}
@@ -1255,7 +1324,7 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
json.instantiate();
error = json->parse(text);
if (error != OK) {
- ERR_PRINT("Validate extension JSON: Error parsing '" + p_path + "' at line " + itos(json->get_error_line()) + ": " + json->get_error_message());
+ ERR_PRINT(vformat("Validate extension JSON: Error parsing '%s' at line %d: %s", p_path, json->get_error_line(), json->get_error_message()));
return error;
}
@@ -1269,19 +1338,23 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
int major = header["version_major"];
int minor = header["version_minor"];
- ERR_FAIL_COND_V_MSG(major != VERSION_MAJOR, ERR_INVALID_DATA, "JSON API dump is for a different engine version (" + itos(major) + ") than this one (" + itos(major) + ")");
- ERR_FAIL_COND_V_MSG(minor > VERSION_MINOR, ERR_INVALID_DATA, "JSON API dump is for a newer version of the engine: " + itos(major) + "." + itos(minor));
+ ERR_FAIL_COND_V_MSG(major != VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, VERSION_MAJOR));
+ ERR_FAIL_COND_V_MSG(minor > VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor));
}
bool failed = false;
HashSet<String> removed_classes_registered;
- if (!compare_dict_array(old_api, new_api, "constants", "name", Vector<String>({ "value", "is_bitfield" }), false)) {
+ if (!compare_dict_array(old_api, new_api, "global_constants", "name", Vector<String>({ "value", "is_bitfield" }), false)) {
+ failed = true;
+ }
+
+ if (!compare_dict_array(old_api, new_api, "global_enums", "name", Vector<String>({ "$values", "is_bitfield" }), false)) {
failed = true;
}
- if (!compare_dict_array(old_api, new_api, "utility_functions", "name", Vector<String>({ "category" }), true)) {
+ if (!compare_dict_array(old_api, new_api, "utility_functions", "name", Vector<String>({ "category", "is_vararg", "*return_type", "*@arguments" }), true)) {
failed = true;
}
@@ -1297,11 +1370,11 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
failed = true;
}
- if (!compare_sub_dict_array(removed_classes_registered, "builtin_classes", "name", old_api, new_api, "methods", "name", {}, true)) {
+ if (!compare_sub_dict_array(removed_classes_registered, "builtin_classes", "name", old_api, new_api, "methods", "name", { "is_vararg", "is_static", "is_const", "*return_type", "*@arguments" }, true)) {
failed = true;
}
- if (!compare_sub_dict_array(removed_classes_registered, "builtin_classes", "name", old_api, new_api, "constructors", "index", { "*arguments" }, false)) {
+ if (!compare_sub_dict_array(removed_classes_registered, "builtin_classes", "name", old_api, new_api, "constructors", "index", { "*@arguments" }, false)) {
failed = true;
}
@@ -1309,11 +1382,15 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
failed = true;
}
- if (!compare_sub_dict_array(removed_classes_registered, "classes", "name", old_api, new_api, "methods", "name", { "is_virtual", "is_vararg", "is_static" }, true)) { // is_const sometimes can change because they are added if someone forgot, but should not be a problem for the extensions.
+ if (!compare_sub_dict_array(removed_classes_registered, "classes", "name", old_api, new_api, "enums", "name", { "is_bitfield", "$values" }, false)) {
+ failed = true;
+ }
+
+ if (!compare_sub_dict_array(removed_classes_registered, "classes", "name", old_api, new_api, "methods", "name", { "is_virtual", "is_vararg", "is_static", "is_const", "*return_value", "*@arguments" }, true)) {
failed = true;
}
- if (!compare_sub_dict_array(removed_classes_registered, "classes", "name", old_api, new_api, "signals", "name", { "*arguments" }, false)) {
+ if (!compare_sub_dict_array(removed_classes_registered, "classes", "name", old_api, new_api, "signals", "name", { "*@arguments" }, false)) {
failed = true;
}
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 0cbcf58882..8bdea01ae6 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -678,3 +678,25 @@ String GDExtensionResourceLoader::get_resource_type(const String &p_path) const
}
return "";
}
+
+#ifdef TOOLS_ENABLED
+Vector<StringName> GDExtensionEditorPlugins::extension_classes;
+GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_add_plugin = nullptr;
+GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr;
+
+void GDExtensionEditorPlugins::add_extension_class(const StringName &p_class_name) {
+ if (editor_node_add_plugin) {
+ editor_node_add_plugin(p_class_name);
+ } else {
+ extension_classes.push_back(p_class_name);
+ }
+}
+
+void GDExtensionEditorPlugins::remove_extension_class(const StringName &p_class_name) {
+ if (editor_node_remove_plugin) {
+ editor_node_remove_plugin(p_class_name);
+ } else {
+ extension_classes.erase(p_class_name);
+ }
+}
+#endif // TOOLS_ENABLED
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index 95811820cf..49f1cf1d8e 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -107,4 +107,28 @@ public:
virtual String get_resource_type(const String &p_path) const;
};
+#ifdef TOOLS_ENABLED
+class GDExtensionEditorPlugins {
+private:
+ static Vector<StringName> extension_classes;
+
+protected:
+ friend class EditorNode;
+
+ // Since this in core, we can't directly reference EditorNode, so it will
+ // set these function pointers in its constructor.
+ typedef void (*EditorPluginRegisterFunc)(const StringName &p_class_name);
+ static EditorPluginRegisterFunc editor_node_add_plugin;
+ static EditorPluginRegisterFunc editor_node_remove_plugin;
+
+public:
+ static void add_extension_class(const StringName &p_class_name);
+ static void remove_extension_class(const StringName &p_class_name);
+
+ static const Vector<StringName> &get_extension_classes() {
+ return extension_classes;
+ }
+};
+#endif // TOOLS_ENABLED
+
#endif // GDEXTENSION_H
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index 12ef1772e3..21d34b6e0c 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -1071,6 +1071,20 @@ static void *gdextension_classdb_get_class_tag(GDExtensionConstStringNamePtr p_c
return class_info ? class_info->class_ptr : nullptr;
}
+static void gdextension_editor_add_plugin(GDExtensionConstStringNamePtr p_classname) {
+#ifdef TOOLS_ENABLED
+ const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
+ GDExtensionEditorPlugins::add_extension_class(classname);
+#endif
+}
+
+static void gdextension_editor_remove_plugin(GDExtensionConstStringNamePtr p_classname) {
+#ifdef TOOLS_ENABLED
+ const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
+ GDExtensionEditorPlugins::remove_extension_class(classname);
+#endif
+}
+
#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr)&gdextension_##m_name)
void gdextension_setup_interface() {
@@ -1199,6 +1213,8 @@ void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(classdb_construct_object);
REGISTER_INTERFACE_FUNC(classdb_get_method_bind);
REGISTER_INTERFACE_FUNC(classdb_get_class_tag);
+ REGISTER_INTERFACE_FUNC(editor_add_plugin);
+ REGISTER_INTERFACE_FUNC(editor_remove_plugin);
}
#undef REGISTER_INTERFACE_FUNCTION
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index a5ea3918df..3aa41f28da 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -2141,6 +2141,26 @@ typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionC
*/
typedef void (*GDExtensionInterfaceGetLibraryPath)(GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringPtr r_path);
+/**
+ * @name editor_add_plugin
+ *
+ * Adds an editor plugin.
+ *
+ * It's safe to call during initialization.
+ *
+ * @param p_class_name A pointer to a StringName with the name of a class (descending from EditorPlugin) which is already registered with ClassDB.
+ */
+typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePtr p_class_name);
+
+/**
+ * @name editor_remove_plugin
+ *
+ * Removes an editor plugin.
+ *
+ * @param p_class_name A pointer to a StringName with the name of a class that was previously added as an editor plugin.
+ */
+typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name);
+
#ifdef __cplusplus
}
#endif
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 8111ca447c..9bb987b670 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -468,7 +468,7 @@ int Image::get_mipmap_count() const {
//using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers
template <uint32_t read_bytes, bool read_alpha, uint32_t write_bytes, bool write_alpha, bool read_gray, bool write_gray>
static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p_dst) {
- uint32_t max_bytes = MAX(read_bytes, write_bytes);
+ constexpr uint32_t max_bytes = MAX(read_bytes, write_bytes);
for (int y = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++) {
@@ -492,8 +492,9 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
}
if constexpr (write_gray) {
- //TODO: not correct grayscale, should use fixed point version of actual weights
- wofs[0] = uint8_t((uint16_t(rgba[0]) + uint16_t(rgba[1]) + uint16_t(rgba[2])) / 3);
+ // REC.709
+ const uint8_t luminance = (13938U * rgba[0] + 46869U * rgba[1] + 4729U * rgba[2] + 32768U) >> 16U;
+ wofs[0] = luminance;
} else {
for (uint32_t i = 0; i < write_bytes; i++) {
wofs[i] = rgba[i];
@@ -3718,9 +3719,9 @@ void Image::premultiply_alpha() {
for (int j = 0; j < width; j++) {
uint8_t *ptr = &data_ptr[(i * width + j) * 4];
- ptr[0] = (uint16_t(ptr[0]) * uint16_t(ptr[3])) >> 8;
- ptr[1] = (uint16_t(ptr[1]) * uint16_t(ptr[3])) >> 8;
- ptr[2] = (uint16_t(ptr[2]) * uint16_t(ptr[3])) >> 8;
+ ptr[0] = (uint16_t(ptr[0]) * uint16_t(ptr[3]) + 255U) >> 8;
+ ptr[1] = (uint16_t(ptr[1]) * uint16_t(ptr[3]) + 255U) >> 8;
+ ptr[2] = (uint16_t(ptr[2]) * uint16_t(ptr[3]) + 255U) >> 8;
}
}
}
diff --git a/core/object/object.cpp b/core/object/object.cpp
index f276547e7b..d6937539c7 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -903,7 +903,7 @@ void Object::set_meta(const StringName &p_name, const Variant &p_value) {
if (E) {
E->value = p_value;
} else {
- ERR_FAIL_COND(!p_name.operator String().is_valid_identifier());
+ ERR_FAIL_COND_MSG(!p_name.operator String().is_valid_identifier(), "Invalid metadata identifier: '" + p_name + "'.");
Variant *V = &metadata.insert(p_name, p_value)->value;
const String &sname = p_name;
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 6ba0deadaa..db0fa69181 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -829,7 +829,7 @@
Converts one or more arguments of any type to string in the best way possible and prints them to the console.
The following BBCode tags are supported: [code]b[/code], [code]i[/code], [code]u[/code], [code]s[/code], [code]indent[/code], [code]code[/code], [code]url[/code], [code]center[/code], [code]right[/code], [code]color[/code], [code]bgcolor[/code], [code]fgcolor[/code].
Color tags only support the following named colors: [code]black[/code], [code]red[/code], [code]green[/code], [code]yellow[/code], [code]blue[/code], [code]magenta[/code], [code]pink[/code], [code]purple[/code], [code]cyan[/code], [code]white[/code], [code]orange[/code], [code]gray[/code]. Hexadecimal color codes are not supported.
- URL tags only support URLs wrapped by an URL tag, not URLs with a different title.
+ URL tags only support URLs wrapped by a URL tag, not URLs with a different title.
When printing to standard output, the supported subset of BBCode is converted to ANSI escape codes for the terminal emulator to display. Support for ANSI escape codes varies across terminal emulators, especially for italic and strikethrough. In standard output, [code]code[/code] is represented with faint text but without any font change. Unsupported tags are left as-is in standard output.
[codeblocks]
[gdscript]
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 34fe3cd1bb..415eb9d682 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AABB" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Axis-Aligned Bounding Box.
+ A 3D axis-aligned bounding box.
</brief_description>
<description>
[AABB] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
diff --git a/doc/classes/AESContext.xml b/doc/classes/AESContext.xml
index aa205ef32a..52158fcd3e 100644
--- a/doc/classes/AESContext.xml
+++ b/doc/classes/AESContext.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AESContext" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Interface to low level AES encryption features.
+ Provides access to AES encryption/decryption of raw data.
</brief_description>
<description>
- This class provides access to AES encryption/decryption of raw data. Both AES-ECB and AES-CBC mode are supported.
+ This class holds the context information required for encryption and decryption operations with AES (Advanced Encryption Standard). Both AES-ECB and AES-CBC modes are supported.
[codeblocks]
[gdscript]
extends Node
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index cc69c0b8f3..8f6a6eeebc 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AStar2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- AStar class representation that uses 2D vectors as edges.
+ An implementation of A* for finding the shortest path between two vertices on a connected graph in 2D space.
</brief_description>
<description>
- This is a wrapper for the [AStar3D] class which uses 2D vectors instead of 3D vectors.
+ An implementation of the A* algorithm, used to find the shortest path between two vertices on a connected graph in 2D space.
+ See [AStar3D] for a more thorough explanation on how to use this class. [AStar2D] is a wrapper for [AStar3D] that enforces 2D coordinates.
</description>
<tutorials>
</tutorials>
@@ -15,7 +16,7 @@
<param index="1" name="to_id" type="int" />
<description>
Called when computing the cost between two connected points.
- Note that this function is hidden in the default [code]AStar2D[/code] class.
+ Note that this function is hidden in the default [AStar2D] class.
</description>
</method>
<method name="_estimate_cost" qualifiers="virtual const">
@@ -24,7 +25,7 @@
<param index="1" name="to_id" type="int" />
<description>
Called when estimating the cost between a point and the path's ending point.
- Note that this function is hidden in the default [code]AStar2D[/code] class.
+ Note that this function is hidden in the default [AStar2D] class.
</description>
</method>
<method name="add_point">
diff --git a/doc/classes/AStar3D.xml b/doc/classes/AStar3D.xml
index da3c6344ee..489f8e38be 100644
--- a/doc/classes/AStar3D.xml
+++ b/doc/classes/AStar3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AStar3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- An implementation of A* to find the shortest paths among connected points in space.
+ An implementation of A* for finding the shortest path between two vertices on a connected graph in 3D space.
</brief_description>
<description>
- A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting short paths among vertices (points), passing through a given set of edges (segments). It enjoys widespread use due to its performance and accuracy. Godot's A* implementation uses points in three-dimensional space and Euclidean distances by default.
- You must add points manually with [method add_point] and create segments manually with [method connect_points]. Then you can test if there is a path between two points with the [method are_points_connected] function, get a path containing indices by [method get_id_path], or one containing actual coordinates with [method get_point_path].
+ A* (A star) is a computer algorithm used in pathfinding and graph traversal, the process of plotting short paths among vertices (points), passing through a given set of edges (segments). It enjoys widespread use due to its performance and accuracy. Godot's A* implementation uses points in 3D space and Euclidean distances by default.
+ You must add points manually with [method add_point] and create segments manually with [method connect_points]. Once done, you can test if there is a path between two points with the [method are_points_connected] function, get a path containing indices by [method get_id_path], or one containing actual coordinates with [method get_point_path].
It is also possible to use non-Euclidean distances. To do so, create a class that extends [code]AStar3D[/code] and override methods [method _compute_cost] and [method _estimate_cost]. Both take two indices and return a length, as is shown in the following example.
[codeblocks]
[gdscript]
diff --git a/doc/classes/AStarGrid2D.xml b/doc/classes/AStarGrid2D.xml
index 2a38d34cfb..0cf0676521 100644
--- a/doc/classes/AStarGrid2D.xml
+++ b/doc/classes/AStarGrid2D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AStarGrid2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A* (or "A-Star") pathfinding tailored to find the shortest paths on 2D grids.
+ An implementation of A* for finding the shortest path between two points on a partial 2D grid.
</brief_description>
<description>
- Compared to [AStar2D] you don't need to manually create points or connect them together. It also supports multiple type of heuristics and modes for diagonal movement. This class also provides a jumping mode which is faster to calculate than without it in the [AStar2D] class.
- In contrast to [AStar2D], you only need set the [member region] of the grid, optionally set the [member cell_size] and then call the [method update] method:
+ [AStarGrid2D] is a variant of [AStar2D] that is specialized for partial 2D grids. It is simpler to use because it doesn't require you to manually create points and connect them together. This class also supports multiple types of heuristics, modes for diagonal movement, and a jumping mode to speed up calculations.
+ To use [AStarGrid2D], you only need to set the [member region] of the grid, optionally set the [member cell_size], and then call the [method update] method:
[codeblocks]
[gdscript]
var astar_grid = AStarGrid2D.new()
@@ -24,6 +24,7 @@
GD.Print(astarGrid.GetPointPath(Vector2I.Zero, new Vector2I(3, 4))); // prints (0, 0), (16, 16), (32, 32), (48, 48), (48, 64)
[/csharp]
[/codeblocks]
+ To remove a point from the pathfinding grid, it must be set as "solid" with [method set_point_solid].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index 6b291dc52c..633657807b 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AcceptDialog" inherits="Window" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base dialog for user notification.
+ A base dialog used for user notification.
</brief_description>
<description>
- This dialog is useful for small notifications to the user about an event. It can only be accepted or closed, with the same result.
+ The default use of [AcceptDialog] is to allow it to only be accepted or closed, with the same result. However, the [signal confirmed] and [signal canceled] signals allow to make the two actions different, and the [method add_button] method allows to add custom buttons and actions.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AnimatableBody2D.xml b/doc/classes/AnimatableBody2D.xml
index fa99d774c2..2a0f831fe6 100644
--- a/doc/classes/AnimatableBody2D.xml
+++ b/doc/classes/AnimatableBody2D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AnimatableBody2D" inherits="StaticBody2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics body for 2D physics which moves only by script or animation (while affecting other bodies on its path). Useful for moving platforms and doors.
+ A 2D physics body that can't be moved by external forces. When moved manually, it affects other bodies in its path.
</brief_description>
<description>
- Animatable body for 2D physics.
- An animatable body can't be moved by external forces or contacts, but can be moved by script or animation to affect other bodies in its path. It is ideal for implementing moving objects in the environment, such as moving platforms or doors.
- When the body is moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to [code]physics[/code]), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
+ An animatable 2D physics body. It can't be moved by external forces or contacts, but can be moved manually by other means such as code, [AnimationPlayer]s (with [member AnimationPlayer.playback_process_mode] set to [code]ANIMATION_PROCESS_PHYSICS[/code]), and [RemoteTransform2D].
+ When [AnimatableBody2D] is moved, its linear and angular velocity are estimated and used to affect other physics bodies in its path. This makes it useful for moving platforms, doors, and other moving objects.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AnimatableBody3D.xml b/doc/classes/AnimatableBody3D.xml
index ad8135b842..a8b88ab77b 100644
--- a/doc/classes/AnimatableBody3D.xml
+++ b/doc/classes/AnimatableBody3D.xml
@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AnimatableBody3D" inherits="StaticBody3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics body for 3D physics which moves only by script or animation (while affecting other bodies on its path). Useful for moving platforms and doors.
+ A 3D physics body that can't be moved by external forces. When moved manually, it affects other bodies in its path.
</brief_description>
<description>
- Animatable body for 3D physics.
- An animatable body can't be moved by external forces or contacts, but can be moved by script or animation to affect other bodies in its path. It is ideal for implementing moving objects in the environment, such as moving platforms or doors.
- When the body is moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to [code]physics[/code]), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ An animatable 3D physics body. It can't be moved by external forces or contacts, but can be moved manually by other means such as code, [AnimationPlayer]s (with [member AnimationPlayer.playback_process_mode] set to [code]ANIMATION_PROCESS_PHYSICS[/code]), and [RemoteTransform3D].
+ When [AnimatableBody3D] is moved, its linear and angular velocity are estimated and used to affect other physics bodies in its path. This makes it useful for moving platforms, doors, and other moving objects.
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml
index cb6a4f30f9..a86ec396ee 100644
--- a/doc/classes/AnimationNode.xml
+++ b/doc/classes/AnimationNode.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Base resource for [AnimationTree] nodes. In general, it's not used directly, but you can create custom ones with custom blending formulas.
- Inherit this when creating nodes mainly for use in [AnimationNodeBlendTree], otherwise [AnimationRootNode] should be used instead.
+ Inherit this when creating animation nodes mainly for use in [AnimationNodeBlendTree], otherwise [AnimationRootNode] should be used instead.
</description>
<tutorials>
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
@@ -14,46 +14,46 @@
<method name="_get_caption" qualifiers="virtual const">
<return type="String" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to override the text caption for this node.
+ When inheriting from [AnimationRootNode], implement this virtual method to override the text caption for this animation node.
</description>
</method>
<method name="_get_child_by_name" qualifiers="virtual const">
<return type="AnimationNode" />
<param index="0" name="name" type="StringName" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return a child node by its [param name].
+ When inheriting from [AnimationRootNode], implement this virtual method to return a child animation node by its [param name].
</description>
</method>
<method name="_get_child_nodes" qualifiers="virtual const">
<return type="Dictionary" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return all children nodes in order as a [code]name: node[/code] dictionary.
+ When inheriting from [AnimationRootNode], implement this virtual method to return all children animation nodes in order as a [code]name: node[/code] dictionary.
</description>
</method>
<method name="_get_parameter_default_value" qualifiers="virtual const">
<return type="Variant" />
<param index="0" name="parameter" type="StringName" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return the default value of a [param parameter]. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees.
+ When inheriting from [AnimationRootNode], implement this virtual method to return the default value of a [param parameter]. Parameters are custom local memory used for your animation nodes, given a resource can be reused in multiple trees.
</description>
</method>
<method name="_get_parameter_list" qualifiers="virtual const">
<return type="Array" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return a list of the properties on this node. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees. Format is similar to [method Object.get_property_list].
+ When inheriting from [AnimationRootNode], implement this virtual method to return a list of the properties on this animation node. Parameters are custom local memory used for your animation nodes, given a resource can be reused in multiple trees. Format is similar to [method Object.get_property_list].
</description>
</method>
<method name="_has_filter" qualifiers="virtual const">
<return type="bool" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return whether the blend tree editor should display filter editing on this node.
+ When inheriting from [AnimationRootNode], implement this virtual method to return whether the blend tree editor should display filter editing on this animation node.
</description>
</method>
<method name="_is_parameter_read_only" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="parameter" type="StringName" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to return whether the [param parameter] is read-only. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees.
+ When inheriting from [AnimationRootNode], implement this virtual method to return whether the [param parameter] is read-only. Parameters are custom local memory used for your animation nodes, given a resource can be reused in multiple trees.
</description>
</method>
<method name="_process" qualifiers="virtual const">
@@ -63,7 +63,7 @@
<param index="2" name="is_external_seeking" type="bool" />
<param index="3" name="test_only" type="bool" />
<description>
- When inheriting from [AnimationRootNode], implement this virtual method to run some code when this node is processed. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute.
+ When inheriting from [AnimationRootNode], implement this virtual method to run some code when this animation node is processed. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute.
Here, call the [method blend_input], [method blend_node] or [method blend_animation] functions. You can also use [method get_parameter] and [method set_parameter] to modify local memory.
This function should return the time left for the current animation to finish (if unsure, pass the value from the main blend being called).
</description>
@@ -72,7 +72,7 @@
<return type="bool" />
<param index="0" name="name" type="String" />
<description>
- Adds an input to the node. This is only useful for nodes created for use in an [AnimationNodeBlendTree]. If the addition fails, returns [code]false[/code].
+ Adds an input to the animation node. This is only useful for animation nodes created for use in an [AnimationNodeBlendTree]. If the addition fails, returns [code]false[/code].
</description>
</method>
<method name="blend_animation">
@@ -100,7 +100,7 @@
<param index="6" name="sync" type="bool" default="true" />
<param index="7" name="test_only" type="bool" default="false" />
<description>
- Blend an input. This is only useful for nodes created for an [AnimationNodeBlendTree]. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute. A filter mode may be optionally passed (see [enum FilterAction] for options).
+ Blend an input. This is only useful for animation nodes created for an [AnimationNodeBlendTree]. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute. A filter mode may be optionally passed (see [enum FilterAction] for options).
</description>
</method>
<method name="blend_node">
@@ -115,7 +115,7 @@
<param index="7" name="sync" type="bool" default="true" />
<param index="8" name="test_only" type="bool" default="false" />
<description>
- Blend another animation node (in case this node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your node for addition.
+ Blend another animation node (in case this animation node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your animation node for addition.
</description>
</method>
<method name="find_input" qualifiers="const">
@@ -128,7 +128,7 @@
<method name="get_input_count" qualifiers="const">
<return type="int" />
<description>
- Amount of inputs in this node, only useful for nodes that go into [AnimationNodeBlendTree].
+ Amount of inputs in this animation node, only useful for animation nodes that go into [AnimationNodeBlendTree].
</description>
</method>
<method name="get_input_name" qualifiers="const">
@@ -142,7 +142,7 @@
<return type="Variant" />
<param index="0" name="name" type="StringName" />
<description>
- Gets the value of a parameter. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees.
+ Gets the value of a parameter. Parameters are custom local memory used for your animation nodes, given a resource can be reused in multiple trees.
</description>
</method>
<method name="is_path_filtered" qualifiers="const">
@@ -194,7 +194,7 @@
<param index="0" name="object_id" type="int" />
<param index="1" name="name" type="String" />
<description>
- Emitted by nodes that inherit from this class and that have an internal tree when one of their nodes removes. The nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], and [AnimationNodeBlendTree].
+ Emitted by nodes that inherit from this class and that have an internal tree when one of their animation nodes removes. The animation nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], and [AnimationNodeBlendTree].
</description>
</signal>
<signal name="animation_node_renamed">
@@ -202,12 +202,12 @@
<param index="1" name="old_name" type="String" />
<param index="2" name="new_name" type="String" />
<description>
- Emitted by nodes that inherit from this class and that have an internal tree when one of their node names changes. The nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], and [AnimationNodeBlendTree].
+ Emitted by nodes that inherit from this class and that have an internal tree when one of their animation node names changes. The animation nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], and [AnimationNodeBlendTree].
</description>
</signal>
<signal name="tree_changed">
<description>
- Emitted by nodes that inherit from this class and that have an internal tree when one of their nodes changes. The nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], [AnimationNodeBlendTree] and [AnimationNodeTransition].
+ Emitted by nodes that inherit from this class and that have an internal tree when one of their animation nodes changes. The animation nodes that emit this signal are [AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], [AnimationNodeStateMachine], [AnimationNodeBlendTree] and [AnimationNodeTransition].
</description>
</signal>
</signals>
diff --git a/doc/classes/AnimationNodeAdd2.xml b/doc/classes/AnimationNodeAdd2.xml
index 68bbe8090b..3aaf772716 100644
--- a/doc/classes/AnimationNodeAdd2.xml
+++ b/doc/classes/AnimationNodeAdd2.xml
@@ -4,7 +4,9 @@
Blends two animations additively inside of an [AnimationNodeBlendTree].
</brief_description>
<description>
- A resource to add to an [AnimationNodeBlendTree]. Blends two animations additively based on an amount value in the [code][0.0, 1.0][/code] range.
+ A resource to add to an [AnimationNodeBlendTree]. Blends two animations additively based on the amount value.
+ If the amount is greater than [code]1.0[/code], the animation connected to "in" port is blended with the amplified animation connected to "add" port.
+ If the amount is less than [code]0.0[/code], the animation connected to "in" port is blended with the inverted animation connected to "add" port.
</description>
<tutorials>
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
diff --git a/doc/classes/AnimationNodeAdd3.xml b/doc/classes/AnimationNodeAdd3.xml
index 1e51a8a4c5..7048c2329c 100644
--- a/doc/classes/AnimationNodeAdd3.xml
+++ b/doc/classes/AnimationNodeAdd3.xml
@@ -4,11 +4,12 @@
Blends two of three animations additively inside of an [AnimationNodeBlendTree].
</brief_description>
<description>
- A resource to add to an [AnimationNodeBlendTree]. Blends two animations together additively out of three based on a value in the [code][-1.0, 1.0][/code] range.
- This node has three inputs:
+ A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three additively out of three based on the amounmt value.
+ This animation node has three inputs:
- The base animation to add to
- - A -add animation to blend with when the blend amount is in the [code][-1.0, 0.0][/code] range.
- - A +add animation to blend with when the blend amount is in the [code][0.0, 1.0][/code] range
+ - A "-add" animation to blend with when the blend amount is negative
+ - A "+add" animation to blend with when the blend amount is positive
+ If the absolute value of the amount is greater than [code]1.0[/code], the animation connected to "in" port is blended with the amplified animation connected to "-add"/"+add" port.
</description>
<tutorials>
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
diff --git a/doc/classes/AnimationNodeBlend2.xml b/doc/classes/AnimationNodeBlend2.xml
index 1460f5f055..db27a7d87d 100644
--- a/doc/classes/AnimationNodeBlend2.xml
+++ b/doc/classes/AnimationNodeBlend2.xml
@@ -4,7 +4,8 @@
Blends two animations linearly inside of an [AnimationNodeBlendTree].
</brief_description>
<description>
- A resource to add to an [AnimationNodeBlendTree]. Blends two animations linearly based on an amount value in the [code][0.0, 1.0][/code] range.
+ A resource to add to an [AnimationNodeBlendTree]. Blends two animations linearly based on the amount value.
+ In general, the blend value should be in the [code][0.0, 1.0][/code] range. Values outside of this range can blend amplified or inverted animations, however, [AnimationNodeAdd2] works better for this purpose.
</description>
<tutorials>
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
diff --git a/doc/classes/AnimationNodeBlend3.xml b/doc/classes/AnimationNodeBlend3.xml
index 34c4b8566a..b7a5403238 100644
--- a/doc/classes/AnimationNodeBlend3.xml
+++ b/doc/classes/AnimationNodeBlend3.xml
@@ -4,11 +4,12 @@
Blends two of three animations linearly inside of an [AnimationNodeBlendTree].
</brief_description>
<description>
- A resource to add to an [AnimationNodeBlendTree]. Blends two animations together linearly out of three based on a value in the [code][-1.0, 1.0][/code] range.
- This node has three inputs:
- - The base animation
- - A -blend animation to blend with when the blend amount is in the [code][-1.0, 0.0][/code] range.
- - A +blend animation to blend with when the blend amount is in the [code][0.0, 1.0][/code] range
+ A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three linearly out of three based on the amounmt value.
+ This animation node has three inputs:
+ - The base animation to blend with
+ - A "-blend" animation to blend with when the blend amount is negative value
+ - A "+blend" animation to blend with when the blend amount is positive value
+ In general, the blend value should be in the [code][-1.0, 1.0][/code] range. Values outside of this range can blend amplified animations, however, [AnimationNodeAdd3] works better for this purpose.
</description>
<tutorials>
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
diff --git a/doc/classes/AnimationNodeBlendSpace1D.xml b/doc/classes/AnimationNodeBlendSpace1D.xml
index aa15ac03d9..02f0053380 100644
--- a/doc/classes/AnimationNodeBlendSpace1D.xml
+++ b/doc/classes/AnimationNodeBlendSpace1D.xml
@@ -91,7 +91,7 @@
The interpolation between animations is linear.
</constant>
<constant name="BLEND_MODE_DISCRETE" value="1" enum="BlendMode">
- The blend space plays the animation of the node the blending position is closest to. Useful for frame-by-frame 2D animations.
+ The blend space plays the animation of the animation node which blending position is closest to. Useful for frame-by-frame 2D animations.
</constant>
<constant name="BLEND_MODE_DISCRETE_CARRY" value="2" enum="BlendMode">
Similar to [constant BLEND_MODE_DISCRETE], but starts the new animation at the last animation's playback position.
diff --git a/doc/classes/AnimationNodeBlendSpace2D.xml b/doc/classes/AnimationNodeBlendSpace2D.xml
index 27dff11e88..46606f12b0 100644
--- a/doc/classes/AnimationNodeBlendSpace2D.xml
+++ b/doc/classes/AnimationNodeBlendSpace2D.xml
@@ -136,7 +136,7 @@
The interpolation between animations is linear.
</constant>
<constant name="BLEND_MODE_DISCRETE" value="1" enum="BlendMode">
- The blend space plays the animation of the node the blending position is closest to. Useful for frame-by-frame 2D animations.
+ The blend space plays the animation of the animation node which blending position is closest to. Useful for frame-by-frame 2D animations.
</constant>
<constant name="BLEND_MODE_DISCRETE_CARRY" value="2" enum="BlendMode">
Similar to [constant BLEND_MODE_DISCRETE], but starts the new animation at the last animation's playback position.
diff --git a/doc/classes/AnimationNodeBlendTree.xml b/doc/classes/AnimationNodeBlendTree.xml
index 9ae34e8038..4b3bf4c806 100644
--- a/doc/classes/AnimationNodeBlendTree.xml
+++ b/doc/classes/AnimationNodeBlendTree.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AnimationNodeBlendTree" inherits="AnimationRootNode" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A sub-tree of blend type [AnimationNode]s used for complex animations. Used by [AnimationTree].
+ A sub-tree of many type [AnimationNode]s used for complex animations. Used by [AnimationTree].
</brief_description>
<description>
- This node may contain a sub-tree of any other blend type nodes, such as [AnimationNodeTransition], [AnimationNodeBlend2], [AnimationNodeBlend3], [AnimationNodeOneShot], etc. This is one of the most commonly used animation node roots.
+ This animation node may contain a sub-tree of any other type animation nodes, such as [AnimationNodeTransition], [AnimationNodeBlend2], [AnimationNodeBlend3], [AnimationNodeOneShot], etc. This is one of the most commonly used animation node roots.
An [AnimationNodeOutput] node named [code]output[/code] is created by default.
</description>
<tutorials>
@@ -17,7 +17,7 @@
<param index="1" name="node" type="AnimationNode" />
<param index="2" name="position" type="Vector2" default="Vector2(0, 0)" />
<description>
- Adds an [AnimationNode] at the given [param position]. The [param name] is used to identify the created sub-node later.
+ Adds an [AnimationNode] at the given [param position]. The [param name] is used to identify the created sub animation node later.
</description>
</method>
<method name="connect_node">
@@ -34,35 +34,35 @@
<param index="0" name="input_node" type="StringName" />
<param index="1" name="input_index" type="int" />
<description>
- Disconnects the node connected to the specified input.
+ Disconnects the animation node connected to the specified input.
</description>
</method>
<method name="get_node" qualifiers="const">
<return type="AnimationNode" />
<param index="0" name="name" type="StringName" />
<description>
- Returns the sub-node with the specified [param name].
+ Returns the sub animation node with the specified [param name].
</description>
</method>
<method name="get_node_position" qualifiers="const">
<return type="Vector2" />
<param index="0" name="name" type="StringName" />
<description>
- Returns the position of the sub-node with the specified [param name].
+ Returns the position of the sub animation node with the specified [param name].
</description>
</method>
<method name="has_node" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="StringName" />
<description>
- Returns [code]true[/code] if a sub-node with specified [param name] exists.
+ Returns [code]true[/code] if a sub animation node with specified [param name] exists.
</description>
</method>
<method name="remove_node">
<return type="void" />
<param index="0" name="name" type="StringName" />
<description>
- Removes a sub-node.
+ Removes a sub animation node.
</description>
</method>
<method name="rename_node">
@@ -70,7 +70,7 @@
<param index="0" name="name" type="StringName" />
<param index="1" name="new_name" type="StringName" />
<description>
- Changes the name of a sub-node.
+ Changes the name of a sub animation node.
</description>
</method>
<method name="set_node_position">
@@ -78,13 +78,13 @@
<param index="0" name="name" type="StringName" />
<param index="1" name="position" type="Vector2" />
<description>
- Modifies the position of a sub-node.
+ Modifies the position of a sub animation node.
</description>
</method>
</methods>
<members>
<member name="graph_offset" type="Vector2" setter="set_graph_offset" getter="get_graph_offset" default="Vector2(0, 0)">
- The global offset of all sub-nodes.
+ The global offset of all sub animation nodes.
</member>
</members>
<signals>
diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml
index bdf2f18431..7e5e61e56b 100644
--- a/doc/classes/AnimationNodeOneShot.xml
+++ b/doc/classes/AnimationNodeOneShot.xml
@@ -4,7 +4,7 @@
Plays an animation once in an [AnimationNodeBlendTree].
</brief_description>
<description>
- A resource to add to an [AnimationNodeBlendTree]. This node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters.
+ A resource to add to an [AnimationNodeBlendTree]. This animation node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters.
After setting the request and changing the animation playback, the one-shot node automatically clears the request on the next process frame by setting its [code]request[/code] value to [constant ONE_SHOT_REQUEST_NONE].
[codeblocks]
[gdscript]
diff --git a/doc/classes/AnimationNodeStateMachine.xml b/doc/classes/AnimationNodeStateMachine.xml
index 9459c31b3b..b2b9166c38 100644
--- a/doc/classes/AnimationNodeStateMachine.xml
+++ b/doc/classes/AnimationNodeStateMachine.xml
@@ -4,7 +4,7 @@
A state machine with multiple [AnimationRootNode]s, used by [AnimationTree].
</brief_description>
<description>
- Contains multiple [AnimationRootNode]s representing animation states, connected in a graph. Node transitions can be configured to happen automatically or via code, using a shortest-path algorithm. Retrieve the [AnimationNodeStateMachinePlayback] object from the [AnimationTree] node to control it programmatically.
+ Contains multiple [AnimationRootNode]s representing animation states, connected in a graph. State transitions can be configured to happen automatically or via code, using a shortest-path algorithm. Retrieve the [AnimationNodeStateMachinePlayback] object from the [AnimationTree] node to control it programmatically.
[b]Example:[/b]
[codeblocks]
[gdscript]
@@ -27,7 +27,7 @@
<param index="1" name="node" type="AnimationNode" />
<param index="2" name="position" type="Vector2" default="Vector2(0, 0)" />
<description>
- Adds a new node to the graph. The [param position] is used for display in the editor.
+ Adds a new animation node to the graph. The [param position] is used for display in the editor.
</description>
</method>
<method name="add_transition">
@@ -36,7 +36,7 @@
<param index="1" name="to" type="StringName" />
<param index="2" name="transition" type="AnimationNodeStateMachineTransition" />
<description>
- Adds a transition between the given nodes.
+ Adds a transition between the given animation nodes.
</description>
</method>
<method name="get_graph_offset" qualifiers="const">
@@ -63,7 +63,7 @@
<return type="Vector2" />
<param index="0" name="name" type="StringName" />
<description>
- Returns the given node's coordinates. Used for display in the editor.
+ Returns the given animation node's coordinates. Used for display in the editor.
</description>
</method>
<method name="get_transition" qualifiers="const">
@@ -97,7 +97,7 @@
<return type="bool" />
<param index="0" name="name" type="StringName" />
<description>
- Returns [code]true[/code] if the graph contains the given node.
+ Returns [code]true[/code] if the graph contains the given animation node.
</description>
</method>
<method name="has_transition" qualifiers="const">
@@ -105,14 +105,14 @@
<param index="0" name="from" type="StringName" />
<param index="1" name="to" type="StringName" />
<description>
- Returns [code]true[/code] if there is a transition between the given nodes.
+ Returns [code]true[/code] if there is a transition between the given animation nodes.
</description>
</method>
<method name="remove_node">
<return type="void" />
<param index="0" name="name" type="StringName" />
<description>
- Deletes the given node from the graph.
+ Deletes the given animation node from the graph.
</description>
</method>
<method name="remove_transition">
@@ -120,7 +120,7 @@
<param index="0" name="from" type="StringName" />
<param index="1" name="to" type="StringName" />
<description>
- Deletes the transition between the two specified nodes.
+ Deletes the transition between the two specified animation nodes.
</description>
</method>
<method name="remove_transition_by_index">
@@ -135,7 +135,7 @@
<param index="0" name="name" type="StringName" />
<param index="1" name="new_name" type="StringName" />
<description>
- Renames the given node.
+ Renames the given animation node.
</description>
</method>
<method name="replace_node">
@@ -157,7 +157,7 @@
<param index="0" name="name" type="StringName" />
<param index="1" name="position" type="Vector2" />
<description>
- Sets the node's coordinates. Used for display in the editor.
+ Sets the animation node's coordinates. Used for display in the editor.
</description>
</method>
</methods>
diff --git a/doc/classes/AnimationNodeSub2.xml b/doc/classes/AnimationNodeSub2.xml
new file mode 100644
index 0000000000..f913526a23
--- /dev/null
+++ b/doc/classes/AnimationNodeSub2.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="AnimationNodeSub2" inherits="AnimationNodeSync" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Blends two animations subtractively inside of an [AnimationNodeBlendTree].
+ </brief_description>
+ <description>
+ A resource to add to an [AnimationNodeBlendTree]. Blends two animations subtractively based on the amount value.
+ This animation node is usually used for pre-calculation to cancel out any extra poses from the animation for the "add" animation source in [AnimationNodeAdd2] or [AnimationNodeAdd3].
+ In general, the blend value should be in the [code][0.0, 1.0][/code] range, but values outside of this range can be used for amplified or inverted animations.
+ [b]Note:[/b] This calculation is different from using a negative value in [AnimationNodeAdd2], since the transformation matrices do not satisfy the commutative law. [AnimationNodeSub2] multiplies the transformation matrix of the inverted animation from the left side, while negative [AnimationNodeAdd2] multiplies it from the right side.
+ </description>
+ <tutorials>
+ <link title="AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
+ </tutorials>
+</class>
diff --git a/doc/classes/AnimationNodeTimeSeek.xml b/doc/classes/AnimationNodeTimeSeek.xml
index 3098fa7662..053e2e0bb2 100644
--- a/doc/classes/AnimationNodeTimeSeek.xml
+++ b/doc/classes/AnimationNodeTimeSeek.xml
@@ -4,7 +4,7 @@
A time-seeking animation node used in [AnimationTree].
</brief_description>
<description>
- This node can be used to cause a seek command to happen to any sub-children of the animation graph. Use this node type to play an [Animation] from the start or a certain playback position inside the [AnimationNodeBlendTree].
+ This animation node can be used to cause a seek command to happen to any sub-children of the animation graph. Use to play an [Animation] from the start or a certain playback position inside the [AnimationNodeBlendTree].
After setting the time and changing the animation playback, the time seek node automatically goes into sleep mode on the next process frame by setting its [code]seek_request[/code] value to [code]-1.0[/code].
[codeblocks]
[gdscript]
diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml
index 481ea9ff59..0d97f128ab 100644
--- a/doc/classes/AnimationNodeTransition.xml
+++ b/doc/classes/AnimationNodeTransition.xml
@@ -20,7 +20,7 @@
animation_tree["parameters/Transition/current_state"]
# Get current state index (read-only).
- animation_tree.get("parameters/Transition/current_index"))
+ animation_tree.get("parameters/Transition/current_index")
# Alternative syntax (same result as above).
animation_tree["parameters/Transition/current_index"]
[/gdscript]
@@ -78,7 +78,7 @@
If [code]true[/code], allows transition to the self state. When the reset option is enabled in input, the animation is restarted. If [code]false[/code], nothing happens on the transition to the self state.
</member>
<member name="input_count" type="int" setter="set_input_count" getter="get_input_count" default="0">
- The number of enabled input ports for this node.
+ The number of enabled input ports for this animation node.
</member>
<member name="xfade_curve" type="Curve" setter="set_xfade_curve" getter="get_xfade_curve">
Determines how cross-fading between animations is eased. If empty, the transition will be linear.
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index e197e7d04d..e973cd9aae 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Area2D" inherits="CollisionObject2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 2D area for detection, as well as physics and audio influence.
+ A region of 2D space that detects other [CollisionObject2D]s entering or exiting it.
</brief_description>
<description>
- 2D area that detects [CollisionObject2D] nodes overlapping, entering, or exiting. Can also alter or override local physics parameters (gravity, damping) and route audio to custom audio buses.
- To give the area its shape, add a [CollisionShape2D] or a [CollisionPolygon2D] node as a [i]direct[/i] child (or add multiple such nodes as direct children) of the area.
- [b]Warning:[/b] See [ConcavePolygonShape2D] for a warning about possibly unexpected behavior when using that shape for an area.
+ [Area2D] is a region of 2D space defined by one or multiple [CollisionShape2D] or [CollisionPolygon2D] child nodes. It detects when other [CollisionObject2D]s enter or exit it, and it also keeps track of which collision objects haven't exited it yet (i.e. which one are overlapping it).
+ This node can also locally alter or override physics parameters (gravity, damping) and route audio to custom audio buses.
</description>
<tutorials>
<link title="Using Area2D">$DOCS_URL/tutorials/physics/using_area_2d.html</link>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index e009d35eeb..4d1c8000c4 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Area3D" inherits="CollisionObject3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 3D area for detection, as well as physics and audio influence.
+ A region of 3D space that detects other [CollisionObject3D]s entering or exiting it.
</brief_description>
<description>
- 3D area that detects [CollisionObject3D] nodes overlapping, entering, or exiting. Can also alter or override local physics parameters (gravity, damping) and route audio to custom audio buses.
- To give the area its shape, add a [CollisionShape3D] or a [CollisionPolygon3D] node as a [i]direct[/i] child (or add multiple such nodes as direct children) of the area.
- [b]Warning:[/b] See [ConcavePolygonShape3D] (also called "trimesh") for a warning about possibly unexpected behavior when using that shape for an area.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ [Area3D] is a region of 3D space defined by one or multiple [CollisionShape3D] or [CollisionPolygon3D] child nodes. It detects when other [CollisionObject3D]s enter or exit it, and it also keeps track of which collision objects haven't exited it yet (i.e. which one are overlapping it).
+ This node can also locally alter or override physics parameters (gravity, damping) and route audio to custom audio buses.
+ [b]Warning:[/b] Using a [ConcavePolygonShape3D] inside a [CollisionShape3D] child of this node (created e.g. by using the [i]Create Trimesh Collision Sibling[/i] option in the [i]Mesh[/i] menu that appears when selecting a [MeshInstance3D] node) may give unexpected results, since this collision shape is hollow. If this is not desired, it has to be split into multiple [ConvexPolygonShape3D]s or primitive shapes like [BoxShape3D], or in some cases it may be replaceable by a [CollisionPolygon3D].
</description>
<tutorials>
+ <link title="Using Area2D">$DOCS_URL/tutorials/physics/using_area_2d.html</link>
<link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link>
<link title="GUI in 3D Demo">https://godotengine.org/asset-library/asset/127</link>
</tutorials>
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 1c761f9f1a..cdfc04c62f 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Array" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A generic array datatype.
+ A built-in data structure that holds a sequence of elements.
</brief_description>
<description>
- A generic array that can contain several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 is the second to last, etc.).
+ An array data structure that can contain a sequence of elements of any type. Elements are accessed by a numerical index starting at 0. Negative indices are used to count from the back (-1 is the last element, -2 is the second to last, etc.).
[b]Example:[/b]
[codeblocks]
[gdscript]
@@ -38,7 +38,6 @@
GD.Print(array1 + array2); // Prints [One, 2, 3, Four]
[/csharp]
[/codeblocks]
- [b]Note:[/b] Concatenating with the [code]+=[/code] operator will create a new array, which has a cost. If you want to append another array to an existing array, [method append_array] is more efficient.
[b]Note:[/b] Arrays are always passed by reference. To get a copy of an array that can be modified independently of the original array, use [method duplicate].
[b]Note:[/b] Erasing elements while iterating over arrays is [b]not[/b] supported and will result in unpredictable behavior.
</description>
diff --git a/doc/classes/AspectRatioContainer.xml b/doc/classes/AspectRatioContainer.xml
index 371a27274c..0f4f7687b9 100644
--- a/doc/classes/AspectRatioContainer.xml
+++ b/doc/classes/AspectRatioContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AspectRatioContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Container that preserves its child controls' aspect ratio.
+ A container that preserves the proportions of its child controls.
</brief_description>
<description>
- Arranges child controls in a way to preserve their aspect ratio automatically whenever the container is resized. Solves the problem where the container size is dynamic and the contents' size needs to adjust accordingly without losing proportions.
+ A container type that arranges its child controls in a way that preserves their proportions automatically when the container is resized. Useful when a container has a dynamic size and the child nodes must adjust their sizes accordingly without losing their aspect ratios.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<members>
<member name="alignment_horizontal" type="int" setter="set_alignment_horizontal" getter="get_alignment_horizontal" enum="AspectRatioContainer.AlignmentMode" default="1">
diff --git a/doc/classes/AudioStreamPlaybackPolyphonic.xml b/doc/classes/AudioStreamPlaybackPolyphonic.xml
index 6c1bfb74df..0143a38401 100644
--- a/doc/classes/AudioStreamPlaybackPolyphonic.xml
+++ b/doc/classes/AudioStreamPlaybackPolyphonic.xml
@@ -24,7 +24,7 @@
<param index="3" name="pitch_scale" type="float" default="1.0" />
<description>
Play an [AudioStream] at a given offset, volume and pitch scale. Playback starts immediately.
- The return value is an unique integer ID that is associated to this playback stream and which can be used to control it.
+ The return value is a unique integer ID that is associated to this playback stream and which can be used to control it.
This ID becomes invalid when the stream ends (if it does not loop), when the [AudioStreamPlaybackPolyphonic] is stopped, or when [method stop_stream] is called.
This function returns [constant INVALID_ID] if the amount of streams currently playing equals [member AudioStreamPolyphonic.polyphony]. If you need a higher amount of maximum polyphony, raise this value.
</description>
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index a934e1544a..1290bfc0f2 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BaseButton" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for different kinds of buttons.
+ Abstract base class for GUI buttons.
</brief_description>
<description>
- BaseButton is the abstract base class for buttons, so it shouldn't be used directly (it doesn't display anything). Other types of buttons inherit from it.
+ [BaseButton] is an abstract base class for GUI buttons. It doesn't display anything by itself.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml
index a769cfeabf..f84d14a5a6 100644
--- a/doc/classes/Basis.xml
+++ b/doc/classes/Basis.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Basis" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 3×3 matrix datatype.
+ A 3×3 matrix for representing 3D rotation and scale.
</brief_description>
<description>
- 3×3 matrix used for 3D rotation and scale. Almost always used as an orthogonal basis for a [Transform3D].
+ A 3×3 matrix used for representing 3D rotation and scale. Usually used as an orthogonal basis for a [Transform3D].
Contains 3 vector fields X, Y and Z as its columns, which are typically interpreted as the local basis vectors of a transformation. For such use, it is composed of a scaling and a rotation matrix, in that order (M = R.S).
- Can also be accessed as array of 3D vectors. These vectors are normally orthogonal to each other, but are not necessarily normalized (due to scaling).
+ Basis can also be accessed as an array of 3D vectors. These vectors are usually orthogonal to each other, but are not necessarily normalized (due to scaling).
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
@@ -110,13 +110,13 @@
<return type="bool" />
<param index="0" name="b" type="Basis" />
<description>
- Returns [code]true[/code] if this basis and [param b] are approximately equal, by calling [code]is_equal_approx[/code] on each component.
+ Returns [code]true[/code] if this basis and [param b] are approximately equal, by calling [method @GlobalScope.is_equal_approx] on all vector components.
</description>
</method>
<method name="is_finite" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if this basis is finite, by calling [method @GlobalScope.is_finite] on each component.
+ Returns [code]true[/code] if this basis is finite, by calling [method @GlobalScope.is_finite] on all vector components.
</description>
</method>
<method name="looking_at" qualifiers="static">
diff --git a/doc/classes/BoxContainer.xml b/doc/classes/BoxContainer.xml
index 2fccb02c05..1716fc83fb 100644
--- a/doc/classes/BoxContainer.xml
+++ b/doc/classes/BoxContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BoxContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for box containers.
+ A container that arranges its child controls horizontally or vertically.
</brief_description>
<description>
- Arranges child [Control] nodes vertically or horizontally, and rearranges them automatically when their minimum size changes.
+ A container that arranges its child controls horizontally or vertically, rearranging them automatically when their minimum size changes.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="add_spacer">
diff --git a/doc/classes/BoxShape3D.xml b/doc/classes/BoxShape3D.xml
index c6e41023b3..1886e8f29a 100644
--- a/doc/classes/BoxShape3D.xml
+++ b/doc/classes/BoxShape3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BoxShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Box shape resource for 3D collisions.
+ A 3D box shape used for physics collision.
</brief_description>
<description>
- 3D box shape to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node.
- [b]Performance:[/b] Being a primitive collision shape, [BoxShape3D] is fast to check collisions against (though not as fast as [SphereShape3D]).
+ A 3D box shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
+ [b]Performance:[/b] [BoxShape3D] is fast to check collisions against. It is faster than [CapsuleShape3D] and [CylinderShape3D], but slower than [SphereShape3D].
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index 1bf5c31818..e5d57d3f18 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Button" inherits="BaseButton" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Standard themed Button.
+ A themed button that can contain text and an icon.
</brief_description>
<description>
- Button is the standard themed button. It can contain text and an icon, and will display them according to the current [Theme].
+ [Button] is the standard themed button. It can contain text and an icon, and it will display them according to the current [Theme].
[b]Example of creating a button and assigning an action when pressed by code:[/b]
[codeblocks]
[gdscript]
@@ -32,9 +32,8 @@
}
[/csharp]
[/codeblocks]
- Buttons (like all Control nodes) can also be created in the editor, but some situations may require creating them from code.
See also [BaseButton] which contains common properties and methods associated with this node.
- [b]Note:[/b] Buttons do not interpret touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions, as [TouchScreenButton] supports multitouch.
+ [b]Note:[/b] Buttons do not interpret touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions.
</description>
<tutorials>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
diff --git a/doc/classes/ButtonGroup.xml b/doc/classes/ButtonGroup.xml
index ebc902bea7..bb32319a31 100644
--- a/doc/classes/ButtonGroup.xml
+++ b/doc/classes/ButtonGroup.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ButtonGroup" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Group of Buttons.
+ A group of buttons that doesn't allow more than one button to be pressed at a time.
</brief_description>
<description>
- Group of [BaseButton]. The members of this group are treated like radio buttons in the sense that only one button can be pressed at the same time. Some types of buttons (such as [CheckBox]) may have a special appearance for this state.
- Every member of the ButtonGroup should have [member BaseButton.toggle_mode] set to [code]true[/code].
+ A group of [BaseButton]-derived buttons. The buttons in a [ButtonGroup] are treated like radio buttons: No more than one button can be pressed at a time. Some types of buttons (such as [CheckBox]) may have a special appearance in this state.
+ Every member of a [ButtonGroup] should have [member BaseButton.toggle_mode] set to [code]true[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml
index a4c639812c..87f1f0b538 100644
--- a/doc/classes/Callable.xml
+++ b/doc/classes/Callable.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Callable" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Built-in type representing a method in an object instance or a standalone function.
+ A built-in type representing a method or a standalone function.
</brief_description>
<description>
[Callable] is a built-in [Variant] type that represents a function. It can either be a method within an [Object] instance, or a standalone function not related to any object, like a lambda function. Like all [Variant] types, it can be stored in variables and passed to other functions. It is most commonly used for signal callbacks.
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 94f310ebfa..cb10367183 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -1,15 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CanvasItem" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class of anything 2D.
+ Abstract base class for everything in 2D space.
</brief_description>
<description>
- Base class of anything 2D. Canvas items are laid out in a tree; children inherit and extend their parent's transform. [CanvasItem] is extended by [Control] for anything GUI-related, and by [Node2D] for anything related to the 2D engine.
- Any [CanvasItem] can draw. For this, [method queue_redraw] is called by the engine, then [constant NOTIFICATION_DRAW] will be received on idle time to request redraw. Because of this, canvas items don't need to be redrawn on every frame, improving the performance significantly. Several functions for drawing on the [CanvasItem] are provided (see [code]draw_*[/code] functions). However, they can only be used inside [method _draw], its corresponding [method Object._notification] or methods connected to the [signal draw] signal.
- Canvas items are drawn in tree order. By default, children are on top of their parents so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis.
- A [CanvasItem] can also be hidden, which will also hide its children. It provides many ways to change parameters such as modulation (for itself and its children) and self modulation (only for itself), as well as its blend mode.
- Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
- [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg_to_rad].
+ Abstract base class for everything in 2D space. Canvas items are laid out in a tree; children inherit and extend their parent's transform. [CanvasItem] is extended by [Control] for GUI-related nodes, and by [Node2D] for 2D game objects.
+ Any [CanvasItem] can draw. For this, [method queue_redraw] is called by the engine, then [constant NOTIFICATION_DRAW] will be received on idle time to request a redraw. Because of this, canvas items don't need to be redrawn on every frame, improving the performance significantly. Several functions for drawing on the [CanvasItem] are provided (see [code]draw_*[/code] functions). However, they can only be used inside [method _draw], its corresponding [method Object._notification] or methods connected to the [signal draw] signal.
+ Canvas items are drawn in tree order. By default, children are on top of their parents, so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis.
+ A [CanvasItem] can be hidden, which will also hide its children. By adjusting various other properties of a [CanvasItem], you can also modulate its color (via [member modulate] or [member self_modulate]), change its Z-index, blend mode, and more.
</description>
<tutorials>
<link title="Viewport and canvas transforms">$DOCS_URL/tutorials/2d/2d_transforms.html</link>
diff --git a/doc/classes/CanvasLayer.xml b/doc/classes/CanvasLayer.xml
index 040877b88e..15e49c018d 100644
--- a/doc/classes/CanvasLayer.xml
+++ b/doc/classes/CanvasLayer.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CanvasLayer" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Canvas drawing layer.
+ A node used for independent rendering of objects within a 2D scene.
</brief_description>
<description>
- Canvas drawing layer. [CanvasItem] nodes that are direct or indirect children of a [CanvasLayer] will be drawn in that layer. The layer is a numeric index that defines the draw order. The default 2D scene renders with index 0, so a [CanvasLayer] with index -1 will be drawn below, and one with index 1 will be drawn above. This is very useful for HUDs (in layer 1+ or above), or backgrounds (in layer -1 or below).
- Embedded [Window]s are placed in layer 1024. CanvasItems in layer 1025 or above appear in front of embedded windows, CanvasItems in layer 1023 or below appear behind embedded windows.
+ [CanvasItem]-derived nodes that are direct or indirect children of a [CanvasLayer] will be drawn in that layer. The layer is a numeric index that defines the draw order. The default 2D scene renders with index [code]0[/code], so a [CanvasLayer] with index [code]-1[/code] will be drawn below, and a [CanvasLayer] with index [code]1[/code] will be drawn above. This order will hold regardless of the [member CanvasItem.z_index] of the nodes within each layer.
+ [CanvasLayer]s can be hidden and they can also optionally follow the viewport. This makes them useful for HUDs like health bar overlays (on layers [code]1[/code] and higher) or backgrounds (on layers [code]-1[/code] and lower).
+ [b]Note:[/b] Embedded [Window]s are placed on layer [code]1024[/code]. [CanvasItem]s on layers [code]1025[/code] and higher appear in front of embedded windows.
</description>
<tutorials>
<link title="Viewport and canvas transforms">$DOCS_URL/tutorials/2d/2d_transforms.html</link>
diff --git a/doc/classes/CanvasModulate.xml b/doc/classes/CanvasModulate.xml
index d0eabe0011..ecebabb1c5 100644
--- a/doc/classes/CanvasModulate.xml
+++ b/doc/classes/CanvasModulate.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CanvasModulate" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Tint the entire canvas.
+ A node that applies a color tint to a canvas.
</brief_description>
<description>
- [CanvasModulate] tints the canvas elements using its assigned [member color].
+ [CanvasModulate] applies a color tint to all nodes on a canvas. Only one can be used to tint a canvas, but [CanvasLayer]s can be used to render things independently.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CapsuleShape2D.xml b/doc/classes/CapsuleShape2D.xml
index bbc2273644..ebc64aaedf 100644
--- a/doc/classes/CapsuleShape2D.xml
+++ b/doc/classes/CapsuleShape2D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CapsuleShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Capsule shape resource for 2D physics.
+ A 2D capsule shape used for physics collision.
</brief_description>
<description>
- 2D capsule shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. In 2D, a capsule is a rectangle shape with half-circles at both ends.
- [b]Performance:[/b] Being a primitive collision shape, [CapsuleShape2D] is fast to check collisions against (though not as fast as [CircleShape2D]).
+ A 2D capsule shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D].
+ [b]Performance:[/b] [CapsuleShape2D] is fast to check collisions against, but it is slower than [RectangleShape2D] and [CircleShape2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CapsuleShape3D.xml b/doc/classes/CapsuleShape3D.xml
index f2e8be1947..6662e20f3a 100644
--- a/doc/classes/CapsuleShape3D.xml
+++ b/doc/classes/CapsuleShape3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CapsuleShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Capsule shape resource for 3D collisions.
+ A 3D capsule shape used for physics collision.
</brief_description>
<description>
- 3D capsule shape to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node. In 3D, a capsule is a cylinder shape with hemispheres at both ends.
- [b]Performance:[/b] Being a primitive collision shape, [CapsuleShape3D] is fast to check collisions against (though not as fast as [SphereShape3D]). [CapsuleShape3D] is cheaper to check collisions against compared to [CylinderShape3D].
+ A 3D capsule shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
+ [b]Performance:[/b] [CapsuleShape3D] is fast to check collisions against. It is faster than [CylinderShape3D], but slower than [SphereShape3D] and [BoxShape3D].
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/CenterContainer.xml b/doc/classes/CenterContainer.xml
index b291e02b3c..c5481d5beb 100644
--- a/doc/classes/CenterContainer.xml
+++ b/doc/classes/CenterContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CenterContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Keeps children controls centered.
+ A container that keeps child controls in its center.
</brief_description>
<description>
- CenterContainer keeps children controls centered. This container keeps all children to their minimum size, in the center.
+ [CenterContainer] is a container that keeps all of its child controls in its center at their minimum size.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<members>
<member name="use_top_left" type="bool" setter="set_use_top_left" getter="is_using_top_left" default="false">
diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml
index c3bca0a585..ddd2521823 100644
--- a/doc/classes/CharacterBody2D.xml
+++ b/doc/classes/CharacterBody2D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CharacterBody2D" inherits="PhysicsBody2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Specialized 2D physics body node for characters moved by script.
+ A 2D physics body specialized for characters moved by script.
</brief_description>
<description>
- Character bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a rigid body, these are the same as a [AnimatableBody2D]. However, they have two main uses:
- [b]Kinematic characters:[/b] Character bodies have an API for moving objects with walls and slopes detection ([method move_and_slide] method), in addition to collision detection (also done with [method PhysicsBody2D.move_and_collide]). This makes them really useful to implement characters that move in specific ways and collide with the world, but don't require advanced physics.
- [b]Kinematic motion:[/b] Character bodies can also be used for kinematic motion (same functionality as [AnimatableBody2D]), which allows them to be moved by code and push other bodies on their path.
+ [CharacterBody2D] is a specialized class for physics bodies that are meant to be user-controlled. They are not affected by physics at all, but they affect other physics bodies in their path. They are mainly used to provide high-level API to move objects with wall and slope detection ([method move_and_slide] method) in addition to the general collision detection provided by [method PhysicsBody2D.move_and_collide]. This makes it useful for highly configurable physics bodies that must move in specific ways and collide with the world, as is often the case with user-controlled characters.
+ For game objects that don't require complex movement or collision detection, such as moving platforms, [AnimatableBody2D] is simpler to configure.
</description>
<tutorials>
<link title="Kinematic character (2D)">$DOCS_URL/tutorials/physics/kinematic_character_2d.html</link>
diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml
index 830c45a45b..0be6f8b705 100644
--- a/doc/classes/CharacterBody3D.xml
+++ b/doc/classes/CharacterBody3D.xml
@@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CharacterBody3D" inherits="PhysicsBody3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Specialized 3D physics body node for characters moved by script.
+ A 3D physics body specialized for characters moved by script.
</brief_description>
<description>
- Character bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a rigid body, these are the same as a [AnimatableBody3D]. However, they have two main uses:
- [i]Kinematic characters:[/i] Character bodies have an API for moving objects with walls and slopes detection ([method move_and_slide] method), in addition to collision detection (also done with [method PhysicsBody3D.move_and_collide]). This makes them really useful to implement characters that move in specific ways and collide with the world, but don't require advanced physics.
- [i]Kinematic motion:[/i] Character bodies can also be used for kinematic motion (same functionality as [AnimatableBody3D]), which allows them to be moved by code and push other bodies on their path.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ [CharacterBody3D] is a specialized class for physics bodies that are meant to be user-controlled. They are not affected by physics at all, but they affect other physics bodies in their path. They are mainly used to provide high-level API to move objects with wall and slope detection ([method move_and_slide] method) in addition to the general collision detection provided by [method PhysicsBody3D.move_and_collide]. This makes it useful for highly configurable physics bodies that must move in specific ways and collide with the world, as is often the case with user-controlled characters.
+ For game objects that don't require complex movement or collision detection, such as moving platforms, [AnimatableBody3D] is simpler to configure.
</description>
<tutorials>
<link title="Kinematic character (2D)">$DOCS_URL/tutorials/physics/kinematic_character_2d.html</link>
diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml
index 699073f9d3..b5d7c8d898 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CheckBox" inherits="Button" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Binary choice user interface widget. See also [CheckButton].
+ A button that represents a binary choice.
</brief_description>
<description>
- A checkbox allows the user to make a binary choice (choosing only one of two possible options). It's similar to [CheckButton] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckBox when toggling it has [b]no[/b] immediate effect on something. For example, it could be used when toggling it will only do something once a confirmation button is pressed.
+ [CheckBox] allows the user to choose one of only two possible options. It's similar to [CheckButton] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use [CheckBox] when toggling it has [b]no[/b] immediate effect on something. For example, it could be used when toggling it will only do something once a confirmation button is pressed.
See also [BaseButton] which contains common properties and methods associated with this node.
- [b]Note:[/b] CheckBox changes its appearance when it's configured as a radio button. See various [code]radio_*[/code] theme properties. To configure CheckBox to act as a radio button, use [member BaseButton.button_group] and [ButtonGroup].
+ When [member BaseButton.button_group] specifies a [ButtonGroup], [CheckBox] changes its appearance to that of a radio button and uses the various [code]radio_*[/code] theme properties.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml
index 55bc8508eb..3f9af48dc9 100644
--- a/doc/classes/CheckButton.xml
+++ b/doc/classes/CheckButton.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CheckButton" inherits="Button" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Checkable button. See also [CheckBox].
+ A button that represents a binary choice.
</brief_description>
<description>
- CheckButton is a toggle button displayed as a check field. It's similar to [CheckBox] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckButton when toggling it has an [b]immediate[/b] effect on something. For example, it could be used if toggling it enables/disables a setting without requiring the user to press a confirmation button.
+ [CheckButton] is a toggle button displayed as a check field. It's similar to [CheckBox] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use [CheckButton] when toggling it has an [b]immediate[/b] effect on something. For example, it can be used when pressing it shows or hides advanced settings, without asking the user to confirm this action.
See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
diff --git a/doc/classes/CircleShape2D.xml b/doc/classes/CircleShape2D.xml
index f6cda0e102..f4dd2dcb27 100644
--- a/doc/classes/CircleShape2D.xml
+++ b/doc/classes/CircleShape2D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CircleShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Circular shape resource for 2D physics.
+ A 2D circle shape used for physics collision.
</brief_description>
<description>
- 2D circular shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. This shape is useful for modeling balls or small characters and its collision detection with everything else is very fast.
- [b]Performance:[/b] Being a primitive collision shape, [CircleShape2D] is the fastest collision shape to check collisions against, as it only requires a distance check with the shape's origin.
+ A 2D circle shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D].
+ [b]Performance:[/b] [CircleShape2D] is fast to check collisions against. It is faster than [RectangleShape2D] and [CapsuleShape2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml
index bfc81841a5..69eee5057d 100644
--- a/doc/classes/ClassDB.xml
+++ b/doc/classes/ClassDB.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ClassDB" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Class information repository.
+ A class information repository.
</brief_description>
<description>
Provides access to metadata stored for every available class.
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index 84e1c80900..67645cefc3 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CodeEdit" inherits="TextEdit" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Multiline text control intended for editing code.
+ A multiline text editor designed for editing code.
</brief_description>
<description>
- CodeEdit is a specialized [TextEdit] designed for editing plain text code files. It contains a bunch of features commonly found in code editors such as line numbers, line folding, code completion, indent management and string / comment management.
- [b]Note:[/b] By default [CodeEdit] always use left-to-right text direction to correctly display source code.
+ CodeEdit is a specialized [TextEdit] designed for editing plain text code files. It has many features commonly found in code editors such as line numbers, line folding, code completion, indent management, and string/comment management.
+ [b]Note:[/b] Regardless of locale, [CodeEdit] will by default always use left-to-right text direction to correctly display source code.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CodeHighlighter.xml b/doc/classes/CodeHighlighter.xml
index db496a00c4..11b00557e9 100644
--- a/doc/classes/CodeHighlighter.xml
+++ b/doc/classes/CodeHighlighter.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CodeHighlighter" inherits="SyntaxHighlighter" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A syntax highlighter for code.
+ A syntax highlighter intended for code.
</brief_description>
<description>
- A syntax highlighter for code.
+ By adjusting various properties of this resource, you can change the colors of strings, comments, numbers, and other text patterns inside a [TextEdit] control.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml
index 37217f84b2..e645d6fb74 100644
--- a/doc/classes/CollisionObject2D.xml
+++ b/doc/classes/CollisionObject2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionObject2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base node for 2D collision objects.
+ Abstract base class for 2D physics objects.
</brief_description>
<description>
- CollisionObject2D is the base class for 2D physics objects. It can hold any number of 2D collision [Shape2D]s. Each shape must be assigned to a [i]shape owner[/i]. The CollisionObject2D can have any number of shape owners. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods.
+ Abstract base class for 2D physics objects. [CollisionObject2D] can hold any number of [Shape2D]s for collision. Each shape must be assigned to a [i]shape owner[/i]. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods.
[b]Note:[/b] Only collisions between objects within the same canvas ([Viewport] canvas or [CanvasLayer]) are supported. The behavior of collisions between objects in different canvases is undefined.
</description>
<tutorials>
diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml
index 5e1cfe74f4..4903784abc 100644
--- a/doc/classes/CollisionObject3D.xml
+++ b/doc/classes/CollisionObject3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionObject3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base node for collision objects.
+ Abstract base class for 3D physics objects.
</brief_description>
<description>
- CollisionObject3D is the base class for physics objects. It can hold any number of collision [Shape3D]s. Each shape must be assigned to a [i]shape owner[/i]. The CollisionObject3D can have any number of shape owners. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ Abstract base class for 3D physics objects. [CollisionObject3D] can hold any number of [Shape3D]s for collision. Each shape must be assigned to a [i]shape owner[/i]. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the [code]shape_owner_*[/code] methods.
+ [b]Warning:[/b] With a non-uniform scale, this node will likely not behave as expected. It is advised to keep its scale the same on all axes and adjust its collision shape(s) instead.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml
index 68c370820e..4ad88d49bc 100644
--- a/doc/classes/CollisionPolygon2D.xml
+++ b/doc/classes/CollisionPolygon2D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionPolygon2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node that represents a 2D collision polygon.
+ A node that provides a polygon shape to a [CollisionObject2D] parent.
</brief_description>
<description>
- Provides a 2D collision polygon to a [CollisionObject2D] parent. Polygons can be drawn in the editor or specified by a list of vertices.
- Depending on the build mode, this node effectively provides several convex shapes (by convex decomposition of the polygon) or a single concave shape made of the polygon's segments.
- In the editor, a [CollisionPolygon2D] can be generated from a [Sprite2D]'s outline by selecting a [Sprite2D] node, going to the [b]Sprite2D[/b] menu at the top of the 2D editor viewport then choosing [b]Create CollisionPolygon2D Sibling[/b].
+ A node that provides a thickened polygon shape (a prism) to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D] or turn [PhysicsBody2D] into a solid object.
+ [b]Warning:[/b] A non-uniformly scaled [CollisionShape3D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CollisionPolygon3D.xml b/doc/classes/CollisionPolygon3D.xml
index b6bf0ce141..382471d0f0 100644
--- a/doc/classes/CollisionPolygon3D.xml
+++ b/doc/classes/CollisionPolygon3D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionPolygon3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node that represents a 3D collision polygon, given by the thickening of a 2D polygon in the local XY plane along the local Z axis.
+ A node that provides a thickened polygon shape (a prism) to a [CollisionObject3D] parent.
</brief_description>
<description>
- Provides a 3D collision polygon to a [CollisionObject3D] parent, by thickening a 2D (convex or concave) polygon in the local XY plane along the local Z axis. The 2D polygon in the local XY plane can be drawn in the editor or specified by a list of vertices. That 2D polygon is thickened evenly in the local Z and -Z directions.
- This node has the same effect as several [ConvexPolygonShape3D] nodes, created by thickening the 2D convex polygons in the convex decomposition of the given 2D polygon (but without the overhead of multiple nodes).
- [b]Warning:[/b] A non-uniformly scaled CollisionPolygon3D node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change its [member polygon]'s vertices instead.
+ A node that provides a thickened polygon shape (a prism) to a [CollisionObject3D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area3D] or turn [PhysicsBody3D] into a solid object.
+ [b]Warning:[/b] A non-uniformly scaled [CollisionShape3D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml
index 895d87929d..d14686a251 100644
--- a/doc/classes/CollisionShape2D.xml
+++ b/doc/classes/CollisionShape2D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionShape2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node that represents collision shape data in 2D space.
+ A node that provides a [Shape2D] to a [CollisionObject2D] parent.
</brief_description>
<description>
- Editor facility for creating and editing collision shapes in 2D space. Set the [member shape] property to configure the shape.
- You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to create a solid object.
+ A node that provides a [Shape2D] to a [CollisionObject2D] parent and allows to edit it. This can give a detection shape to an [Area2D] or turn a [PhysicsBody2D] into a solid object.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/CollisionShape3D.xml b/doc/classes/CollisionShape3D.xml
index f79f9a8803..b5e63b0135 100644
--- a/doc/classes/CollisionShape3D.xml
+++ b/doc/classes/CollisionShape3D.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CollisionShape3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node that represents collision shape data in 3D space.
+ A node that provides a [Shape3D] to a [CollisionObject3D] parent.
</brief_description>
<description>
- Editor facility for creating and editing collision shapes in 3D space. Set the [member shape] property to configure the shape.
- You can use this node to represent all sorts of collision shapes, for example, add this to an [Area3D] to give it a detection shape, or add it to a [PhysicsBody3D] to create a solid object.
- [b]Warning:[/b] A non-uniformly scaled CollisionShape3D node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size of its [member shape] resource instead.
+ A node that provides a [Shape3D] to a [CollisionObject3D] parent and allows to edit it. This can give a detection shape to an [Area3D] or turn a [PhysicsBody3D] into a solid object.
+ [b]Warning:[/b] A non-uniformly scaled [CollisionShape3D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its [member shape] resource instead.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index b73ed59715..f5411750b5 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Color" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Color built-in type, in RGBA format.
+ A color represented in RGBA format.
</brief_description>
<description>
- A color represented in RGBA format by red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) components. Each component is a 16-bit floating-point value, usually ranging from 0 to 1. Some properties (such as [member CanvasItem.modulate]) may support values greater than 1, for overbright or High Dynamic Range colors. If you want to supply values in a range of 0 to 255, you should use [method @GDScript.Color8].
- Colors can also be created by name from a set of standardized colors, through the [String] constructor, [method from_string], or by directly fetching the color constants documented here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url], with the addition of [constant TRANSPARENT].
- [b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it's equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
+ A color represented in RGBA format by a red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) component. Each component is a 16-bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/code]. Some properties (such as [member CanvasItem.modulate]) may support values greater than [code]1.0[/code], for overbright or HDR (High Dynamic Range) colors.
+ Colors can be created in various ways: By the various [Color] constructors, by static methods such as [method from_hsv], and by using a name from the set of standardized colors based on [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url] with the addition of [constant TRANSPARENT]. GDScript also provides [method @GDScript.Color8], which uses integers from [code]0[/code] to [code]255[/code] and doesn't support overbright colors.
+ [b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it is equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url]
</description>
<tutorials>
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index 61a0606f79..fbeae42932 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ColorPicker" inherits="VBoxContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Color picker control.
+ A widget that provides an interface for selecting or modifying a color.
</brief_description>
<description>
- Displays a color picker widget. Useful for selecting a color from an RGB/RGBA colorspace.
- [b]Note:[/b] This control is the color picker widget itself. You can use a [ColorPickerButton] instead if you need a button that brings up a [ColorPicker] in a pop-up.
+ A widget that provides an interface for selecting or modifying a color. It can optionally provide functionalities like a color sampler (eyedropper), color modes, and presets.
+ [b]Note:[/b] This control is the color picker widget itself. You can use a [ColorPickerButton] instead if you need a button that brings up a [ColorPicker] in a popup.
</description>
<tutorials>
<link title="Tween Demo">https://godotengine.org/asset-library/asset/146</link>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index 022d8cd7d0..a725d1a3ee 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ColorPickerButton" inherits="Button" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Button that pops out a [ColorPicker].
+ A button that brings up a [ColorPicker] when pressed.
</brief_description>
<description>
- Encapsulates a [ColorPicker] making it accessible by pressing a button. Pressing the button will toggle the [ColorPicker] visibility.
+ Encapsulates a [ColorPicker], making it accessible by pressing a button. Pressing the button will toggle the [ColorPicker]'s visibility.
See also [BaseButton] which contains common properties and methods associated with this node.
[b]Note:[/b] By default, the button may not be wide enough for the color preview swatch to be visible. Make sure to set [member Control.custom_minimum_size] to a big enough value to give the button enough space.
</description>
diff --git a/doc/classes/ColorRect.xml b/doc/classes/ColorRect.xml
index 0afecfd80f..e179ab07bb 100644
--- a/doc/classes/ColorRect.xml
+++ b/doc/classes/ColorRect.xml
@@ -1,25 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ColorRect" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Colored rectangle.
+ A control that displays a solid color rectangle.
</brief_description>
<description>
- Displays a rectangle filled with a solid [member color]. If you need to display the border alone, consider using [ReferenceRect] instead.
+ Displays a rectangle filled with a solid [member color]. If you need to display the border alone, consider using a [Panel] instead.
</description>
<tutorials>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
</tutorials>
<members>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
- The fill color.
- [codeblocks]
- [gdscript]
- $ColorRect.color = Color(1, 0, 0, 1) # Set ColorRect's color to red.
- [/gdscript]
- [csharp]
- GetNode&lt;ColorRect&gt;("ColorRect").Color = new Color(1, 0, 0, 1); // Set ColorRect's color to red.
- [/csharp]
- [/codeblocks]
+ The fill color of the rectangle.
</member>
</members>
</class>
diff --git a/doc/classes/ConcavePolygonShape2D.xml b/doc/classes/ConcavePolygonShape2D.xml
index 591b73a8c7..817c2891d9 100644
--- a/doc/classes/ConcavePolygonShape2D.xml
+++ b/doc/classes/ConcavePolygonShape2D.xml
@@ -1,16 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConcavePolygonShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Concave polygon shape resource for 2D physics.
+ A 2D polyline shape used for physics collision.
</brief_description>
<description>
- 2D concave polygon shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node.
- The shape consists of a collection of line segments, and as such it does not include any "inside" that the segments might be enclosing. If the segments do enclose anything, then the shape is [i]hollow[/i], as opposed to a [ConvexPolygonShape2D] which is solid. See also [CollisionPolygon2D].
- Being made out of line segments, this shape is the most freely configurable single 2D shape. It can be used to form (hollow) polygons of any nature, convex or concave.
- [b]Note:[/b] When used for collision, [b]ConcavePolygonShape2D[/b] is intended to work with static [PhysicsBody2D] nodes like [StaticBody2D] and is not recommended to use with [RigidBody2D] nodes in a mode other than Static. A [CollisionPolygon2D] in convex decomposition mode (solids) or several convex objects are advised for that instead. Otherwise, a concave polygon 2D shape is better suited for static bodies.
- [b]Warning:[/b] The nature of this shape makes it extra prone to being tunneled through by (small) fast physics bodies. For example, consider a (small) rigid body [i]Ball[/i] traveling toward a static body [i]Box[/i] at high speed. If the box uses a [b]ConcavePolygonShape2D[/b] consisting of four segments, then the ball might end up inside the box or tunnel all the way through the box, if it goes fast enough. This is (partly) because the ball can only collide against the individual segments of the hollow box. In interactions with rigid bodies tunneling can be avoided by enabling continuous collision detection on the rigid body.
- [b]Warning:[/b] Using this shape for an [Area2D] (via a [CollisionShape2D] node) may give unexpected results: the area will only detect collisions with the segments in the [ConcavePolygonShape2D] (and not with any "inside" of the shape, for example).
- [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, using [ConvexPolygonShape2D] will perform better. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape2D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape2D]'s documentation for instructions. However, consider using primitive collision shapes such as [CircleShape2D] or [RectangleShape2D] first.
+ A 2D polyline shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SEGMENTS[/code] mode.
+ Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConvexPolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection.
+ [b]Note:[/b] When used for collision, [ConcavePolygonShape2D] is intended to work with static [CollisionShape2D] nodes like [StaticBody2D] and will likely not behave well for [CharacterBody2D]s or [RigidBody2D]s in a mode other than Static.
+ [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape2D] is hollow, so it won't detect a collision.
+ [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest 2D collision shape to check collisions against. Its use should generally be limited to level geometry. If the polyline is closed, [CollisionPolygon2D]'s [code]BUILD_SOLIDS[/code] mode can be used, which decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s documentation for instructions.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ConcavePolygonShape3D.xml b/doc/classes/ConcavePolygonShape3D.xml
index 8141be7972..a9ac34c04a 100644
--- a/doc/classes/ConcavePolygonShape3D.xml
+++ b/doc/classes/ConcavePolygonShape3D.xml
@@ -1,16 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConcavePolygonShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Concave polygon shape resource (also called "trimesh") for 3D physics.
+ A 3D trimesh shape used for physics collision.
</brief_description>
<description>
- 3D concave polygon shape resource (also called "trimesh") to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node.
- The shape consists of a collection of triangle faces, and as such it does not include any "inside" that the faces might be enclosing. If the faces enclose anything, then the shape is [i]hollow[/i], as opposed to a [ConvexPolygonShape3D] which is solid. See also [CollisionPolygon3D].
- Being made out of triangle faces, this shape is the most freely configurable single 3D shape. Despite its name, it can be used to form (hollow) polyhedra of any nature, convex or concave.
- [b]Note:[/b] When used for collision, [b]ConcavePolygonShape3D[/b] is intended to work with static [PhysicsBody3D] nodes like [StaticBody3D] and will not work with [CharacterBody3D] or [RigidBody3D] in a mode other than Static.
- [b]Warning:[/b] The nature of this shape makes it extra prone to being tunneled through by (small) fast physics bodies. For example, consider a (small) rigid body [i]Ball[/i] traveling toward a static body [i]Box[/i] at high speed. If the box uses a [b]ConcavePolygonShape3D[/b] consisting of twelve triangle faces (two triangle faces for each of the six sides of the box), then the ball might end up inside the box or tunnel all the way through the box, if it goes fast enough. This is (partly) because the ball can only collide against the individual faces of the hollow box. In interactions with rigid bodies tunneling can be avoided by enabling continuous collision detection on the rigid body.
- [b]Warning:[/b] Using this shape for an [Area3D] (via a [CollisionShape3D] node, created e.g. by using the [i]Create Trimesh Collision Sibling[/i] option in the [i]Mesh[/i] menu that appears when selecting a [MeshInstance3D] node) may give unexpected results: the area will only detect collisions with the triangle faces in the [ConcavePolygonShape3D] (and not with any "inside" of the shape, for example); moreover it will only detect all such collisions if [member backface_collision] is [code]true[/code].
- [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, using [ConvexPolygonShape3D] will perform better. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions. However, consider using primitive collision shapes such as [SphereShape3D] or [BoxShape3D] first.
+ A 3D trimesh shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
+ Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConvexPolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection.
+ [b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than Static.
+ [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape3D] is hollow, so it won't detect a collision.
+ [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest 3D collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, [ConvexPolygonShape3D] should be used. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions.
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/ConeTwistJoint3D.xml b/doc/classes/ConeTwistJoint3D.xml
index 39746b3c05..da67ac6df3 100644
--- a/doc/classes/ConeTwistJoint3D.xml
+++ b/doc/classes/ConeTwistJoint3D.xml
@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConeTwistJoint3D" inherits="Joint3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A twist joint between two 3D PhysicsBodies.
+ A physics joint that connects two 3D physics bodies in a way that simulates a ball-and-socket joint.
</brief_description>
<description>
- The joint can rotate the bodies across an axis defined by the local x-axes of the [Joint3D].
- The twist axis is initiated as the X axis of the [Joint3D].
- Once the Bodies swing, the twist axis is calculated as the middle of the x-axes of the Joint3D in the local space of the two Bodies. See also [Generic6DOFJoint3D].
+ A physics joint that connects two 3D physics bodies in a way that simulates a ball-and-socket joint. The twist axis is initiated as the X axis of the [ConeTwistJoint3D]. Once the physics bodies swing, the twist axis is calculated as the middle of the X axes of the joint in the local space of the two physics bodies. Useful for limbs like shoulders and hips, lamps hanging off a ceiling, etc.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ConfirmationDialog.xml b/doc/classes/ConfirmationDialog.xml
index 5f1d731891..631e107448 100644
--- a/doc/classes/ConfirmationDialog.xml
+++ b/doc/classes/ConfirmationDialog.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConfirmationDialog" inherits="AcceptDialog" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Dialog for confirmation of actions.
+ A dialog used for confirmation of actions.
</brief_description>
<description>
- Dialog for confirmation of actions. This dialog inherits from [AcceptDialog], but has by default an OK and Cancel button (in host OS order).
+ A dialog used for confirmation of actions. This window is similar to [AcceptDialog], but pressing its Cancel button can have a different outcome from pressing the OK button. The order of the two buttons varies depending on the host OS.
To get cancel action, you can use:
[codeblocks]
[gdscript]
diff --git a/doc/classes/Container.xml b/doc/classes/Container.xml
index 2c61dfbe95..6d7101ea1b 100644
--- a/doc/classes/Container.xml
+++ b/doc/classes/Container.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Container" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base node for containers.
+ Base class for all GUI containers.
</brief_description>
<description>
- Base node for containers. A [Container] contains other controls and automatically arranges them in a certain way.
- A Control can inherit this to create custom container classes.
+ Base class for all GUI containers. A [Container] automatically arranges its child controls in a certain way. This class can be inherited to make custom container types.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="_get_allowed_size_flags_horizontal" qualifiers="virtual const">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 36074639dc..57321575b9 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Control" inherits="CanvasItem" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- All user interface nodes inherit from Control. A control's anchors and offsets adapt its position and size relative to its parent.
+ Base class for all GUI controls. Adapts its position and size based on its parent control.
</brief_description>
<description>
Base class for all UI-related nodes. [Control] features a bounding rectangle that defines its extents, an anchor position relative to its parent control or the current viewport, and offsets relative to the anchor. The offsets update automatically when the node, any of its parents, or the screen size change.
diff --git a/doc/classes/ConvexPolygonShape2D.xml b/doc/classes/ConvexPolygonShape2D.xml
index 886a62eafa..d131df3d27 100644
--- a/doc/classes/ConvexPolygonShape2D.xml
+++ b/doc/classes/ConvexPolygonShape2D.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConvexPolygonShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Convex polygon shape resource for 2D physics.
+ A 2D convex polygon shape used for physics collision.
</brief_description>
<description>
- 2D convex polygon shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node.
- The shape is a [i]solid[/i] that includes all the points that it encloses, as opposed to [ConcavePolygonShape2D] which is hollow if it encloses anything. See also [CollisionPolygon2D].
- The solid nature of the shape makes it well-suited for both detection and physics; in physics body interactions this allows depenetrating even those shapes which end up (e.g. due to high speed) fully inside the convex shape (similarly to primitive shapes, but unlike [ConcavePolygonShape2D]). The convexity limits the possible geometric shape of a single [ConvexPolygonShape2D]: it cannot be concave.
- [b]Convex decomposition:[/b] Concave objects' collisions can be represented accurately using [i]several[/i] convex shapes. This allows dynamic physics bodies to have complex concave collisions (at a performance cost). It can be achieved using several [ConvexPolygonShape2D] nodes or by using the [CollisionPolygon2D] node in Solids build mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b].
- [b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions against compared to [ConcavePolygonShape2D], but it is slower than primitive collision shapes such as [CircleShape2D] or [RectangleShape2D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
+ A 2D convex polygon shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SOLIDS[/code] mode.
+ [ConvexPolygonShape2D] is [i]solid[/i], which means it detects collisions from objects that are fully inside it, unlike [ConcavePolygonShape2D] which is hollow. This makes it more suitable for both detection and physics.
+ [b]Convex decomposition:[/b] A concave polygon can be split up into several convex polygons. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape3D] nodes or by using the [CollisionPolygon2D] node in [code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b].
+ [b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions against compared to [ConcavePolygonShape2D], but it is slower than primitive collision shapes such as [CircleShape2D] and [RectangleShape2D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ConvexPolygonShape3D.xml b/doc/classes/ConvexPolygonShape3D.xml
index 69c45f9504..126cd2b983 100644
--- a/doc/classes/ConvexPolygonShape3D.xml
+++ b/doc/classes/ConvexPolygonShape3D.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConvexPolygonShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Convex polygon shape resource for 3D physics.
+ A 3D convex polyhedron shape used for physics collision.
</brief_description>
<description>
- 3D convex polygon shape resource to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node.
- The shape is a [i]solid[/i] that includes all the points that it encloses, as opposed to [ConcavePolygonShape3D] which is hollow if it encloses anything. See also [CollisionPolygon3D].
- The solid nature of the shape makes it well-suited for both detection and physics; in physics body interactions this allows depenetrating even those shapes which end up (e.g. due to high speed) fully inside the convex shape (similarly to primitive shapes, but unlike [ConcavePolygonShape3D] and [HeightMapShape3D]). The convexity restricts the possible geometric shape of a single [ConvexPolygonShape3D]: it cannot be concave.
- [b]Convex decomposition:[/b] Concave objects' collisions can be represented accurately using [i]several[/i] convex shapes. This allows dynamic physics bodies to have complex concave collisions (at a performance cost). It can be achieved by using several [ConvexPolygonShape3D] nodes or by using the [CollisionPolygon3D] node. To generate a collision polygon from a mesh, select the [MeshInstance3D] node, go to the [b]Mesh[/b] menu that appears above the viewport and choose [b]Create Multiple Convex Collision Siblings[/b]. Alternatively, [method MeshInstance3D.create_multiple_convex_collisions] can be called in a script to perform this decomposition at run-time.
- [b]Performance:[/b] [ConvexPolygonShape3D] is faster to check collisions against compared to [ConcavePolygonShape3D], but it is slower than primitive collision shapes such as [SphereShape3D] or [BoxShape3D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
+ A 3D convex polyhedron shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
+ [ConvexPolygonShape3D] is [i]solid[/i], which means it detects collisions from objects that are fully inside it, unlike [ConcavePolygonShape3D] which is hollow. This makes it more suitable for both detection and physics.
+ [b]Convex decomposition:[/b] A concave polyhedron can be split up into several convex polyhedra. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape3D] nodes. To generate a convex decomposition from a mesh, select the [MeshInstance3D] node, go to the [b]Mesh[/b] menu that appears above the viewport, and choose [b]Create Multiple Convex Collision Siblings[/b]. Alternatively, [method MeshInstance3D.create_multiple_convex_collisions] can be called in a script to perform this decomposition at run-time.
+ [b]Performance:[/b] [ConvexPolygonShape3D] is faster to check collisions against compared to [ConcavePolygonShape3D], but it is slower than primitive collision shapes such as [SphereShape3D] and [BoxShape3D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml
index d4898055d9..ba410035af 100644
--- a/doc/classes/Crypto.xml
+++ b/doc/classes/Crypto.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Crypto" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Access to advanced cryptographic functionalities.
+ Provides access to advanced cryptographic functionalities.
</brief_description>
<description>
- The Crypto class allows you to access some more advanced cryptographic functionalities in Godot.
- For now, this includes generating cryptographically secure random bytes, RSA keys and self-signed X509 certificates generation, asymmetric key encryption/decryption, and signing/verification.
+ The Crypto class provides access to advanced cryptographic functionalities.
+ Currently, this includes asymmetric key encryption/decryption, signing/verification, and generating cryptographically secure random bytes, RSA keys, HMAC digests, and self-signed [X509Certificate]s.
[codeblocks]
[gdscript]
extends Node
diff --git a/doc/classes/CylinderShape3D.xml b/doc/classes/CylinderShape3D.xml
index 09fffe80c9..1492e09591 100644
--- a/doc/classes/CylinderShape3D.xml
+++ b/doc/classes/CylinderShape3D.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CylinderShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Cylinder shape for 3D collisions.
+ A 3D cylinder shape used for physics collision.
</brief_description>
<description>
- Cylinder shape for collisions. Like [CapsuleShape3D], but without hemispheres at the cylinder's ends.
+ A 2D capsule shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
[b]Note:[/b] There are several known bugs with cylinder collision shapes. Using [CapsuleShape3D] or [BoxShape3D] instead is recommended.
- [b]Performance:[/b] Being a primitive collision shape, [CylinderShape3D] is fast to check collisions against (though not as fast as [SphereShape3D]). [CylinderShape3D] is also more demanding compared to [CapsuleShape3D].
+ [b]Performance:[/b] [CylinderShape3D] is fast to check collisions against, but it is slower than [CapsuleShape3D], [BoxShape3D], and [CylinderShape3D].
</description>
<tutorials>
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
diff --git a/doc/classes/DampedSpringJoint2D.xml b/doc/classes/DampedSpringJoint2D.xml
index 866d901022..11a6e5bd30 100644
--- a/doc/classes/DampedSpringJoint2D.xml
+++ b/doc/classes/DampedSpringJoint2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="DampedSpringJoint2D" inherits="Joint2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Damped spring constraint for 2D physics.
+ A physics joint that connects two 2D physics bodies with a spring-like force.
</brief_description>
<description>
- Damped spring constraint for 2D physics. This resembles a spring joint that always wants to go back to a given length.
+ A physics joint that connects two 2D physics bodies with a spring-like force. This resembles a spring that always wants to stretch to a given length.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index 50aea102f6..5817aecad9 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Dictionary" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Dictionary type.
+ A built-in data structure that holds key-value pairs.
</brief_description>
<description>
- Dictionary type. Associative container, which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding new entries. In other programming languages, this data structure is sometimes referred to as a hash map or associative array.
- You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code].
- [b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a dictionary which can be modified independently of the original dictionary, use [method duplicate].
+ Dictionaries are associative containers that contain values referenced by unique keys. Dictionaries will preserve the insertion order when adding new entries. In other programming languages, this data structure is often referred to as a hash map or an associative array.
+ You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs inside curly braces [code]{}[/code].
Creating a dictionary:
[codeblocks]
[gdscript]
@@ -134,6 +133,7 @@
}
[/csharp]
[/codeblocks]
+ [b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a dictionary which can be modified independently of the original dictionary, use [method duplicate].
[b]Note:[/b] Erasing elements while iterating over dictionaries is [b]not[/b] supported and will result in unpredictable behavior.
</description>
<tutorials>
diff --git a/doc/classes/DirAccess.xml b/doc/classes/DirAccess.xml
index d26b839e64..c98db3bc26 100644
--- a/doc/classes/DirAccess.xml
+++ b/doc/classes/DirAccess.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="DirAccess" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Type used to handle the filesystem.
+ Provides methods for managing directories and their content.
</brief_description>
<description>
- Directory type. It is used to manage directories and their content (not restricted to the project folder).
+ This class is used to manage directories and their content, even outside of the project folder.
[DirAccess] can't be instantiated directly. Instead it is created with a static method that takes a path for which it will be opened.
Most of the methods have a static alternative that can be used without creating a [DirAccess]. Static methods only support absolute paths (including [code]res://[/code] and [code]user://[/code]).
[codeblock]
@@ -173,7 +173,7 @@
<description>
Returns a [PackedStringArray] containing filenames of the directory contents, excluding directories. The array is sorted alphabetically.
Affected by [member include_hidden].
- [b]Note:[/b] When used on a [code]res://[/code] path in an exported project, only the files actually included in the PCK at the given folder level are returned. In practice, this means that since imported resources are stored in a top-level [code].godot/[/code] folder, only paths to [code]*.gd[/code] and [code]*.import[/code] files are returned (plus a few files such as [code]project.godot[/code] or [code]project.binary[code] and the project icon). In an exported project, the list of returned files will also vary depending on whether [member ProjectSettings.editor/export/convert_text_resources_to_binary] is [code]true[/code].
+ [b]Note:[/b] When used on a [code]res://[/code] path in an exported project, only the files actually included in the PCK at the given folder level are returned. In practice, this means that since imported resources are stored in a top-level [code].godot/[/code] folder, only paths to [code]*.gd[/code] and [code]*.import[/code] files are returned (plus a few files such as [code]project.godot[/code] or [code]project.binary[/code] and the project icon). In an exported project, the list of returned files will also vary depending on whether [member ProjectSettings.editor/export/convert_text_resources_to_binary] is [code]true[/code].
</description>
</method>
<method name="get_files_at" qualifiers="static">
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 47a7d2c67d..c7df562304 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="DisplayServer" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Singleton for window management functions.
+ A server interface for low-level window management.
</brief_description>
<description>
- [DisplayServer] handles everything related to window management. This is separated from [OS] as a single operating system may support multiple display servers.
+ [DisplayServer] handles everything related to window management. It is separated from [OS] as a single operating system may support multiple display servers.
[b]Headless mode:[/b] Starting the engine with the [code]--headless[/code] [url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line argument[/url] disables all rendering and window management functions. Most functions from [DisplayServer] will return dummy values in this case.
</description>
<tutorials>
@@ -74,7 +74,7 @@
<param index="3" name="callback" type="Callable" />
<description>
Shows a text input dialog which uses the operating system's native look-and-feel. [param callback] will be called with a [String] argument equal to the text field's contents when the dialog is closed for any reason.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="dialog_show">
@@ -85,7 +85,7 @@
<param index="3" name="callback" type="Callable" />
<description>
Shows a text dialog which uses the operating system's native look-and-feel. [param callback] will be called when the dialog is closed for any reason.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="enable_for_stealing_focus">
@@ -93,7 +93,7 @@
<param index="0" name="process_id" type="int" />
<description>
Allows the [param process_id] PID to steal focus from this window. In other words, this disables the operating system's focus stealing protection for the specified PID.
- [b]Note:[/b] This method is implemented on Windows.
+ [b]Note:[/b] This method is implemented only on Windows.
</description>
</method>
<method name="force_process_and_drop_events">
@@ -198,7 +198,7 @@
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -221,7 +221,7 @@
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -244,7 +244,7 @@
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -268,7 +268,7 @@
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -290,7 +290,7 @@
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -316,7 +316,7 @@
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] By default, there's no indication of the current item state, it should be changed manually.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -339,7 +339,7 @@
An [param accelerator] can optionally be defined, which is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The [param accelerator] is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
[b]Note:[/b] Radio-checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method global_menu_set_item_checked] for more info on how to control it.
[b]Note:[/b] The [param callback] and [param key_callback] Callables need to accept exactly one Variant parameter, the parameter passed to the Callables will be the value passed to [param tag].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -354,7 +354,7 @@
<description>
Adds a separator between items to the global menu with ID [param menu_root]. Separators also occupy an index.
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -371,7 +371,7 @@
<description>
Adds an item that will act as a submenu of the global menu [param menu_root]. The [param submenu] argument is the ID of the global menu root that will be shown when the item is clicked.
Returns index of the inserted item, it's not guaranteed to be the same as [param index] value.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -384,7 +384,7 @@
<param index="0" name="menu_root" type="String" />
<description>
Removes all items from the global menu with ID [param menu_root].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Supported system menu IDs:[/b]
[codeblock]
"_main" - Main menu (macOS).
@@ -398,7 +398,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the accelerator of the item at index [param idx]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_callback" qualifiers="const">
@@ -407,7 +407,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the callback of the item at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_count" qualifiers="const">
@@ -415,7 +415,7 @@
<param index="0" name="menu_root" type="String" />
<description>
Returns number of items in the global menu with ID [param menu_root].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_icon" qualifiers="const">
@@ -424,7 +424,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the icon of the item at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_indentation_level" qualifiers="const">
@@ -433,7 +433,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the horizontal offset of the item at the given [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_tag" qualifiers="const">
@@ -442,7 +442,7 @@
<param index="1" name="tag" type="Variant" />
<description>
Returns the index of the item with the specified [param tag]. Index is automatically assigned to each item by the engine. Index can not be set manually.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_index_from_text" qualifiers="const">
@@ -451,7 +451,7 @@
<param index="1" name="text" type="String" />
<description>
Returns the index of the item with the specified [param text]. Index is automatically assigned to each item by the engine. Index can not be set manually.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_key_callback" qualifiers="const">
@@ -460,7 +460,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the callback of the item accelerator at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_max_states" qualifiers="const">
@@ -469,7 +469,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns number of states of a multistate item. See [method global_menu_add_multistate_item] for details.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_state" qualifiers="const">
@@ -478,7 +478,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the state of a multistate item. See [method global_menu_add_multistate_item] for details.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_submenu" qualifiers="const">
@@ -487,7 +487,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the submenu ID of the item at index [param idx]. See [method global_menu_add_submenu_item] for more info on how to add a submenu.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_tag" qualifiers="const">
@@ -496,7 +496,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the metadata of the specified item, which might be of any type. You can set it with [method global_menu_set_item_tag], which provides a simple way of assigning context data to items.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_text" qualifiers="const">
@@ -505,7 +505,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the text of the item at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_get_item_tooltip" qualifiers="const">
@@ -514,7 +514,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns the tooltip associated with the specified index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_checkable" qualifiers="const">
@@ -523,7 +523,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is checkable in some way, i.e. if it has a checkbox or radio button.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_checked" qualifiers="const">
@@ -532,7 +532,7 @@
<param index="1" name="idx" type="int" />
<description>
Returns [code]true[/code] if the item at index [param idx] is checked.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_disabled" qualifiers="const">
@@ -542,7 +542,7 @@
<description>
Returns [code]true[/code] if the item at index [param idx] is disabled. When it is disabled it can't be selected, or its action invoked.
See [method global_menu_set_item_disabled] for more info on how to disable an item.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_is_item_radio_checkable" qualifiers="const">
@@ -552,7 +552,7 @@
<description>
Returns [code]true[/code] if the item at index [param idx] has radio button-style checkability.
[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/unchecking items in radio groups.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_remove_item">
@@ -562,7 +562,7 @@
<description>
Removes the item at index [param idx] from the global menu [param menu_root].
[b]Note:[/b] The indices of items after the removed item will be shifted by one.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_accelerator">
@@ -572,7 +572,7 @@
<param index="2" name="keycode" type="int" enum="Key" />
<description>
Sets the accelerator of the item at index [param idx]. [param keycode] can be a single [enum Key], or a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]).
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_callback">
@@ -583,7 +583,7 @@
<description>
Sets the callback of the item at index [param idx]. Callback is emitted when an item is pressed.
[b]Note:[/b] The [param callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_checkable">
@@ -593,7 +593,7 @@
<param index="2" name="checkable" type="bool" />
<description>
Sets whether the item at index [param idx] has a checkbox. If [code]false[/code], sets the type of the item to plain text.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_checked">
@@ -603,7 +603,7 @@
<param index="2" name="checked" type="bool" />
<description>
Sets the checkstate status of the item at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_disabled">
@@ -613,7 +613,7 @@
<param index="2" name="disabled" type="bool" />
<description>
Enables/disables the item at index [param idx]. When it is disabled, it can't be selected and its action can't be invoked.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_icon">
@@ -623,7 +623,7 @@
<param index="2" name="icon" type="Texture2D" />
<description>
Replaces the [Texture2D] icon of the specified [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
[b]Note:[/b] This method is not supported by macOS "_dock" menu items.
</description>
</method>
@@ -634,7 +634,7 @@
<param index="2" name="level" type="int" />
<description>
Sets the horizontal offset of the item at the given [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_key_callback">
@@ -645,7 +645,7 @@
<description>
Sets the callback of the item at index [param idx]. Callback is emitted when its accelerator is activated.
[b]Note:[/b] The [param key_callback] Callable needs to accept exactly one Variant parameter, the parameter passed to the Callable will be the value passed to the [code]tag[/code] parameter when the menu item was created.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_max_states">
@@ -655,7 +655,7 @@
<param index="2" name="max_states" type="int" />
<description>
Sets number of state of a multistate item. See [method global_menu_add_multistate_item] for details.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_radio_checkable">
@@ -666,7 +666,7 @@
<description>
Sets the type of the item at the specified index [param idx] to radio button. If [code]false[/code], sets the type of the item to plain text.
[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/unchecking items in radio groups.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_state">
@@ -676,7 +676,7 @@
<param index="2" name="state" type="int" />
<description>
Sets the state of a multistate item. See [method global_menu_add_multistate_item] for details.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_submenu">
@@ -686,7 +686,7 @@
<param index="2" name="submenu" type="String" />
<description>
Sets the submenu of the item at index [param idx]. The submenu is the ID of a global menu root that would be shown when the item is clicked.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_tag">
@@ -696,7 +696,7 @@
<param index="2" name="tag" type="Variant" />
<description>
Sets the metadata of an item, which may be of any type. You can later get it with [method global_menu_get_item_tag], which provides a simple way of assigning context data to items.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_text">
@@ -706,7 +706,7 @@
<param index="2" name="text" type="String" />
<description>
Sets the text of the item at index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="global_menu_set_item_tooltip">
@@ -716,7 +716,7 @@
<param index="2" name="tooltip" type="String" />
<description>
Sets the [String] tooltip of the item at the specified index [param idx].
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="has_feature" qualifiers="const">
@@ -730,14 +730,14 @@
<return type="Vector2i" />
<description>
Returns the text selection in the [url=https://en.wikipedia.org/wiki/Input_method]Input Method Editor[/url] composition string, with the [Vector2i]'s [code]x[/code] component being the caret position and [code]y[/code] being the length of the selection.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="ime_get_text" qualifiers="const">
<return type="String" />
<description>
Returns the composition string contained within the [url=https://en.wikipedia.org/wiki/Input_method]Input Method Editor[/url] window.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="is_dark_mode" qualifiers="const">
@@ -869,7 +869,7 @@
<description>
Returns the greatest scale factor of all screens.
[b]Note:[/b] On macOS returned value is [code]2.0[/code] if there is at least one hiDPI (Retina) screen in the system, and [code]1.0[/code] in all other cases.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="screen_get_orientation" qualifiers="const">
@@ -925,7 +925,7 @@
<description>
Returns the scale factor of the specified screen by index.
[b]Note:[/b] On macOS returned value is [code]2.0[/code] for hiDPI (Retina) screen, and [code]1.0[/code] for all other cases.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="screen_get_size" qualifiers="const">
@@ -981,14 +981,14 @@
<return type="String" />
<description>
Returns current active tablet driver name.
- [b]Note:[/b] This method is implemented on Windows.
+ [b]Note:[/b] This method is implemented only on Windows.
</description>
</method>
<method name="tablet_get_driver_count" qualifiers="const">
<return type="int" />
<description>
Returns the total number of available tablet drivers.
- [b]Note:[/b] This method is implemented on Windows.
+ [b]Note:[/b] This method is implemented only on Windows.
</description>
</method>
<method name="tablet_get_driver_name" qualifiers="const">
@@ -996,7 +996,7 @@
<param index="0" name="idx" type="int" />
<description>
Returns the tablet driver name for the given index.
- [b]Note:[/b] This method is implemented on Windows.
+ [b]Note:[/b] This method is implemented only on Windows.
</description>
</method>
<method name="tablet_set_current_driver">
@@ -1004,7 +1004,7 @@
<param index="0" name="name" type="String" />
<description>
Set active tablet driver name.
- [b]Note:[/b] This method is implemented on Windows.
+ [b]Note:[/b] This method is implemented only on Windows.
</description>
</method>
<method name="tts_get_voices" qualifiers="const">
@@ -1160,7 +1160,7 @@
<return type="int" />
<param index="0" name="window_id" type="int" default="0" />
<description>
- Returns the [method Object.get_instance_id] of the [Window] the [param window_id] is attached to. also [method window_get_attached_instance_id].
+ Returns the [method Object.get_instance_id] of the [Window] the [param window_id] is attached to.
</description>
</method>
<method name="window_get_current_screen" qualifiers="const">
@@ -1268,14 +1268,14 @@
<return type="bool" />
<description>
Returns [code]true[/code], if double-click on a window title should maximize it.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="window_minimize_on_title_dbl_click" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code], if double-click on a window title should minimize it.
- [b]Note:[/b] This method is implemented on macOS.
+ [b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
<method name="window_move_to_foreground">
@@ -1503,7 +1503,7 @@
<param index="1" name="window_id" type="int" default="0" />
<description>
When [constant WINDOW_FLAG_EXTEND_TO_TITLE] flag is set, set offset to the center of the first titlebar button.
- [b]Note:[/b] This flag is implemented on macOS.
+ [b]Note:[/b] This flag is implemented only on macOS.
</description>
</method>
<method name="window_set_window_event_callback">
@@ -1666,7 +1666,7 @@
I-beam cursor shape. This is used by default when hovering a control that accepts text input, such as [LineEdit] or [TextEdit].
</constant>
<constant name="CURSOR_POINTING_HAND" value="2" enum="CursorShape">
- Pointing hand cursor shape. This is used by default when hovering a [LinkButton] or an URL tag in a [RichTextLabel].
+ Pointing hand cursor shape. This is used by default when hovering a [LinkButton] or a URL tag in a [RichTextLabel].
</constant>
<constant name="CURSOR_CROSS" value="3" enum="CursorShape">
Crosshair cursor. This is intended to be displayed when the user needs precise aim over an element, such as a rectangle selection tool or a color picker.
@@ -1759,7 +1759,7 @@
Window content is expanded to the full size of the window. Unlike borderless window, the frame is left intact and can be used to resize the window, title bar is transparent, but have minimize/maximize/close buttons.
Use [method window_set_window_buttons_offset] to adjust minimize/maximize/close buttons offset.
Use [method window_get_safe_title_margins] to determine area under the title bar that is not covered by decorations.
- [b]Note:[/b] This flag is implemented on macOS.
+ [b]Note:[/b] This flag is implemented only on macOS.
</constant>
<constant name="WINDOW_FLAG_MOUSE_PASSTHROUGH" value="7" enum="WindowFlags">
All mouse events are passed to the underlying window of the same application.
@@ -1784,15 +1784,15 @@
</constant>
<constant name="WINDOW_EVENT_GO_BACK_REQUEST" value="5" enum="WindowEvent">
Sent when the device "Back" button is pressed, see [method window_set_window_event_callback].
- [b]Note:[/b] This event is implemented on Android.
+ [b]Note:[/b] This event is implemented only on Android.
</constant>
<constant name="WINDOW_EVENT_DPI_CHANGE" value="6" enum="WindowEvent">
Sent when the window is moved to the display with different DPI, or display DPI is changed, see [method window_set_window_event_callback].
- [b]Note:[/b] This flag is implemented on macOS.
+ [b]Note:[/b] This flag is implemented only on macOS.
</constant>
<constant name="WINDOW_EVENT_TITLEBAR_CHANGE" value="7" enum="WindowEvent">
Sent when the window title bar decoration is changed (e.g. [constant WINDOW_FLAG_EXTEND_TO_TITLE] is set or window entered/exited full screen mode), see [method window_set_window_event_callback].
- [b]Note:[/b] This flag is implemented on macOS.
+ [b]Note:[/b] This flag is implemented only 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]).
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
index 3912e9fe26..1585b28be0 100644
--- a/doc/classes/EditorFileDialog.xml
+++ b/doc/classes/EditorFileDialog.xml
@@ -4,7 +4,7 @@
A modified version of [FileDialog] used by the editor.
</brief_description>
<description>
- [EditorFileDialog] is an enhanced version of [FileDialog] available only to editor plugins. Additional features include list of favorited/recent files and ability to see files as thumbnails grid instead of list.
+ [EditorFileDialog] is an enhanced version of [FileDialog] available only to editor plugins. Additional features include list of favorited/recent files and the ability to see files as thumbnails grid instead of list.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 3ad28f9062..418548a95f 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -4,7 +4,7 @@
Godot editor's interface.
</brief_description>
<description>
- EditorInterface gives you control over Godot editor's window. It allows customizing the window, saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects, and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], [ScriptEditor], the editor viewport, and information about scenes.
+ [EditorInterface] gives you control over Godot editor's window. It allows customizing the window, saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects, and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], [ScriptEditor], the editor viewport, and information about scenes.
[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorPlugin.get_editor_interface].
</description>
<tutorials>
diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml
index 2ddbdfdf86..55d1a38c3e 100644
--- a/doc/classes/EditorNode3DGizmoPlugin.xml
+++ b/doc/classes/EditorNode3DGizmoPlugin.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorNode3DGizmoPlugin" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Used by the editor to define Node3D gizmo types.
+ A class used by the editor to define Node3D gizmo types.
</brief_description>
<description>
[EditorNode3DGizmoPlugin] allows you to define a new type of Gizmo. There are two main ways to do so: extending [EditorNode3DGizmoPlugin] for the simpler gizmos, or creating a new [EditorNode3DGizmo] type. See the tutorial in the documentation for more info.
diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml
index a89eb7b9c8..3e9d98f67a 100644
--- a/doc/classes/EditorProperty.xml
+++ b/doc/classes/EditorProperty.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorProperty" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Custom control to edit properties for adding into the inspector.
+ Custom control for editing properties that can be added to the [EditorInspector].
</brief_description>
<description>
- This control allows property editing for one or multiple properties into [EditorInspector]. It is added via [EditorInspectorPlugin].
+ A custom control for editing properties that can be added to the [EditorInspector]. It is added via [EditorInspectorPlugin].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml
index e01dbfbb3b..b85629912e 100644
--- a/doc/classes/EditorResourcePreview.xml
+++ b/doc/classes/EditorResourcePreview.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorResourcePreview" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Helper to generate previews of resources or files.
+ A node used to generate previews of resources or files.
</brief_description>
<description>
- This object is used to generate previews for resources of files.
+ This node is used to generate previews for resources of files.
[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_previewer].
</description>
<tutorials>
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 6a27bff763..2f28a6df87 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -739,11 +739,8 @@
<member name="text_editor/appearance/gutters/line_numbers_zero_padded" type="bool" setter="" getter="">
If [code]true[/code], displays line numbers with zero padding (e.g. [code]007[/code] instead of [code]7[/code]).
</member>
- <member name="text_editor/appearance/gutters/show_bookmark_gutter" type="bool" setter="" getter="">
- If [code]true[/code], displays icons for bookmarks in a gutter at the left. Bookmarks remain functional when this setting is disabled.
- </member>
<member name="text_editor/appearance/gutters/show_info_gutter" type="bool" setter="" getter="">
- If [code]true[/code], displays a gutter at the left containing icons for methods with signal connections.
+ If [code]true[/code], displays a gutter at the left containing icons for methods with signal connections and for overridden methods.
</member>
<member name="text_editor/appearance/gutters/show_line_numbers" type="bool" setter="" getter="">
If [code]true[/code], displays line numbers in a gutter at the left.
diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml
index 2b05ba24fc..3d8ba0118e 100644
--- a/doc/classes/EditorSyntaxHighlighter.xml
+++ b/doc/classes/EditorSyntaxHighlighter.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSyntaxHighlighter" inherits="SyntaxHighlighter" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base Syntax highlighter resource for the [ScriptEditor].
+ Base class for [SyntaxHighlighter] used by the [ScriptEditor].
</brief_description>
<description>
- Base syntax highlighter resource all editor syntax highlighters extend from, it is used in the [ScriptEditor].
+ Base class that all [SyntaxHighlighter]s used by the [ScriptEditor] extend from.
Add a syntax highlighter to an individual script by calling [method ScriptEditorBase.add_syntax_highlighter]. To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter]
</description>
<tutorials>
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index aa15f88afa..c695c3348e 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Engine" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Access to engine properties.
+ Provides access to engine properties.
</brief_description>
<description>
The [Engine] singleton allows you to query and modify the project's run-time parameters, such as frames per second, time scale, and others.
diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml
index 11dbb00f10..d70caab839 100644
--- a/doc/classes/FileAccess.xml
+++ b/doc/classes/FileAccess.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FileAccess" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Type to handle file reading and writing operations.
+ Provides methods for file reading and writing operations.
</brief_description>
<description>
- File type. This is used to permanently store data into the user device's file system and to read from it. This can be used to store game save data or player configuration files, for example.
+ This class can be used to permanently store data in the user device's file system and to read from it. This is useful for store game save data or player configuration files.
Here's a sample on how to write and read from a file:
[codeblocks]
[gdscript]
@@ -33,7 +33,7 @@
[/csharp]
[/codeblocks]
In the example above, the file will be saved in the user data folder as specified in the [url=$DOCS_URL/tutorials/io/data_paths.html]Data paths[/url] documentation.
- [FileAccess] will close when it's freed, which happens when it goes out of scope or when it gets assigned with [code]null[/code]. In C# the reference must be disposed after we are done using it, this can be done with the [code]using[/code] statement or calling the [code]Dispose[/code] method directly.
+ [FileAccess] will close when it's freed, which happens when it goes out of scope or when it gets assigned with [code]null[/code]. In C# the reference must be disposed manually, which can be done with the [code]using[/code] statement or by calling the [code]Dispose[/code] method directly.
[codeblocks]
[gdscript]
var file = FileAccess.open("res://something") # File is opened and locked for use.
@@ -44,7 +44,7 @@
// The using statement calls Dispose when going out of scope.
[/csharp]
[/codeblocks]
- [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of the [FileAccess] API, as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package.
+ [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of [FileAccess], as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package.
[b]Note:[/b] Files are automatically closed only if the process exits "normally" (such as by clicking the window manager's close button or pressing [b]Alt + F4[/b]). If you stop the project execution by pressing [b]F8[/b] while the project is running, the file won't be closed as the game process will be killed. You can work around this by calling [method flush] at regular intervals.
</description>
<tutorials>
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index f09040cc76..fe448d381a 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FileDialog" inherits="ConfirmationDialog" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Dialog for selecting files or directories in the filesystem.
+ A dialog for selecting files or directories in the filesystem.
</brief_description>
<description>
- FileDialog is a preset dialog used to choose files and directories in the filesystem. It supports filter masks. The FileDialog automatically sets its window title according to the [member file_mode]. If you want to use a custom title, disable this by setting [member mode_overrides_title] to [code]false[/code].
+ [FileDialog] is a preset dialog used to choose files and directories in the filesystem. It supports filter masks. [FileDialog] automatically sets its window title according to the [member file_mode]. If you want to use a custom title, disable this by setting [member mode_overrides_title] to [code]false[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/FileSystemDock.xml b/doc/classes/FileSystemDock.xml
index 82a216d713..512fa431f9 100644
--- a/doc/classes/FileSystemDock.xml
+++ b/doc/classes/FileSystemDock.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FileSystemDock" inherits="VBoxContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Editor dock for managing files in the project.
+ Godot editor's dock for managing files in the project.
</brief_description>
<description>
This class is available only in [EditorPlugin]s and can't be instantiated. You can access it using [method EditorInterface.get_file_system_dock].
- While FileSystemDock doesn't expose any methods for file manipulation, you can listen for various file-related signals.
+ While [FileSystemDock] doesn't expose any methods for file manipulation, it can listen for various file-related signals.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/FlowContainer.xml b/doc/classes/FlowContainer.xml
index 0b8ce662f1..9636a0fbc7 100644
--- a/doc/classes/FlowContainer.xml
+++ b/doc/classes/FlowContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FlowContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for flow containers.
+ A container that arranges its child controls horizontally or vertically and wraps them around at the borders.
</brief_description>
<description>
- Arranges child [Control] nodes vertically or horizontally in a left-to-right or top-to-bottom flow.
- A line is filled with [Control] nodes until no more fit on the same line, similar to text in an autowrapped label.
+ A container that arranges its child controls horizontally or vertically and wraps them around at the borders. This is similar to how text in a book wraps around when no more words can fit on a line.
</description>
<tutorials>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="get_line_count" qualifiers="const">
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index fc4c4b4b5d..57c31bebb5 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Font" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for fonts and font variations.
+ Abstract base class for fonts and font variations.
</brief_description>
<description>
- Font is the abstract base class for font, so it shouldn't be used directly. Other types of fonts inherit from it.
+ Abstract base class for different font types. It has methods for drawing text and font character introspection.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml
index 4993d0dc42..1430f79614 100644
--- a/doc/classes/FontFile.xml
+++ b/doc/classes/FontFile.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FontFile" inherits="Font" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Font source data and prerendered glyph cache, imported from dynamic or bitmap font.
+ Holds font source data and prerendered glyph cache, imported from a dynamic or a bitmap font.
</brief_description>
<description>
[FontFile] contains a set of glyphs to represent Unicode characters imported from a font file, as well as a cache of rasterized glyphs, and a set of fallback [Font]s to use.
@@ -12,8 +12,8 @@
- Bitmap font importer: AngelCode BMFont (.fnt, .font), text and binary (version 3) format variants.
- Monospace image font importer: All supported image formats.
[b]Note:[/b] A character is a symbol that represents an item (letter, digit etc.) in an abstract way.
- [b]Note:[/b] A glyph is a bitmap or shape used to draw one or more characters in a context-dependent manner. Glyph indices are bound to the specific font data source.
- [b]Note:[/b] If a none of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code.
+ [b]Note:[/b] A glyph is a bitmap or a shape used to draw one or more characters in a context-dependent manner. Glyph indices are bound to the specific font data source.
+ [b]Note:[/b] If none of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code.
[codeblocks]
[gdscript]
var f = load("res://BarlowCondensed-Bold.ttf")
diff --git a/doc/classes/FontVariation.xml b/doc/classes/FontVariation.xml
index 9bc0e0424b..ede341e71f 100644
--- a/doc/classes/FontVariation.xml
+++ b/doc/classes/FontVariation.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FontVariation" inherits="Font" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Variation of the [Font].
+ A variation of a font with additional settings.
</brief_description>
<description>
- OpenType variations, simulated bold / slant, and additional font settings like OpenType features and extra spacing.
+ Provides OpenType variations, simulated bold / slant, and additional font settings like OpenType features and extra spacing.
To use simulated bold font variant:
[codeblocks]
[gdscript]
diff --git a/doc/classes/Generic6DOFJoint3D.xml b/doc/classes/Generic6DOFJoint3D.xml
index 4b2f6fd32c..aac9a82467 100644
--- a/doc/classes/Generic6DOFJoint3D.xml
+++ b/doc/classes/Generic6DOFJoint3D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Generic6DOFJoint3D" inherits="Joint3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- The generic 6-degrees-of-freedom joint can implement a variety of joint types by locking certain axes' rotation or translation.
+ A physics joint that allows for complex movement and rotation between two 3D physics bodies.
</brief_description>
<description>
- The first 3 DOF axes are linear axes, which represent translation of Bodies, and the latter 3 DOF axes represent the angular motion. Each axis can be either locked, or limited.
+ The [Generic6DOFJoint3D] (6 Degrees Of Freedom) joint allows for implementing custom types of joints by locking the rotation and translation of certain axes.
+ The first 3 DOF represent the linear motion of the physics bodies and the last 3 DOF represent the angular motion of the physics bodies. Each axis can be either locked, or limited.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml
index a0be997221..1db7142855 100644
--- a/doc/classes/Geometry2D.xml
+++ b/doc/classes/Geometry2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Geometry2D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Helper node to calculate generic geometry operations in 2D space.
+ Provides methods for some common 2D geometric operations.
</brief_description>
<description>
- Geometry2D provides users with a set of helper functions to create geometric shapes, compute intersections between shapes, and process various other geometric operations.
+ Provides a set of helper functions to create geometric shapes, compute intersections between shapes, and process various other geometric operations in 2D.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Geometry3D.xml b/doc/classes/Geometry3D.xml
index b2fb4251bb..2f068b9fa5 100644
--- a/doc/classes/Geometry3D.xml
+++ b/doc/classes/Geometry3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Geometry3D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Helper node to calculate generic geometry operations in 3D space.
+ Provides methods for some common 3D geometric operations.
</brief_description>
<description>
- Geometry3D provides users with a set of helper functions to create geometric shapes, compute intersections between shapes, and process various other geometric operations.
+ Provides a set of helper functions to create geometric shapes, compute intersections between shapes, and process various other geometric operations in 3D.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Gradient.xml b/doc/classes/Gradient.xml
index aa941f9fd3..f76ccb49ac 100644
--- a/doc/classes/Gradient.xml
+++ b/doc/classes/Gradient.xml
@@ -80,8 +80,12 @@
<member name="colors" type="PackedColorArray" setter="set_colors" getter="get_colors" default="PackedColorArray(0, 0, 0, 1, 1, 1, 1, 1)">
Gradient's colors returned as a [PackedColorArray].
</member>
+ <member name="interpolation_color_space" type="int" setter="set_interpolation_color_space" getter="get_interpolation_color_space" enum="Gradient.ColorSpace" default="0">
+ The color space used to interpolate between points of the gradient. It does not affect the returned colors, which will always be in sRGB space. See [enum ColorSpace] for available modes.
+ [b]Note:[/b] This setting has no effect when [member interpolation_mode] is set to [constant GRADIENT_INTERPOLATE_CONSTANT].
+ </member>
<member name="interpolation_mode" type="int" setter="set_interpolation_mode" getter="get_interpolation_mode" enum="Gradient.InterpolationMode" default="0">
- Defines how the colors between points of the gradient are interpolated. See [enum InterpolationMode] for available modes.
+ The algorithm used to interpolate between points of the gradient. See [enum InterpolationMode] for available modes.
</member>
<member name="offsets" type="PackedFloat32Array" setter="set_offsets" getter="get_offsets" default="PackedFloat32Array(0, 1)">
Gradient's offsets returned as a [PackedFloat32Array].
@@ -97,5 +101,14 @@
<constant name="GRADIENT_INTERPOLATE_CUBIC" value="2" enum="InterpolationMode">
Cubic interpolation.
</constant>
+ <constant name="GRADIENT_COLOR_SPACE_SRGB" value="0" enum="ColorSpace">
+ sRGB color space.
+ </constant>
+ <constant name="GRADIENT_COLOR_SPACE_LINEAR_SRGB" value="1" enum="ColorSpace">
+ Linear sRGB color space.
+ </constant>
+ <constant name="GRADIENT_COLOR_SPACE_OKLAB" value="2" enum="ColorSpace">
+ [url=https://bottosson.github.io/posts/oklab/]Oklab[/url] color space. This color space provides a smooth and uniform-looking transition between colors.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/GradientTexture2D.xml b/doc/classes/GradientTexture2D.xml
index 2d425035ca..9522de3528 100644
--- a/doc/classes/GradientTexture2D.xml
+++ b/doc/classes/GradientTexture2D.xml
@@ -42,6 +42,9 @@
<constant name="FILL_RADIAL" value="1" enum="Fill">
The colors are linearly interpolated in a circular pattern.
</constant>
+ <constant name="FILL_SQUARE" value="2" enum="Fill">
+ The colors are linearly interpolated in a square pattern.
+ </constant>
<constant name="REPEAT_NONE" value="0" enum="Repeat">
The gradient fill is restricted to the range defined by [member fill_from] to [member fill_to] offsets.
</constant>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 31b352cfed..19ee396de1 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GraphEdit" inherits="Control" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- GraphEdit is a control responsible for displaying and manipulating graph-like data using [GraphNode]s. It provides access to creation, removal, connection, and disconnection of nodes.
+ An editor for graph-like structures, using [GraphNode]s.
</brief_description>
<description>
- [b]Note:[/b] Please be aware that this node will undergo extensive refactoring in a future 4.x version involving compatibility-breaking API changes.
- GraphEdit provides tools for creation, manipulation, and display of various graphs. Its main purpose in the engine is to power the visual programming systems, such as visual shaders, but it is also available for use in user projects.
- GraphEdit by itself is only an empty container, representing an infinite grid where [GraphNode]s can be placed. Each [GraphNode] represent a node in the graph, a single unit of data in the connected scheme. GraphEdit, in turn, helps to control various interactions with nodes and between nodes. When the user attempts to connect, disconnect, or close a [GraphNode], a signal is emitted in the GraphEdit, but no action is taken by default. It is the responsibility of the programmer utilizing this control to implement the necessary logic to determine how each request should be handled.
+ [GraphEdit] provides tools for creation, manipulation, and display of various graphs. Its main purpose in the engine is to power the visual programming systems, such as visual shaders, but it is also available for use in user projects.
+ [GraphEdit] by itself is only an empty container, representing an infinite grid where [GraphNode]s can be placed. Each [GraphNode] represents a node in the graph, a single unit of data in the connected scheme. [GraphEdit], in turn, helps to control various interactions with nodes and between nodes. When the user attempts to connect, disconnect, or close a [GraphNode], a signal is emitted in the [GraphEdit], but no action is taken by default. It is the responsibility of the programmer utilizing this control to implement the necessary logic to determine how each request should be handled.
[b]Performance:[/b] It is greatly advised to enable low-processor usage mode (see [member OS.low_processor_usage_mode]) when using GraphEdits.
</description>
<tutorials>
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index 6e0ffe8225..5b3e377cbb 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GraphNode" inherits="Container" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- GraphNode is a [Container] control that represents a single data unit in a [GraphEdit] graph. You can customize the number, type, and color of left- and right-side connection ports.
+ A container with connection ports, representing a node in a [GraphEdit].
</brief_description>
<description>
- [b]Note:[/b] Please be aware that this node will undergo extensive refactoring in a future 4.x version involving compatibility-breaking API changes.
- GraphNode allows to create nodes for a [GraphEdit] graph with customizable content based on its child [Control]s. GraphNode is a [Container] and is responsible for placing its children on screen. This works similar to [VBoxContainer]. Children, in turn, provide GraphNode with so-called slots, each of which can have a connection port on either side. This is similar to how [TabContainer] uses children to create the tabs.
- Each GraphNode slot is defined by its index and can provide the node with up to two ports: one on the left, and one on the right. By convention the left port is also referred to as the input port and the right port is referred to as the output port. Each port can be enabled and configured individually, using different type and color. The type is an arbitrary value that you can define using your own considerations. The parent [GraphEdit] will receive this information on each connect and disconnect request.
+ [GraphNode] allows to create nodes for a [GraphEdit] graph with customizable content based on its child controls. [GraphNode] is derived from [Container] and it is responsible for placing its children on screen. This works similar to [VBoxContainer]. Children, in turn, provide [GraphNode] with so-called slots, each of which can have a connection port on either side.
+ Each [GraphNode] slot is defined by its index and can provide the node with up to two ports: one on the left, and one on the right. By convention the left port is also referred to as the [b]input port[/b] and the right port is referred to as the [b]output port[/b]. Each port can be enabled and configured individually, using different type and color. The type is an arbitrary value that you can define using your own considerations. The parent [GraphEdit] will receive this information on each connect and disconnect request.
Slots can be configured in the Inspector dock once you add at least one child [Control]. The properties are grouped by each slot's index in the "Slot" section.
- [b]Note:[/b] While GraphNode is set up using slots and slot indices, connections are made between the ports which are enabled. Because of that [GraphEdit] uses port's index and not slot's index. You can use [method get_connection_input_slot] and [method get_connection_output_slot] to get the slot index from the port index.
+ [b]Note:[/b] While GraphNode is set up using slots and slot indices, connections are made between the ports which are enabled. Because of that, [GraphEdit] uses the port's index and not the slot's index. You can use [method get_connection_input_slot] and [method get_connection_output_slot] to get the slot index from the port index.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml
index c73fcf31aa..8446f5ca60 100644
--- a/doc/classes/GridContainer.xml
+++ b/doc/classes/GridContainer.xml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GridContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Grid container used to arrange Control-derived children in a grid like layout.
+ A container that arranges its child controls in a grid layout.
</brief_description>
<description>
- GridContainer will arrange its Control-derived children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns. For example, if the container has 5 children, and 2 columns, there will be 3 rows in the container.
- Notice that grid layout will preserve the columns and rows for every size of the container, and that empty columns will be expanded automatically.
- [b]Note:[/b] GridContainer only works with child nodes inheriting from Control. It won't rearrange child nodes inheriting from Node2D.
+ [GridContainer] arranges its child controls in a grid layout. The number of columns is specified by the [member columns] property, whereas the number of rows depends on how many are needed for the child controls. The number of rows and columns is preserved for every size of the container.
+ [b]Note:[/b] [GridContainer] only works with child nodes inheriting from [Control]. It won't rearrange child nodes inheriting from [Node2D].
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
<link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link>
</tutorials>
<members>
diff --git a/doc/classes/GrooveJoint2D.xml b/doc/classes/GrooveJoint2D.xml
index ad1a6f6437..abb3f86ed8 100644
--- a/doc/classes/GrooveJoint2D.xml
+++ b/doc/classes/GrooveJoint2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GrooveJoint2D" inherits="Joint2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Groove constraint for 2D physics.
+ A physics joint that restricts the movement of two 2D physics bodies to a fixed axis.
</brief_description>
<description>
- Groove constraint for 2D physics. This is useful for making a body "slide" through a segment placed in another.
+ A physics joint that restricts the movement of two 2D physics bodies to a fixed axis. For example, a [StaticBody2D] representing a piston base can be attached to a [RigidBody2D] representing the piston head, moving up and down.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HBoxContainer.xml b/doc/classes/HBoxContainer.xml
index 7268ef5004..5217b0e4e2 100644
--- a/doc/classes/HBoxContainer.xml
+++ b/doc/classes/HBoxContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HBoxContainer" inherits="BoxContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal box container.
+ A container that arranges its child controls horizontally.
</brief_description>
<description>
- Horizontal box container. See [BoxContainer].
+ A variant of [BoxContainer] that can only arrange its child controls horizontally. Child controls are rearranged automatically when their minimum size changes.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="separation" data_type="constant" type="int" default="4">
diff --git a/doc/classes/HFlowContainer.xml b/doc/classes/HFlowContainer.xml
index 8ed9608437..c0c99cb11f 100644
--- a/doc/classes/HFlowContainer.xml
+++ b/doc/classes/HFlowContainer.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HFlowContainer" inherits="FlowContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal flow container.
+ A container that arranges its child controls horizontally and wraps them around at the borders.
</brief_description>
<description>
- Horizontal version of [FlowContainer].
+ A variant of [FlowContainer] that can only arrange its child controls horizontally, wrapping them around at the borders. This is similar to how text in a book wraps around when no more words can fit on a line.
</description>
<tutorials>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="h_separation" data_type="constant" type="int" default="4">
diff --git a/doc/classes/HScrollBar.xml b/doc/classes/HScrollBar.xml
index 34b495bd86..320a6f608e 100644
--- a/doc/classes/HScrollBar.xml
+++ b/doc/classes/HScrollBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HScrollBar" inherits="ScrollBar" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal scroll bar.
+ A horizontal scrollbar that goes from left (min) to right (max).
</brief_description>
<description>
- Horizontal version of [ScrollBar], which goes from left (min) to right (max).
+ A horizontal scrollbar, typically used to navigate through content that extends beyond the visible width of a control. It is a [Range]-based control and goes from left (min) to right (max).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HSeparator.xml b/doc/classes/HSeparator.xml
index 9ff7c840c3..492145679c 100644
--- a/doc/classes/HSeparator.xml
+++ b/doc/classes/HSeparator.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HSeparator" inherits="Separator" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal separator.
+ A horizontal line used for separating other controls.
</brief_description>
<description>
- Horizontal separator. See [Separator]. Even though it looks horizontal, it is used to separate objects vertically.
+ A horizontal separator used for separating other controls that are arranged [b]vertically[/b]. [HSeparator] is purely visual and normally drawn as a [StyleBoxLine].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml
index 2ab66a2e75..14060721af 100644
--- a/doc/classes/HSlider.xml
+++ b/doc/classes/HSlider.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HSlider" inherits="Slider" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal slider.
+ A horizontal slider that goes from left (min) to right (max).
</brief_description>
<description>
- Horizontal slider. See [Slider]. This one goes from left (min) to right (max).
- [b]Note:[/b] The [signal Range.changed] and [signal Range.value_changed] signals are part of the [Range] class which this class inherits from.
+ A horizontal slider, used to adjust a value by moving a grabber along a horizontal axis. It is a [Range]-based control and goes from left (min) to right (max).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HSplitContainer.xml b/doc/classes/HSplitContainer.xml
index 311c9243c7..86661867d7 100644
--- a/doc/classes/HSplitContainer.xml
+++ b/doc/classes/HSplitContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HSplitContainer" inherits="SplitContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Horizontal split container.
+ A container that splits two child controls horizontally and provides a grabber for adjusting the split ratio.
</brief_description>
<description>
- Horizontal split container. See [SplitContainer]. This goes from left to right.
+ A container that accepts only two child controls, then arranges them horizontally and creates a divisor between them. The divisor can be dragged around to change the size relation between the child controls.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="autohide" data_type="constant" type="int" default="1">
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index 5852a06ea7..e1644f1b21 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -8,7 +8,7 @@
See the [HTTPRequest] node for a higher-level alternative.
[b]Note:[/b] This client only needs to connect to a host once (see [method connect_to_host]) to send multiple requests. Because of this, methods that take URLs usually take just the part after the host instead of the full URL, as the client is already connected to a host. See [method request] for a full example and to get started.
A [HTTPClient] should be reused between multiple requests or to connect to different hosts instead of creating one client per request. Supports Transport Layer Security (TLS), including server certificate verification. HTTP status codes in the 2xx range indicate success, 3xx redirection (i.e. "try again, but over here"), 4xx something was wrong with the request, and 5xx something went wrong on the server's side.
- For more information on HTTP, see https://developer.mozilla.org/en-US/docs/Web/HTTP (or read RFC 2616 to get it straight from the source: https://tools.ietf.org/html/rfc2616).
+ For more information on HTTP, see [url=https://developer.mozilla.org/en-US/docs/Web/HTTP]MDN's documentation on HTTP[/url] (or read [url=https://tools.ietf.org/html/rfc2616]RFC 2616[/url] to get it straight from the source).
[b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android.
[b]Note:[/b] It's recommended to use transport encryption (TLS) and to avoid sending sensitive information (such as login credentials) in HTTP GET URL parameters. Consider using HTTP POST requests or HTTP headers for such information instead.
[b]Note:[/b] When performing HTTP requests from a project exported to Web, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header.
diff --git a/doc/classes/HashingContext.xml b/doc/classes/HashingContext.xml
index 14c3d14ae1..e5af3ad4b4 100644
--- a/doc/classes/HashingContext.xml
+++ b/doc/classes/HashingContext.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HashingContext" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Context to compute cryptographic hashes over multiple iterations.
+ Provides functionality for computing cryptographic hashes chunk by chunk.
</brief_description>
<description>
- The HashingContext class provides an interface for computing cryptographic hashes over multiple iterations. This is useful for example when computing hashes of big files (so you don't have to load them all in memory), network streams, and data streams in general (so you don't have to hold buffers).
+ The HashingContext class provides an interface for computing cryptographic hashes over multiple iterations. Useful for computing hashes of big files (so you don't have to load them all in memory), network streams, and data streams in general (so you don't have to hold buffers).
The [enum HashType] enum shows the supported hashing algorithms.
[codeblocks]
[gdscript]
diff --git a/doc/classes/HeightMapShape3D.xml b/doc/classes/HeightMapShape3D.xml
index c257e1bdfc..e490fc1d71 100644
--- a/doc/classes/HeightMapShape3D.xml
+++ b/doc/classes/HeightMapShape3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HeightMapShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Height map shape resource for 3D physics.
+ A 3D height map shape used for physics collision.
</brief_description>
<description>
- Height map shape resource, which can be added to a [PhysicsBody3D] or [Area3D]. Heightmap collision is typically used for colliding with terrains. However, since heightmaps cannot store overhangs, collisions with other structures (such as buildings) must be done with other collision shapes such as [ConcavePolygonShape3D]. If needed, "holes" can be created in an [HeightMapShape3D] by assigning very low points (like [code]-100000[/code]) in the desired area.
- [b]Performance:[/b] [HeightMapShape3D] is faster to check collisions against compared to [ConcavePolygonShape3D], but it is slower than primitive collision shapes such as [SphereShape3D] or [BoxShape3D].
+ A 3D heightmap shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. This is useful for terrain, but it is limited as overhangs (such as caves) cannot be stored. Holes in a [HeightMapShape3D] are created by assigning very low values to points in the desired area.
+ [b]Performance:[/b] [HeightMapShape3D] is faster to check collisions against than [ConcavePolygonShape3D], but it is significantly slower than primitive shapes like [BoxShape3D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HingeJoint3D.xml b/doc/classes/HingeJoint3D.xml
index 56b0ae95ee..bd123217a7 100644
--- a/doc/classes/HingeJoint3D.xml
+++ b/doc/classes/HingeJoint3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HingeJoint3D" inherits="Joint3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A hinge between two 3D PhysicsBodies.
+ A physics joint that restricts the rotation of a 3D physics body around an axis relative to another physics body.
</brief_description>
<description>
- A HingeJoint3D normally uses the Z axis of body A as the hinge axis, another axis can be specified when adding it manually though. See also [Generic6DOFJoint3D].
+ A physics joint that restricts the rotation of a 3D physics body around an axis relative to another physics body. For example, Body A can be a [StaticBody3D] representing a door hinge that a [RigidBody3D] rotates around.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 5250b7a323..98edcf6c42 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Input" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A singleton that deals with inputs.
+ A singleton for handling inputs.
</brief_description>
<description>
- A singleton that deals with inputs. This includes key presses, mouse buttons and movement, joypads, and input actions. Actions and their events can be set in the [b]Input Map[/b] tab in the [b]Project &gt; Project Settings[/b], or with the [InputMap] class.
- [b]Note:[/b] The methods here reflect the global input state and are not affected by [method Control.accept_event] or [method Viewport.set_input_as_handled], which only deal with the way input is propagated in the [SceneTree].
+ The [Input] singleton handles key presses, mouse buttons and movement, gamepads, and input actions. Actions and their events can be set in the [b]Input Map[/b] tab in [b]Project &gt; Project Settings[/b], or with the [InputMap] class.
+ [b]Note:[/b] [Input]'s methods reflect the global input state and are not affected by [method Control.accept_event] or [method Viewport.set_input_as_handled], as those methods only deal with the way input is propagated in the [SceneTree].
</description>
<tutorials>
<link title="Inputs documentation index">$DOCS_URL/tutorials/inputs/index.html</link>
diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml
index 5d2dc8942f..f389cd9add 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEvent" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Generic input event.
+ Abstract base class for input events.
</brief_description>
<description>
- Base class of all sort of input event. See [method Node._input].
+ Abstract base class of all types of input events. See [method Node._input].
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
<link title="Viewport and canvas transforms">$DOCS_URL/tutorials/2d/2d_transforms.html</link>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
diff --git a/doc/classes/InputEventAction.xml b/doc/classes/InputEventAction.xml
index fc4d57e059..5a684763c0 100644
--- a/doc/classes/InputEventAction.xml
+++ b/doc/classes/InputEventAction.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventAction" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for actions.
+ An input event type for actions.
</brief_description>
<description>
- Contains a generic action which can be targeted from several types of inputs. Actions can be created from the [b]Input Map[/b] tab in the [b]Project &gt; Project Settings[/b] menu. See [method Node._input].
+ Contains a generic action which can be targeted from several types of inputs. Actions and their events can be set in the [b]Input Map[/b] tab in [b]Project &gt; Project Settings[/b], or with the [InputMap] class.
[b]Note:[/b] Unlike the other [InputEvent] subclasses which map to unique physical events, this virtual one is not emitted by the engine. This class is useful to emit actions manually with [method Input.parse_input_event], which are then received in [method Node._input]. To check if a physical event matches an action from the Input Map, use [method InputEvent.is_action] and [method InputEvent.is_action_pressed].
</description>
<tutorials>
- <link title="InputEvent: Actions">$DOCS_URL/tutorials/inputs/inputevent.html#actions</link>
+ <link title="Using InputEvent: Actions">$DOCS_URL/tutorials/inputs/inputevent.html#actions</link>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
</tutorials>
diff --git a/doc/classes/InputEventFromWindow.xml b/doc/classes/InputEventFromWindow.xml
index 03813be76f..58204ef3fb 100644
--- a/doc/classes/InputEventFromWindow.xml
+++ b/doc/classes/InputEventFromWindow.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventFromWindow" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for [Viewport]-based input events.
+ Abstract base class for [Viewport]-based input events.
</brief_description>
<description>
InputEventFromWindow represents events specifically received by windows. This includes mouse events, keyboard events in focused windows or touch screen actions.
diff --git a/doc/classes/InputEventGesture.xml b/doc/classes/InputEventGesture.xml
index af3954c743..5979d5fbea 100644
--- a/doc/classes/InputEventGesture.xml
+++ b/doc/classes/InputEventGesture.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventGesture" inherits="InputEventWithModifiers" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for touch control gestures.
+ Abstract base class for touch gestures.
</brief_description>
<description>
- InputEventGesture is sent when a user performs a supported gesture on a touch screen. Gestures can't be emulated using mouse, because they typically require multi-touch.
+ InputEventGestures are sent when a user performs a supported gesture on a touch screen. Gestures can't be emulated using mouse, because they typically require multi-touch.
</description>
<tutorials>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="position" type="Vector2" setter="set_position" getter="get_position" default="Vector2(0, 0)">
diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml
index dff1b20ef2..095cc1c363 100644
--- a/doc/classes/InputEventJoypadButton.xml
+++ b/doc/classes/InputEventJoypadButton.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventJoypadButton" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event for gamepad buttons.
+ Represents a gamepad button being pressed or released.
</brief_description>
<description>
Input event type for gamepad buttons. For gamepad analog sticks and joysticks, see [InputEventJoypadMotion].
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="button_index" type="int" setter="set_button_index" getter="get_button_index" enum="JoyButton" default="0">
diff --git a/doc/classes/InputEventJoypadMotion.xml b/doc/classes/InputEventJoypadMotion.xml
index 32fe01dda1..6254860bc4 100644
--- a/doc/classes/InputEventJoypadMotion.xml
+++ b/doc/classes/InputEventJoypadMotion.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventJoypadMotion" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for gamepad joysticks and other motions. For buttons, see [code]InputEventJoypadButton[/code].
+ Represents axis motions (such as joystick or analog triggers) from a gamepad.
</brief_description>
<description>
- Stores information about joystick motions. One [InputEventJoypadMotion] represents one axis at a time.
+ Stores information about joystick motions. One [InputEventJoypadMotion] represents one axis at a time. For gamepad buttons, see [InputEventJoypadButton].
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="axis" type="int" setter="set_axis" getter="get_axis" enum="JoyAxis" default="0">
diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml
index 1c623eaead..06e1c737db 100644
--- a/doc/classes/InputEventKey.xml
+++ b/doc/classes/InputEventKey.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventKey" inherits="InputEventWithModifiers" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for keyboard events.
+ Represents a key on a keyboard being pressed or released.
</brief_description>
<description>
- Stores key presses on the keyboard. Supports key presses, key releases and [member echo] events.
+ An input event for keys on a keyboard. Supports key presses, key releases and [member echo] events. It can also be received in [method Node._unhandled_key_input].
[b]Note:[/b] Events received from the keyboard usually have all properties set. Event mappings should have only one of the [member keycode], [member physical_keycode] or [member unicode] set.
- When events are compared, properties are checked in the following priority - [member keycode], [member physical_keycode] and [member unicode], events with the first matching value will be considered equal.
+ When events are compared, properties are checked in the following priority - [member keycode], [member physical_keycode] and [member unicode]. Events with the first matching value will be considered equal.
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
<method name="as_text_key_label" qualifiers="const">
diff --git a/doc/classes/InputEventMIDI.xml b/doc/classes/InputEventMIDI.xml
index 02d7ed201e..078edf1d34 100644
--- a/doc/classes/InputEventMIDI.xml
+++ b/doc/classes/InputEventMIDI.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventMIDI" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event for MIDI inputs.
+ Represents an input event from a MIDI device, such as a piano.
</brief_description>
<description>
- InputEventMIDI allows receiving input events from MIDI devices such as a piano. MIDI stands for Musical Instrument Digital Interface.
+ InputEventMIDI allows receiving input events from MIDI (Musical Instrument Digital Interface) devices such as a piano.
MIDI signals can be sent over a 5-pin MIDI connector or over USB, if your device supports both be sure to check the settings in the device to see which output it's using.
To receive input events from MIDI devices, you need to call [method OS.open_midi_inputs]. You can check which devices are detected using [method OS.get_connected_midi_inputs].
[codeblocks]
diff --git a/doc/classes/InputEventMagnifyGesture.xml b/doc/classes/InputEventMagnifyGesture.xml
index fa53617418..cae975bc79 100644
--- a/doc/classes/InputEventMagnifyGesture.xml
+++ b/doc/classes/InputEventMagnifyGesture.xml
@@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventMagnifyGesture" inherits="InputEventGesture" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- [InputEvent] that represents a magnifying touch gesture.
+ Represents a magnifying touch gesture.
</brief_description>
<description>
- Magnify gesture is performed when the user pinches the touch screen. It's typically used for zooming.
+ Stores the factor of a magnifying touch gesture. This is usually performed when the user pinches the touch screen and used for zooming in/out.
</description>
<tutorials>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="factor" type="float" setter="set_factor" getter="get_factor" default="1.0">
- The amount (or delta) of the event. This value is higher the faster the gesture is performed.
+ The amount (or delta) of the event. This value is closer to [code]1.0[/code] the slower the gesture is performed.
</member>
</members>
</class>
diff --git a/doc/classes/InputEventMouse.xml b/doc/classes/InputEventMouse.xml
index 50d4df4842..0f3794a1f6 100644
--- a/doc/classes/InputEventMouse.xml
+++ b/doc/classes/InputEventMouse.xml
@@ -4,10 +4,10 @@
Base input event type for mouse events.
</brief_description>
<description>
- Stores general mouse events information.
+ Stores general information about mouse events.
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" default="0">
diff --git a/doc/classes/InputEventMouseButton.xml b/doc/classes/InputEventMouseButton.xml
index 500244f209..2ec00191b6 100644
--- a/doc/classes/InputEventMouseButton.xml
+++ b/doc/classes/InputEventMouseButton.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventMouseButton" inherits="InputEventMouse" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for mouse button events.
+ Represents a mouse button being pressed or released.
</brief_description>
<description>
- Contains mouse click information. See [method Node._input].
+ Stores information about mouse click events. See [method Node._input].
</description>
<tutorials>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
<link title="Mouse and input coordinates">$DOCS_URL/tutorials/inputs/mouse_and_input_coordinates.html</link>
</tutorials>
<members>
diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml
index 37e7515154..84751d4999 100644
--- a/doc/classes/InputEventMouseMotion.xml
+++ b/doc/classes/InputEventMouseMotion.xml
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventMouseMotion" inherits="InputEventMouse" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for mouse motion events.
+ Represents a mouse or a pen movement.
</brief_description>
<description>
- Contains mouse and pen motion information. Supports relative, absolute positions and velocity. See [method Node._input].
+ Stores information about a mouse or a pen motion. This includes relative position, absolute position, and velocity. See [method Node._input].
[b]Note:[/b] By default, this event is only emitted once per frame rendered at most. If you need more precise input reporting, set [member Input.use_accumulated_input] to [code]false[/code] to make events emitted as often as possible. If you use InputEventMouseMotion to draw lines, consider implementing [url=https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to avoid visible gaps in lines if the user is moving the mouse quickly.
</description>
<tutorials>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
<link title="Mouse and input coordinates">$DOCS_URL/tutorials/inputs/mouse_and_input_coordinates.html</link>
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
</tutorials>
diff --git a/doc/classes/InputEventPanGesture.xml b/doc/classes/InputEventPanGesture.xml
index 0ee74f1328..71ef37a472 100644
--- a/doc/classes/InputEventPanGesture.xml
+++ b/doc/classes/InputEventPanGesture.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventPanGesture" inherits="InputEventGesture" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- [InputEvent] that represents a panning touch gesture.
+ Represents a panning touch gesture.
</brief_description>
<description>
- Pan gesture is performed when the user swipes the touch screen with two fingers. It's typically used for panning/scrolling.
+ Stores information about pan gestures. A pan gesture is performed when the user swipes the touch screen with two fingers. It's typically used for panning/scrolling.
</description>
<tutorials>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="delta" type="Vector2" setter="set_delta" getter="get_delta" default="Vector2(0, 0)">
diff --git a/doc/classes/InputEventScreenDrag.xml b/doc/classes/InputEventScreenDrag.xml
index 73eea77416..0e0ed53cba 100644
--- a/doc/classes/InputEventScreenDrag.xml
+++ b/doc/classes/InputEventScreenDrag.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventScreenDrag" inherits="InputEventFromWindow" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for screen drag events. Only available on mobile devices.
+ Represents a screen drag event.
</brief_description>
<description>
- Contains screen drag information. See [method Node._input].
+ Stores information about screen drag events. See [method Node._input].
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="index" type="int" setter="set_index" getter="get_index" default="0">
diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml
index 2f993d151c..a9264f3953 100644
--- a/doc/classes/InputEventScreenTouch.xml
+++ b/doc/classes/InputEventScreenTouch.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventScreenTouch" inherits="InputEventFromWindow" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Input event type for screen touch events.
- (only available on mobile devices)
+ Represents a screen touch event.
</brief_description>
<description>
- Stores multi-touch press/release information. Supports touch press, touch release and [member index] for multi-touch count and order.
+ Stores information about multi-touch press/release input events. Supports touch press, touch release and [member index] for multi-touch count and order.
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
<member name="canceled" type="bool" setter="set_canceled" getter="is_canceled" default="false">
diff --git a/doc/classes/InputEventShortcut.xml b/doc/classes/InputEventShortcut.xml
index 6d7d7609b9..120c9d8703 100644
--- a/doc/classes/InputEventShortcut.xml
+++ b/doc/classes/InputEventShortcut.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventShortcut" inherits="InputEvent" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- [InputEvent] that signifies a triggered keyboard [Shortcut].
+ Represents a triggered keyboard [Shortcut].
</brief_description>
<description>
- InputEventShortcut is a special event that can be received in [method Node._unhandled_key_input]. It's typically sent by the editor's Command Palette to trigger actions, but can also be sent manually using [method Viewport.push_unhandled_input].
+ InputEventShortcut is a special event that can be received in [method Node._unhandled_key_input]. It is typically sent by the editor's Command Palette to trigger actions, but can also be sent manually using [method Viewport.push_unhandled_input].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml
index 614c6e9326..9ba0d5d641 100644
--- a/doc/classes/InputEventWithModifiers.xml
+++ b/doc/classes/InputEventWithModifiers.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputEventWithModifiers" inherits="InputEventFromWindow" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for keys events with modifiers.
+ Abstract base class for input events affected by modifier keys like [kbd]Shift[/kbd] and [kbd]Alt[/kbd].
</brief_description>
<description>
- Contains keys events information with modifiers support like [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See [method Node._input].
+ Stores information about mouse, keyboard, and touch gesture input events. This includes information about which modifier keys are pressed, such as [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See [method Node._input].
</description>
<tutorials>
- <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
+ <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
<method name="get_modifiers_mask" qualifiers="const">
diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml
index b5c7cd66a2..e08ba3f640 100644
--- a/doc/classes/InputMap.xml
+++ b/doc/classes/InputMap.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="InputMap" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Singleton that manages [InputEventAction].
+ A singleton that manages all [InputEventAction]s.
</brief_description>
<description>
Manages all [InputEventAction] which can be created/modified from the project settings menu [b]Project &gt; Project Settings &gt; Input Map[/b] or in code with [method add_action] and [method action_add_event]. See [method Node._input].
</description>
<tutorials>
- <link title="InputEvent: InputMap">$DOCS_URL/tutorials/inputs/inputevent.html#inputmap</link>
+ <link title="Using InputEvent: InputMap">$DOCS_URL/tutorials/inputs/inputevent.html#inputmap</link>
</tutorials>
<methods>
<method name="action_add_event">
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index 4aca92776f..5b5cd6618b 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ItemList" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control that provides a list of selectable items (and/or icons) in a single column, or optionally in multiple columns.
+ A vertical list of selectable items with one or multiple columns.
</brief_description>
<description>
- This control provides a selectable list of items that may be in a single (or multiple columns) with option of text, icons, or both text and icon. Tooltips are supported and may be different for every item in the list.
+ This control provides a vertical list of selectable items that may be in a single or in multiple columns, with each item having options for text and an icon. Tooltips are supported and may be different for every item in the list.
Selectable items in the list may be selected or deselected and multiple selection may be enabled. Selection with right mouse button may also be enabled to allow use of popup context menus. Items may also be "activated" by double-clicking them or by pressing [kbd]Enter[/kbd].
- Item text only supports single-line strings, newline characters (e.g. [code]\n[/code]) in the string won't produce a newline. Text wrapping is enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to fully fit its content by default. You need to set [member fixed_column_width] greater than zero to wrap the text.
- All [code]set_*[/code] methods allow negative item index, which makes the item accessed from the last one.
+ Item text only supports single-line strings. Newline characters (e.g. [code]\n[/code]) in the string won't produce a newline. Text wrapping is enabled in [constant ICON_MODE_TOP] mode, but the column's width is adjusted to fully fit its content by default. You need to set [member fixed_column_width] greater than zero to wrap the text.
+ All [code]set_*[/code] methods allow negative item indices, i.e. [code]-1[/code] to access the last item, [code]-2[/code] to select the second-to-last item, and so on.
[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports searching within the list while the control is focused. Press a key that matches the first letter of an item's name to select the first item starting with the given letter. After that point, there are two ways to perform incremental search: 1) Press the same key again before the timeout duration to select the next item starting with the same letter. 2) Press letter keys that match the rest of the word before the timeout duration to match to select the item in question directly. Both of these actions will be reset to the beginning of the list if the timeout duration has passed since the last keystroke was registered. You can adjust the timeout duration by changing [member ProjectSettings.gui/timers/incremental_search_max_interval_msec].
</description>
<tutorials>
diff --git a/doc/classes/Joint2D.xml b/doc/classes/Joint2D.xml
index b215aa275b..57a36535c5 100644
--- a/doc/classes/Joint2D.xml
+++ b/doc/classes/Joint2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Joint2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base node for all joint constraints in 2D physics.
+ Abstract base class for all 2D physics joints.
</brief_description>
<description>
- Base node for all joint constraints in 2D physics. Joints take 2 bodies and apply a custom constraint.
+ Abstract base class for all joints in 2D physics. 2D joints bind together two physics bodies and apply a constraint.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Joint3D.xml b/doc/classes/Joint3D.xml
index ca77597d53..e8f07ccf72 100644
--- a/doc/classes/Joint3D.xml
+++ b/doc/classes/Joint3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Joint3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all 3D joints.
+ Abstract base class for all 3D physics joints.
</brief_description>
<description>
- Joints are used to bind together two physics bodies. They have a solver priority and can define if the bodies of the two attached nodes should be able to collide with each other. See also [Generic6DOFJoint3D].
+ Abstract base class for all joints in 3D physics. 3D joints bind together two physics bodies and apply a constraint.
</description>
<tutorials>
<link title="3D Truck Town Demo">https://godotengine.org/asset-library/asset/524</link>
diff --git a/doc/classes/KinematicCollision2D.xml b/doc/classes/KinematicCollision2D.xml
index 8e67ec9a06..127e2fb2ce 100644
--- a/doc/classes/KinematicCollision2D.xml
+++ b/doc/classes/KinematicCollision2D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="KinematicCollision2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Collision data for [method PhysicsBody2D.move_and_collide] collisions.
+ Holds collision data from the movement of a [PhysicsBody2D].
</brief_description>
<description>
- Contains collision data for [method PhysicsBody2D.move_and_collide] collisions. When a [PhysicsBody2D] is moved using [method PhysicsBody2D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision2D] object is returned.
- This object contains information about the collision, including the colliding object, the remaining motion, and the collision position. This information can be used to calculate a collision response.
+ Holds collision data from the movement of a [PhysicsBody2D], usually from [method PhysicsBody2D.move_and_collide]. When a [PhysicsBody2D] is moved, it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision2D] object is returned.
+ The collision data includes the colliding object, the remaining motion, and the collision position. This data can be used to determine a custom response to the collision.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/KinematicCollision3D.xml b/doc/classes/KinematicCollision3D.xml
index b28725dcd3..41e6e01822 100644
--- a/doc/classes/KinematicCollision3D.xml
+++ b/doc/classes/KinematicCollision3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="KinematicCollision3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Collision data for [method PhysicsBody3D.move_and_collide] collisions.
+ Holds collision data from the movement of a [PhysicsBody3D].
</brief_description>
<description>
- Contains collision data for [method PhysicsBody3D.move_and_collide] collisions. When a [PhysicsBody3D] is moved using [method PhysicsBody3D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision3D] object is returned.
- This object contains information about the collision, including the colliding object, the remaining motion, and the collision position. This information can be used to calculate a collision response.
+ Holds collision data from the movement of a [PhysicsBody3D], usually from [method PhysicsBody3D.move_and_collide]. When a [PhysicsBody3D] is moved, it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision3D] object is returned.
+ The collision data includes the colliding object, the remaining motion, and the collision position. This data can be used to determine a custom response to the collision.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index 6a26da9f4f..cb77102ee2 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Label" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Displays plain text in a line or wrapped inside a rectangle. For formatted text, use [RichTextLabel].
+ A control for displaying plain text.
</brief_description>
<description>
- Label displays plain text on the screen. It gives you control over the horizontal and vertical alignment and can wrap the text inside the node's bounding rectangle. It doesn't support bold, italics, or other formatting. For that, use [RichTextLabel] instead.
- [b]Note:[/b] Contrarily to most other [Control]s, Label's [member Control.mouse_filter] defaults to [constant Control.MOUSE_FILTER_IGNORE] (i.e. it doesn't react to mouse input events). This implies that a label won't display any configured [member Control.tooltip_text], unless you change its mouse filter.
+ A control for displaying plain text. It gives you control over the horizontal and vertical alignment and can wrap the text inside the node's bounding rectangle. It doesn't support bold, italics, or other rich text formatting. For that, use [RichTextLabel] instead.
</description>
<tutorials>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml
index 7499074dc9..7b2f054703 100644
--- a/doc/classes/Label3D.xml
+++ b/doc/classes/Label3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Label3D" inherits="GeometryInstance3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Displays plain text in a 3D world.
+ A node for displaying plain text in 3D space.
</brief_description>
<description>
- Label3D displays plain text in a 3D world. It gives you control over the horizontal and vertical alignment.
+ A node for displaying plain text in 3D space. By adjusting various properties of this node, you can configure things such as the text's appearance and whether it always faces the camera.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml
index fd2c8162e4..2ea9332e9c 100644
--- a/doc/classes/LabelSettings.xml
+++ b/doc/classes/LabelSettings.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="LabelSettings" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Collection of common settings to customize label text.
+ Provides common settings to customize the text in a [Label].
</brief_description>
<description>
- [LabelSettings] is a resource that can be assigned to a [Label] node to customize it. It will take priority over the properties defined in theme. The resource can be shared between multiple labels and swapped on the fly, so it's convenient and flexible way to setup text style.
+ [LabelSettings] is a resource that provides common settings to customize the text in a [Label]. It will take priority over the properties defined in [member Control.theme]. The resource can be shared between multiple labels and changed on the fly, so it's convenient and flexible way to setup text style.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index d040c51bb0..d098956c4e 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="LineEdit" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control that provides single-line string editing.
+ An input field for single-line text.
</brief_description>
<description>
- LineEdit provides a single-line string editor, used for text fields.
- It features many built-in shortcuts which will always be available ([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):
+ [LineEdit] provides an input field for editing a single line of text. It features many built-in shortcuts that are always available ([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):
- [kbd]Ctrl + C[/kbd]: Copy
- [kbd]Ctrl + X[/kbd]: Cut
- [kbd]Ctrl + V[/kbd] or [kbd]Ctrl + Y[/kbd]: Paste/"yank"
@@ -17,14 +16,14 @@
- [kbd]Ctrl + A[/kbd]: Select all text
- [kbd]Up Arrow[/kbd]/[kbd]Down Arrow[/kbd]: Move the caret to the beginning/end of the line
On macOS, some extra keyboard shortcuts are available:
- - [kbd]Ctrl + F[/kbd]: Same as [kbd]Right Arrow[/kbd], move the caret one character right
- - [kbd]Ctrl + B[/kbd]: Same as [kbd]Left Arrow[/kbd], move the caret one character left
- - [kbd]Ctrl + P[/kbd]: Same as [kbd]Up Arrow[/kbd], move the caret to the previous line
- - [kbd]Ctrl + N[/kbd]: Same as [kbd]Down Arrow[/kbd], move the caret to the next line
- - [kbd]Ctrl + D[/kbd]: Same as [kbd]Delete[/kbd], delete the character on the right side of caret
- - [kbd]Ctrl + H[/kbd]: Same as [kbd]Backspace[/kbd], delete the character on the left side of the caret
- - [kbd]Ctrl + A[/kbd]: Same as [kbd]Home[/kbd], move the caret to the beginning of the line
- - [kbd]Ctrl + E[/kbd]: Same as [kbd]End[/kbd], move the caret to the end of the line
+ - [kbd]Cmd + F[/kbd]: Same as [kbd]Right Arrow[/kbd], move the caret one character right
+ - [kbd]Cmd + B[/kbd]: Same as [kbd]Left Arrow[/kbd], move the caret one character left
+ - [kbd]Cmd + P[/kbd]: Same as [kbd]Up Arrow[/kbd], move the caret to the previous line
+ - [kbd]Cmd + N[/kbd]: Same as [kbd]Down Arrow[/kbd], move the caret to the next line
+ - [kbd]Cmd + D[/kbd]: Same as [kbd]Delete[/kbd], delete the character on the right side of caret
+ - [kbd]Cmd + H[/kbd]: Same as [kbd]Backspace[/kbd], delete the character on the left side of the caret
+ - [kbd]Cmd + A[/kbd]: Same as [kbd]Home[/kbd], move the caret to the beginning of the line
+ - [kbd]Cmd + E[/kbd]: Same as [kbd]End[/kbd], move the caret to the end of the line
- [kbd]Cmd + Left Arrow[/kbd]: Same as [kbd]Home[/kbd], move the caret to the beginning of the line
- [kbd]Cmd + Right Arrow[/kbd]: Same as [kbd]End[/kbd], move the caret to the end of the line
</description>
diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml
index 8a58ef2460..5918adf5e0 100644
--- a/doc/classes/LinkButton.xml
+++ b/doc/classes/LinkButton.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="LinkButton" inherits="BaseButton" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Simple button used to represent a link to some resource.
+ A button that represents a link.
</brief_description>
<description>
- This kind of button is primarily used when the interaction with the button causes a context change (like linking to a web page).
+ A button that represents a link. This type of button is primarily used for interactions that cause a context change (like linking to a web page).
See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
diff --git a/doc/classes/MarginContainer.xml b/doc/classes/MarginContainer.xml
index 3167512e5f..9ba4517e0e 100644
--- a/doc/classes/MarginContainer.xml
+++ b/doc/classes/MarginContainer.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MarginContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Simple margin container.
+ A container that keeps a margin around its child controls.
</brief_description>
<description>
- Adds a top, left, bottom, and right margin to all [Control] nodes that are direct children of the container. To control the [MarginContainer]'s margin, use the [code]margin_*[/code] theme properties listed below.
- [b]Note:[/b] Be careful, [Control] margin values are different from the constant margin values. If you want to change the custom margin values of the [MarginContainer] by code, you should use the following examples:
+ [MarginContainer] adds an adjustable margin on each side of its child controls. The margins are added around all children, not around each individual one. To control the [MarginContainer]'s margins, use the [code]margin_*[/code] theme properties listed below.
+ [b]Note:[/b] The margin sizes are theme overrides, not normal properties. This is an example of how to change them in code:
[codeblocks]
[gdscript]
# This code sample assumes the current script is extending MarginContainer.
@@ -26,7 +26,7 @@
[/codeblocks]
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="margin_bottom" data_type="constant" type="int" default="0">
diff --git a/doc/classes/MenuBar.xml b/doc/classes/MenuBar.xml
index 512994ae3e..f3fbcfff7b 100644
--- a/doc/classes/MenuBar.xml
+++ b/doc/classes/MenuBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MenuBar" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A horizontal menu bar, which displays [PopupMenu]s or system global menu.
+ A horizontal menu bar that creates a [MenuButton] for each [PopupMenu] child.
</brief_description>
<description>
- New items can be created by adding [PopupMenu] nodes to this node.
+ A horizontal menu bar that creates a [MenuButton] for each [PopupMenu] child. New items are created by adding [PopupMenu]s to this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index c937371a52..4f62660bb9 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MenuButton" inherits="Button" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Special button that brings up a [PopupMenu] when clicked.
+ A button that brings up a [PopupMenu] when clicked.
</brief_description>
<description>
- Special button that brings up a [PopupMenu] when clicked.
- New items can be created inside this [PopupMenu] using [code]get_popup().add_item("My Item Name")[/code]. You can also create them directly from the editor. To do so, select the [MenuButton] node, then in the toolbar at the top of the 2D editor, click [b]Items[/b] then click [b]Add[/b] in the popup. You will be able to give each item new properties.
+ A button that brings up a [PopupMenu] when clicked. To create new items inside this [PopupMenu], use [code]get_popup().add_item("My Item Name")[/code]. You can also create them directly from Godot editor's inspector.
See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index 52c8099fd9..4b9fa7bca9 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -235,16 +235,16 @@
[PackedVector2Array] for second UV coordinates.
</constant>
<constant name="ARRAY_CUSTOM0" value="6" enum="ArrayType">
- Contains custom color channel 0. [PackedByteArray] if [code](format &gt;&gt; [constant ARRAY_FORMAT_CUSTOM0_SHIFT]) &amp; [constant ARRAY_FORMAT_CUSTOM_MASK])[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
+ Contains custom color channel 0. [PackedByteArray] if [code](format &gt;&gt; Mesh.ARRAY_FORMAT_CUSTOM0_SHIFT) &amp; Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
</constant>
<constant name="ARRAY_CUSTOM1" value="7" enum="ArrayType">
- Contains custom color channel 1. [PackedByteArray] if [code](format &gt;&gt; [constant ARRAY_FORMAT_CUSTOM1_SHIFT]) &amp; [constant ARRAY_FORMAT_CUSTOM_MASK])[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
+ Contains custom color channel 1. [PackedByteArray] if [code](format &gt;&gt; Mesh.ARRAY_FORMAT_CUSTOM1_SHIFT) &amp; Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
</constant>
<constant name="ARRAY_CUSTOM2" value="8" enum="ArrayType">
- Contains custom color channel 2. [PackedByteArray] if [code](format &gt;&gt; [constant ARRAY_FORMAT_CUSTOM2_SHIFT]) &amp; [constant ARRAY_FORMAT_CUSTOM_MASK])[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
+ Contains custom color channel 2. [PackedByteArray] if [code](format &gt;&gt; Mesh.ARRAY_FORMAT_CUSTOM2_SHIFT) &amp; Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
</constant>
<constant name="ARRAY_CUSTOM3" value="9" enum="ArrayType">
- Contains custom color channel 3. [PackedByteArray] if [code](format &gt;&gt; [constant ARRAY_FORMAT_CUSTOM3_SHIFT]) &amp; [constant ARRAY_FORMAT_CUSTOM_MASK])[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
+ Contains custom color channel 3. [PackedByteArray] if [code](format &gt;&gt; Mesh.ARRAY_FORMAT_CUSTOM3_SHIFT) &amp; Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise.
</constant>
<constant name="ARRAY_BONES" value="10" enum="ArrayType">
[PackedFloat32Array] or [PackedInt32Array] of bone indices. Contains either 4 or 8 numbers per vertex depending on the presence of the [constant ARRAY_FLAG_USE_8_BONE_WEIGHTS] flag.
diff --git a/doc/classes/MissingNode.xml b/doc/classes/MissingNode.xml
index 88a65f33ad..0ad97e084e 100644
--- a/doc/classes/MissingNode.xml
+++ b/doc/classes/MissingNode.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MissingNode" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- This is an internal editor class intended for keeping data of nodes of unknown type.
+ An internal editor class intended for keeping the data of unrecognized nodes.
</brief_description>
<description>
This is an internal editor class intended for keeping data of nodes of unknown type (most likely this type was supplied by an extension that is no longer loaded). It can't be manually instantiated or placed in the scene. Ignore it if you don't know what it is.
@@ -10,6 +10,7 @@
</tutorials>
<members>
<member name="original_class" type="String" setter="set_original_class" getter="get_original_class">
+ Returns the name of the type this node was originally.
</member>
<member name="recording_properties" type="bool" setter="set_recording_properties" getter="is_recording_properties">
</member>
diff --git a/doc/classes/MissingResource.xml b/doc/classes/MissingResource.xml
index a71b16ed74..f63a6401d8 100644
--- a/doc/classes/MissingResource.xml
+++ b/doc/classes/MissingResource.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MissingResource" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- This is an internal editor class intended for keeping data of resources of unknown type.
+ An internal editor class intended for keeping the data of unrecognized resources.
</brief_description>
<description>
This is an internal editor class intended for keeping data of resources of unknown type (most likely this type was supplied by an extension that is no longer loaded). It can't be manually instantiated or placed in the scene. Ignore it if you don't know what it is.
@@ -10,6 +10,7 @@
</tutorials>
<members>
<member name="original_class" type="String" setter="set_original_class" getter="get_original_class">
+ Returns the name of the class this resource was originally.
</member>
<member name="recording_properties" type="bool" setter="set_recording_properties" getter="is_recording_properties">
</member>
diff --git a/doc/classes/Mutex.xml b/doc/classes/Mutex.xml
index ab1fad9624..98da57ed94 100644
--- a/doc/classes/Mutex.xml
+++ b/doc/classes/Mutex.xml
@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Mutex" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A synchronization mutex (mutual exclusion).
+ A binary [Semaphore] for synchronization of multiple [Thread]s.
</brief_description>
<description>
- A synchronization mutex (mutual exclusion). This is used to synchronize multiple [Thread]s, and is equivalent to a binary [Semaphore]. It guarantees that only one thread can ever acquire the lock at a time. A mutex can be used to protect a critical section; however, be careful to avoid deadlocks.
- It's of the recursive kind, so it can be locked multiple times by one thread, provided it also unlocks it as many times.
- [b]Warning:[/b]
- To guarantee that the operating system is able to perform proper cleanup (no crashes, no deadlocks), these conditions must be met:
- - By the time a [Mutex]'s reference count reaches zero and therefore it is destroyed, no threads (including the one on which the destruction will happen) must have it locked.
- - By the time a [Thread]'s reference count reaches zero and therefore it is destroyed, it must not have any mutex locked.
+ A synchronization mutex (mutual exclusion). This is used to synchronize multiple [Thread]s, and is equivalent to a binary [Semaphore]. It guarantees that only one thread can access a critical section at a time.
+ This is a reentrant mutex, meaning that it can be locked multiple times by one thread, provided it also unlocks it as many times.
+ [b]Warning:[/b] Mutexes must be used carefully to avoid deadlocks.
+ [b]Warning:[/b] To ensure proper cleanup without crashes or deadlocks, the following conditions must be met:
+ - When a [Mutex]'s reference count reaches zero and it is therefore destroyed, no threads (including the one on which the destruction will happen) must have it locked.
+ - When a [Thread]'s reference count reaches zero and it is therefore destroyed, it must not have any mutex locked.
</description>
<tutorials>
<link title="Using multiple threads">$DOCS_URL/tutorials/performance/using_multiple_threads.html</link>
+ <link title="Thread-safe APIs">$DOCS_URL/tutorials/performance/thread_safe_apis.html</link>
</tutorials>
<methods>
<method name="lock">
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index e401450e42..0feeacfb41 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationAgent2D" inherits="Node" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 2D Agent used in navigation for collision avoidance.
+ A 2D agent used to pathfind to a position while avoiding obstacles.
</brief_description>
<description>
- 2D Agent that is used in navigation to reach a position while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent2D] is physics safe.
- [b]Note:[/b] After [member target_position] is set, the [method get_next_path_position] function must be used once every physics frame to update the internal path logic of the NavigationAgent. The returned position from this function should be used as the next movement position for the agent's parent node.
+ A 2D agent used to pathfind to a position while avoiding static and dynamic obstacles. The calculation can be used by the parent node to dynamically move it along the path. Requires navigation data to work correctly.
+ Dynamic obstacles are avoided using RVO collision avoidance. Avoidance is computed before physics, so the pathfinding information can be used safely in the physics step.
+ [b]Note:[/b] After setting the [member target_position] property, the [method get_next_path_position] method must be used once every physics frame to update the internal path logic of the navigation agent. The vector position it returns should be used as the next movement position for the agent's parent node.
</description>
<tutorials>
<link title="Using NavigationAgents">$DOCS_URL/tutorials/navigation/navigation_using_navigationagents.html</link>
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index 00ef894378..6dc1b4ec36 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationAgent3D" inherits="Node" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 3D Agent used in navigation for collision avoidance.
+ A 3D agent used to pathfind to a position while avoiding obstacles.
</brief_description>
<description>
- 3D Agent that is used in navigation to reach a position while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent3D] is physics safe.
- [b]Note:[/b] After [member target_position] is set, the [method get_next_path_position] function must be used once every physics frame to update the internal path logic of the NavigationAgent. The returned position from this function should be used as the next movement position for the agent's parent node.
+ A 3D agent used to pathfind to a position while avoiding static and dynamic obstacles. The calculation can be used by the parent node to dynamically move it along the path. Requires navigation data to work correctly.
+ Dynamic obstacles are avoided using RVO collision avoidance. Avoidance is computed before physics, so the pathfinding information can be used safely in the physics step.
+ [b]Note:[/b] After setting the [member target_position] property, the [method get_next_path_position] method must be used once every physics frame to update the internal path logic of the navigation agent. The vector position it returns should be used as the next movement position for the agent's parent node.
</description>
<tutorials>
<link title="Using NavigationAgents">$DOCS_URL/tutorials/navigation/navigation_using_navigationagents.html</link>
diff --git a/doc/classes/NavigationLink2D.xml b/doc/classes/NavigationLink2D.xml
index a08f65da3c..7dd7e31775 100644
--- a/doc/classes/NavigationLink2D.xml
+++ b/doc/classes/NavigationLink2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationLink2D" inherits="Node2D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Creates a link between two positions that [NavigationServer2D] can route agents through.
+ A link between two positions on [NavigationRegion2D]s that agents can be routed through.
</brief_description>
<description>
- Creates a link between two positions that [NavigationServer2D] can route agents through. Links can be used to express navigation methods that aren't just traveling along the surface of the navigation mesh, like zip-lines, teleporters, or jumping across gaps.
+ A link between two positions on [NavigationRegion2D]s that agents can be routed through. These positions can be on the same [NavigationRegion2D] or on two different ones. Links are useful to express navigation methods other than traveling along the surface of the navigation polygon, such as ziplines, teleporters, or gaps that can be jumped across.
</description>
<tutorials>
<link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link>
diff --git a/doc/classes/NavigationLink3D.xml b/doc/classes/NavigationLink3D.xml
index 70dfee9c10..1ef59305e2 100644
--- a/doc/classes/NavigationLink3D.xml
+++ b/doc/classes/NavigationLink3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationLink3D" inherits="Node3D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Creates a link between two positions that [NavigationServer3D] can route agents through.
+ A link between two positions on [NavigationRegion3D]s that agents can be routed through.
</brief_description>
<description>
- Creates a link between two positions that [NavigationServer3D] can route agents through. Links can be used to express navigation methods that aren't just traveling along the surface of the navigation mesh, like zip-lines, teleporters, or jumping across gaps.
+ A link between two positions on [NavigationRegion3D]s that agents can be routed through. These positions can be on the same [NavigationRegion3D] or on two different ones. Links are useful to express navigation methods other than traveling along the surface of the navigation mesh, such as ziplines, teleporters, or gaps that can be jumped across.
</description>
<tutorials>
<link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link>
diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml
index a3d266b15c..5999dc6222 100644
--- a/doc/classes/NavigationMesh.xml
+++ b/doc/classes/NavigationMesh.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationMesh" inherits="Resource" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A mesh to approximate the walkable areas and obstacles.
+ A navigation mesh that defines traversable areas and obstacles.
</brief_description>
<description>
A navigation mesh is a collection of polygons that define which areas of an environment are traversable to aid agents in pathfinding through complicated spaces.
diff --git a/doc/classes/NavigationPathQueryParameters2D.xml b/doc/classes/NavigationPathQueryParameters2D.xml
index afead4c55b..0e48508197 100644
--- a/doc/classes/NavigationPathQueryParameters2D.xml
+++ b/doc/classes/NavigationPathQueryParameters2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationPathQueryParameters2D" inherits="RefCounted" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 2D navigation path query.
+ Provides parameters for 2D navigation path queries.
</brief_description>
<description>
- This class contains the start and target position and other parameters to be used with [method NavigationServer2D.query_path].
+ By changing various properties of this object, such as the start and target position, you can configure path queries to the [NavigationServer2D].
</description>
<tutorials>
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
diff --git a/doc/classes/NavigationPathQueryParameters3D.xml b/doc/classes/NavigationPathQueryParameters3D.xml
index 985b320628..7564c6a858 100644
--- a/doc/classes/NavigationPathQueryParameters3D.xml
+++ b/doc/classes/NavigationPathQueryParameters3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationPathQueryParameters3D" inherits="RefCounted" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 3D navigation path query.
+ Provides parameters for 3D navigation path queries.
</brief_description>
<description>
- This class contains the start and target position and other parameters to be used with [method NavigationServer3D.query_path].
+ By changing various properties of this object, such as the start and target position, you can configure path queries to the [NavigationServer3D].
</description>
<tutorials>
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
diff --git a/doc/classes/NavigationPathQueryResult2D.xml b/doc/classes/NavigationPathQueryResult2D.xml
index 096ee255eb..e9acdea5ba 100644
--- a/doc/classes/NavigationPathQueryResult2D.xml
+++ b/doc/classes/NavigationPathQueryResult2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationPathQueryResult2D" inherits="RefCounted" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Result from a [NavigationPathQueryParameters2D] navigation path query.
+ Represents the result of a 2D pathfinding query.
</brief_description>
<description>
- This class contains the result of a navigation path query from [method NavigationServer2D.query_path].
+ This class stores the result of a 2D navigation path query from the [NavigationServer2D].
</description>
<tutorials>
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
diff --git a/doc/classes/NavigationPathQueryResult3D.xml b/doc/classes/NavigationPathQueryResult3D.xml
index 597c80ed29..8953f0e6df 100644
--- a/doc/classes/NavigationPathQueryResult3D.xml
+++ b/doc/classes/NavigationPathQueryResult3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationPathQueryResult3D" inherits="RefCounted" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Result from a [NavigationPathQueryParameters3D] navigation path query.
+ Represents the result of a 3D pathfinding query.
</brief_description>
<description>
- This class contains the result of a navigation path query from [method NavigationServer3D.query_path].
+ This class stores the result of a 3D navigation path query from the [NavigationServer3D].
</description>
<tutorials>
<link title="Using NavigationPathQueryObjects">$DOCS_URL/tutorials/navigation/navigation_using_navigationpathqueryobjects.html</link>
diff --git a/doc/classes/NavigationPolygon.xml b/doc/classes/NavigationPolygon.xml
index 554bf58610..73725117bd 100644
--- a/doc/classes/NavigationPolygon.xml
+++ b/doc/classes/NavigationPolygon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationPolygon" inherits="Resource" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A node that has methods to draw outlines or use indices of vertices to create navigation polygons.
+ A navigation polygon that defines traversable areas and obstacles.
</brief_description>
<description>
There are two ways to create polygons. Either by using the [method add_outline] method, or using the [method add_polygon] method.
diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml
index 1f1c0993d5..05cd49f323 100644
--- a/doc/classes/NavigationRegion2D.xml
+++ b/doc/classes/NavigationRegion2D.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationRegion2D" inherits="Node2D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A region of the 2D navigation map.
+ A traversable 2D region that [NavigationAgent2D]s can use for pathfinding.
</brief_description>
<description>
- A region of the navigation map. It tells the [NavigationServer2D] what can be navigated and what cannot, based on its [NavigationPolygon] resource.
+ A traversable 2D region based on a [NavigationPolygon] that [NavigationAgent2D]s can use for pathfinding.
Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer2D.map_set_edge_connection_margin].
[b]Note:[/b] Overlapping two regions' navigation polygons is not enough for connecting two regions. They must share a similar edge.
- The pathfinding cost of entering this region from another region can be controlled with the [member enter_cost] value.
+ The pathfinding cost of entering a region from another region can be controlled with the [member enter_cost] value.
[b]Note:[/b] This value is not added to the path cost when the start position is already inside this region.
The pathfinding cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier.
[b]Note:[/b] This node caches changes to its properties, so if you make changes to the underlying region [RID] in [NavigationServer2D], they will not be reflected in this node's properties.
diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml
index 0988d07e8c..88b4f0dbf1 100644
--- a/doc/classes/NavigationRegion3D.xml
+++ b/doc/classes/NavigationRegion3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationRegion3D" inherits="Node3D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A region of the navigation map.
+ A traversable 3D region that [NavigationAgent3D]s can use for pathfinding.
</brief_description>
<description>
- A region of the navigation map. It tells the [NavigationServer3D] what can be navigated and what cannot, based on its [NavigationMesh] resource.
+ A traversable 3D region based on a [NavigationMesh] that [NavigationAgent3D]s can use for pathfinding.
Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer3D.map_set_edge_connection_margin].
[b]Note:[/b] Overlapping two regions' navigation meshes is not enough for connecting two regions. They must share a similar edge.
The cost of entering this region from another region can be controlled with the [member enter_cost] value.
diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml
index e2293f2439..a487bb68c2 100644
--- a/doc/classes/NavigationServer2D.xml
+++ b/doc/classes/NavigationServer2D.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationServer2D" inherits="Object" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Server interface for low-level 2D navigation access.
+ A server interface for low-level 2D navigation access.
</brief_description>
<description>
- NavigationServer2D is the server responsible for all 2D navigation. It handles several objects, namely maps, regions and agents.
- Maps are made up of regions, which are made of navigation polygons. Together, they define the navigable areas in the 2D world.
- [b]Note:[/b] Most NavigationServer changes take effect after the next physics frame and not immediately. This includes all changes made to maps, regions or agents by navigation related Nodes in the SceneTree or made through scripts.
+ NavigationServer2D is the server that handles navigation maps, regions and agents. It does not handle A* navigation from [AStar2D] or [AStarGrid2D].
+ Maps are made up of regions, which are made of navigation polygons. Together, they define the traversable areas in the 2D world.
+ [b]Note:[/b] Most [NavigationServer2D] changes take effect after the next physics frame and not immediately. This includes all changes made to maps, regions or agents by navigation-related nodes in the scene tree or made through scripts.
For two regions to be connected to each other, they must share a similar edge. An edge is considered connected to another if both of its two vertices are at a distance less than [code]edge_connection_margin[/code] to the respective other edge's vertex.
- You may assign navigation layers to regions with [method NavigationServer2D.region_set_navigation_layers], which then can be checked upon when requesting a path with [method NavigationServer2D.map_get_path]. This allows allowing or forbidding some areas to 2D objects.
+ You may assign navigation layers to regions with [method NavigationServer2D.region_set_navigation_layers], which then can be checked upon when requesting a path with [method NavigationServer2D.map_get_path]. This can be used to allow or deny certain areas for some objects.
To use the collision avoidance system, you may use agents. You can set an agent's target velocity, then the servers will emit a callback with a modified velocity.
- [b]Note:[/b] The collision avoidance system ignores regions. Using the modified velocity as-is might lead to pushing an agent outside of a navigable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
+ [b]Note:[/b] The collision avoidance system ignores regions. Using the modified velocity directly may move an agent outside of the traversable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
This server keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
</description>
<tutorials>
@@ -383,7 +383,7 @@
<return type="RID[]" />
<param index="0" name="map" type="RID" />
<description>
- Returns all navigation obstacle [RID]s that are currently assigned to the requested navigation [code]map[/code].
+ Returns all navigation obstacle [RID]s that are currently assigned to the requested navigation [param map].
</description>
</method>
<method name="map_get_path" qualifiers="const">
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml
index cc6b3b8ca4..f5221ad17d 100644
--- a/doc/classes/NavigationServer3D.xml
+++ b/doc/classes/NavigationServer3D.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationServer3D" inherits="Object" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Server interface for low-level 3D navigation access.
+ A server interface for low-level 3D navigation access.
</brief_description>
<description>
- NavigationServer3D is the server responsible for all 3D navigation. It handles several objects, namely maps, regions and agents.
+ NavigationServer2D is the server that handles navigation maps, regions and agents. It does not handle A* navigation from [AStar3D].
Maps are made up of regions, which are made of navigation meshes. Together, they define the navigable areas in the 3D world.
- [b]Note:[/b] Most NavigationServer changes take effect after the next physics frame and not immediately. This includes all changes made to maps, regions or agents by navigation related Nodes in the SceneTree or made through scripts.
+ [b]Note:[/b] Most [NavigationServer3D] changes take effect after the next physics frame and not immediately. This includes all changes made to maps, regions or agents by navigation-related nodes in the scene tree or made through scripts.
For two regions to be connected to each other, they must share a similar edge. An edge is considered connected to another if both of its two vertices are at a distance less than [code]edge_connection_margin[/code] to the respective other edge's vertex.
- You may assign navigation layers to regions with [method NavigationServer3D.region_set_navigation_layers], which then can be checked upon when requesting a path with [method NavigationServer3D.map_get_path]. This allows allowing or forbidding some areas to 3D objects.
+ You may assign navigation layers to regions with [method NavigationServer3D.region_set_navigation_layers], which then can be checked upon when requesting a path with [method NavigationServer3D.map_get_path]. This can be used to allow or deny certain areas for some objects.
To use the collision avoidance system, you may use agents. You can set an agent's target velocity, then the servers will emit a callback with a modified velocity.
- [b]Note:[/b] The collision avoidance system ignores regions. Using the modified velocity as-is might lead to pushing and agent outside of a navigable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
+ [b]Note:[/b] The collision avoidance system ignores regions. Using the modified velocity directly may move an agent outside of the traversable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
This server keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
</description>
<tutorials>
@@ -433,7 +433,7 @@
<return type="RID[]" />
<param index="0" name="map" type="RID" />
<description>
- Returns all navigation obstacle [RID]s that are currently assigned to the requested navigation [code]map[/code].
+ Returns all navigation obstacle [RID]s that are currently assigned to the requested navigation [param map].
</description>
</method>
<method name="map_get_path" qualifiers="const">
diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml
index 63dd59fd2c..d5283236a9 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NinePatchRect" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Scalable texture-based frame that tiles the texture's centers and sides, but keeps the corners' original size. Perfect for panels and dialog boxes.
+ A control that displays a texture by keeping its corners intact, but tiling its edges and center.
</brief_description>
<description>
- Also known as 9-slice panels, NinePatchRect produces clean panels of any size, based on a small texture. To do so, it splits the texture in a 3×3 grid. When you scale the node, it tiles the texture's sides horizontally or vertically, the center on both axes but it doesn't scale or tile the corners.
+ Also known as 9-slice panels, [NinePatchRect] produces clean panels of any size based on a small texture. To do so, it splits the texture in a 3×3 grid. When you scale the node, it tiles the texture's edges horizontally or vertically, tiles the center on both axes, and leaves the corners unchanged.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 328f0c3fa1..4ea96f97e5 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Node" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all [i]scene[/i] objects.
+ Base class for all scene objects.
</brief_description>
<description>
Nodes are Godot's building blocks. They can be assigned as the child of another node, resulting in a tree arrangement. A given node can contain any number of nodes as children with the requirement that all siblings (direct children of a node) should have unique names.
diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml
index ee34a0c405..1bc44d5680 100644
--- a/doc/classes/NodePath.xml
+++ b/doc/classes/NodePath.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NodePath" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Pre-parsed scene tree path.
+ A pre-parsed scene tree path.
</brief_description>
<description>
A pre-parsed relative or absolute path in a scene tree, for use with [method Node.get_node] and similar functions. It can reference a node, a resource within a node, or a property of a node or resource. For example, [code]"Path2D/PathFollow2D/Sprite2D:texture:size"[/code] would refer to the [code]size[/code] property of the [code]texture[/code] resource on the node named [code]"Sprite2D"[/code] which is a child of the other named nodes in the path.
@@ -22,6 +22,7 @@
[/codeblock]
See also [StringName], which is a similar concept for general-purpose string interning.
[b]Note:[/b] In the editor, [NodePath] properties are automatically updated when moving, renaming or deleting a node in the scene tree, but they are never updated at runtime.
+ [b]Note:[/b] In a boolean context, a [NodePath] will evaluate to [code]false[/code] if it is empty ([code]NodePath("")[/code]). Otherwise, a [NodePath] will always evaluate to [code]true[/code].
</description>
<tutorials>
<link title="2D Role Playing Game Demo">https://godotengine.org/asset-library/asset/520</link>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index e64b409551..0696ae224a 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="OS" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Operating System functions.
+ Provides access to common operating system functionalities.
</brief_description>
<description>
- Operating System functions. [OS] wraps the most common functionality to communicate with the host operating system, such as the video driver, delays, environment variables, execution of binaries, command line, etc.
+ This class wraps the most common functionalities for communicating with the host operating system, such as the video driver, delays, environment variables, execution of binaries, command line, etc.
[b]Note:[/b] In Godot 4, [OS] functions related to window management were moved to the [DisplayServer] singleton.
</description>
<tutorials>
@@ -241,7 +241,7 @@
<return type="PackedStringArray" />
<description>
With this function, you can get the list of dangerous permissions that have been granted to the Android application.
- [b]Note:[/b] This method is implemented on Android.
+ [b]Note:[/b] This method is implemented only on Android.
</description>
</method>
<method name="get_keycode_string" qualifiers="const">
@@ -599,7 +599,7 @@
<return type="bool" />
<description>
With this function, you can request dangerous permissions since normal permissions are automatically granted at install time in Android applications.
- [b]Note:[/b] This method is implemented on Android.
+ [b]Note:[/b] This method is implemented only on Android.
</description>
</method>
<method name="set_environment" qualifiers="const">
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index 0a52df1e49..79b58a1364 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -175,7 +175,7 @@
print("Goodbye!")
[/gdscript]
[csharp]
- public override void _Notification(long what)
+ public override void _Notification(int what)
{
if (what == NotificationPredelete)
{
@@ -599,7 +599,8 @@
<param index="1" name="default" type="Variant" default="null" />
<description>
Returns the object's metadata value for the given entry [param name]. If the entry does not exist, returns [param default]. If [param default] is [code]null[/code], an error is also generated.
- [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector dock and should not be edited.
+ [b]Note:[/b] A metadata's [param name] must be a valid identifier as per [method StringName.is_valid_identifier] method.
+ [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited, although it can still be found by this method.
</description>
</method>
<method name="get_meta_list" qualifiers="const">
@@ -661,6 +662,7 @@
<param index="0" name="name" type="StringName" />
<description>
Returns [code]true[/code] if a metadata entry is found with the given [param name]. See also [method get_meta], [method set_meta] and [method remove_meta].
+ [b]Note:[/b] A metadata's [param name] must be a valid identifier as per [method StringName.is_valid_identifier] method.
[b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited, although it can still be found by this method.
</description>
</method>
@@ -788,7 +790,8 @@
<param index="0" name="name" type="StringName" />
<description>
Removes the given entry [param name] from the object's metadata. See also [method has_meta], [method get_meta] and [method set_meta].
- [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited.
+ [b]Note:[/b] A metadata's [param name] must be a valid identifier as per [method StringName.is_valid_identifier] method.
+ [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited, although it can still be found by this method.
</description>
</method>
<method name="set">
@@ -887,7 +890,8 @@
<description>
Adds or changes the entry [param name] inside the object's metadata. The metadata [param value] can be any [Variant], although some types cannot be serialized correctly.
If [param value] is [code]null[/code], the entry is removed. This is the equivalent of using [method remove_meta]. See also [method has_meta] and [method get_meta].
- [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector dock and should not be edited.
+ [b]Note:[/b] A metadata's [param name] must be a valid identifier as per [method StringName.is_valid_identifier] method.
+ [b]Note:[/b] Metadata that has a [param name] starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited, although it can still be found by this method.
</description>
</method>
<method name="set_script">
diff --git a/doc/classes/OptimizedTranslation.xml b/doc/classes/OptimizedTranslation.xml
index d8c4ce63eb..7d55355363 100644
--- a/doc/classes/OptimizedTranslation.xml
+++ b/doc/classes/OptimizedTranslation.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="OptimizedTranslation" inherits="Translation" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Optimized translation.
+ An optimized translation, used by default for CSV Translations.
</brief_description>
<description>
- Optimized translation. Uses real-time compressed translations, which results in very small dictionaries.
+ An optimized translation, used by default for CSV Translations. Uses real-time compressed translations, which results in very small dictionaries.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 17a164953d..84c8b89021 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="OptionButton" inherits="Button" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Button control that provides selectable options when pressed.
+ A button that brings up a dropdown with selectable options when pressed.
</brief_description>
<description>
- OptionButton is a type button that provides a selectable list of items when pressed. The item selected becomes the "current" item and is displayed as the button text.
+ [OptionButton] is a type of button that brings up a dropdown with selectable items when pressed. The item selected becomes the "current" item and is displayed as the button text.
See also [BaseButton] which contains common properties and methods associated with this node.
[b]Note:[/b] Properties [member Button.text] and [member Button.icon] are automatically set based on the selected item. They shouldn't be changed manually.
[b]Note:[/b] The ID values used for items are limited to 32 bits, not full 64 bits of [int]. This has a range of [code]-2^32[/code] to [code]2^32 - 1[/code], i.e. [code]-2147483648[/code] to [code]2147483647[/code].
+ [b]Note:[/b] The ID values used for items are 32-bit, unlike [int] which is always 64-bit. They go from [code]-2147483648[/code] to [code]2147483647[/code].
+ [b]Note:[/b] The [member Button.text] and [member Button.icon] properties are set automatically based on the selected item. They shouldn't be changed manually.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PackedDataContainerRef.xml b/doc/classes/PackedDataContainerRef.xml
index 440673d9b0..5199d9b445 100644
--- a/doc/classes/PackedDataContainerRef.xml
+++ b/doc/classes/PackedDataContainerRef.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PackedDataContainerRef" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Internal class used by [PackedDataContainer].
+ An internal class used by [PackedDataContainer] to pack nested arrays and dictionaries.
</brief_description>
<description>
When packing nested containers using [PackedDataContainer], they are recursively packed into [PackedDataContainerRef] (only applies to [Array] and [Dictionary]). Their data can be retrieved the same way as from [PackedDataContainer].
diff --git a/doc/classes/Panel.xml b/doc/classes/Panel.xml
index 1f5b0ab925..92ed109e70 100644
--- a/doc/classes/Panel.xml
+++ b/doc/classes/Panel.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Panel" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Provides an opaque background for [Control] children.
+ A GUI control that displays a [StyleBox].
</brief_description>
<description>
- Panel is a [Control] that displays an opaque background. It's commonly used as a parent and container for other types of [Control] nodes.
+ [Panel] is a GUI control that displays a [StyleBox]. See also [PanelContainer].
</description>
<tutorials>
<link title="2D Role Playing Game Demo">https://godotengine.org/asset-library/asset/520</link>
@@ -13,7 +13,7 @@
</tutorials>
<theme_items>
<theme_item name="panel" data_type="style" type="StyleBox">
- The style of this [Panel].
+ The [StyleBox] of this control.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/PanelContainer.xml b/doc/classes/PanelContainer.xml
index 6419d25441..2217fde78c 100644
--- a/doc/classes/PanelContainer.xml
+++ b/doc/classes/PanelContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PanelContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Panel container type.
+ A container that keeps its child controls within the area of a [StyleBox].
</brief_description>
<description>
- Panel container type. This container fits controls inside of the delimited area of a stylebox. It's useful for giving controls an outline.
+ A container that keeps its child controls within the area of a [StyleBox]. Useful for giving controls an outline.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
<link title="2D Role Playing Game Demo">https://godotengine.org/asset-library/asset/520</link>
</tutorials>
<members>
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index 82f706d3f2..445cf3a762 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsBody2D" inherits="CollisionObject2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all objects affected by physics in 2D space.
+ Abstract base class for 2D game objects affected by physics.
</brief_description>
<description>
- PhysicsBody2D is an abstract base class for implementing a physics body. All *Body2D types inherit from it.
+ [PhysicsBody2D] is an abstract base class for 2D game objects affected by physics. All 2D physics bodies inherit from it.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml
index 9d2abd19c2..b8e77083f1 100644
--- a/doc/classes/PhysicsBody3D.xml
+++ b/doc/classes/PhysicsBody3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsBody3D" inherits="CollisionObject3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all objects affected by physics in 3D space.
+ Abstract base class for 3D game objects affected by physics.
</brief_description>
<description>
- PhysicsBody3D is an abstract base class for implementing a physics body. All *Body3D types inherit from it.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ [PhysicsBody3D] is an abstract base class for 3D game objects affected by physics. All 3D physics bodies inherit from it.
+ [b]Warning:[/b] With a non-uniform scale, this node will likely not behave as expected. It is advised to keep its scale the same on all axes and adjust its collision shape(s) instead.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml
index bfc25e0bd4..7928fa1717 100644
--- a/doc/classes/PhysicsDirectBodyState2D.xml
+++ b/doc/classes/PhysicsDirectBodyState2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectBodyState2D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Direct access object to a physics body in the [PhysicsServer2D].
+ Provides direct access to a physics body in the [PhysicsServer2D].
</brief_description>
<description>
- Provides direct access to a physics body in the [PhysicsServer2D], allowing safe changes to physics properties. This object is passed via the direct state callback of rigid bodies, and is intended for changing the direct state of that body. See [method RigidBody2D._integrate_forces].
+ Provides direct access to a physics body in the [PhysicsServer2D], allowing safe changes to physics properties. This object is passed via the direct state callback of [RigidBody2D], and is intended for changing the direct state of that body. See [method RigidBody2D._integrate_forces].
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsDirectBodyState2DExtension.xml b/doc/classes/PhysicsDirectBodyState2DExtension.xml
index b6c0adb91d..eee723ca0f 100644
--- a/doc/classes/PhysicsDirectBodyState2DExtension.xml
+++ b/doc/classes/PhysicsDirectBodyState2DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectBodyState2DExtension" inherits="PhysicsDirectBodyState2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsDirectBodyState2D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsDirectBodyState2D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsDirectBodyState2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsDirectBodyState3D.xml b/doc/classes/PhysicsDirectBodyState3D.xml
index 77ebd58ad9..8b2656187c 100644
--- a/doc/classes/PhysicsDirectBodyState3D.xml
+++ b/doc/classes/PhysicsDirectBodyState3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectBodyState3D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Direct access object to a physics body in the [PhysicsServer3D].
+ Provides direct access to a physics body in the [PhysicsServer3D].
</brief_description>
<description>
- Provides direct access to a physics body in the [PhysicsServer3D], allowing safe changes to physics properties. This object is passed via the direct state callback of rigid bodies, and is intended for changing the direct state of that body. See [method RigidBody3D._integrate_forces].
+ Provides direct access to a physics body in the [PhysicsServer3D], allowing safe changes to physics properties. This object is passed via the direct state callback of [RigidBody3D], and is intended for changing the direct state of that body. See [method RigidBody3D._integrate_forces].
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsDirectBodyState3DExtension.xml b/doc/classes/PhysicsDirectBodyState3DExtension.xml
index 3220733d23..8bca17a08f 100644
--- a/doc/classes/PhysicsDirectBodyState3DExtension.xml
+++ b/doc/classes/PhysicsDirectBodyState3DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectBodyState3DExtension" inherits="PhysicsDirectBodyState3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsDirectBodyState3D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsDirectBodyState3D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsDirectBodyState3D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsDirectSpaceState2D.xml b/doc/classes/PhysicsDirectSpaceState2D.xml
index ecc01d0c5c..2d88601319 100644
--- a/doc/classes/PhysicsDirectSpaceState2D.xml
+++ b/doc/classes/PhysicsDirectSpaceState2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectSpaceState2D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Direct access object to a space in the [PhysicsServer2D].
+ Provides direct access to a physics space in the [PhysicsServer2D].
</brief_description>
<description>
- Direct access object to a space in the [PhysicsServer2D]. It's used mainly to do queries against objects and areas residing in a given space.
+ Provides direct access to a physics space in the [PhysicsServer2D]. It's used mainly to do queries against objects and areas residing in a given space.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsDirectSpaceState2DExtension.xml b/doc/classes/PhysicsDirectSpaceState2DExtension.xml
index 4548b606e1..f38d7ec4b4 100644
--- a/doc/classes/PhysicsDirectSpaceState2DExtension.xml
+++ b/doc/classes/PhysicsDirectSpaceState2DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectSpaceState2DExtension" inherits="PhysicsDirectSpaceState2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsDirectSpaceState2D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsDirectSpaceState2D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsDirectSpaceState2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml
index ee347c04b1..e3eda631c6 100644
--- a/doc/classes/PhysicsDirectSpaceState3D.xml
+++ b/doc/classes/PhysicsDirectSpaceState3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectSpaceState3D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Direct access object to a space in the [PhysicsServer3D].
+ Provides direct access to a physics space in the [PhysicsServer3D].
</brief_description>
<description>
- Direct access object to a space in the [PhysicsServer3D]. It's used mainly to do queries against objects and areas residing in a given space.
+ Provides direct access to a physics space in the [PhysicsServer3D]. It's used mainly to do queries against objects and areas residing in a given space.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/PhysicsDirectSpaceState3DExtension.xml b/doc/classes/PhysicsDirectSpaceState3DExtension.xml
index 64089489c0..b3377c31b1 100644
--- a/doc/classes/PhysicsDirectSpaceState3DExtension.xml
+++ b/doc/classes/PhysicsDirectSpaceState3DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsDirectSpaceState3DExtension" inherits="PhysicsDirectSpaceState3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsDirectSpaceState3D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsDirectSpaceState3D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsDirectSpaceState3D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsMaterial.xml b/doc/classes/PhysicsMaterial.xml
index 57204ebef2..16a1989e8c 100644
--- a/doc/classes/PhysicsMaterial.xml
+++ b/doc/classes/PhysicsMaterial.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsMaterial" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A material for physics properties.
+ Holds physics-related properties of a surface, namely its roughness and bounciness.
</brief_description>
<description>
- Provides a means of modifying the collision properties of a [PhysicsBody3D].
+ Holds physics-related properties of a surface, namely its roughness and bounciness. This class is used to apply these properties to a physics body.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsPointQueryParameters2D.xml b/doc/classes/PhysicsPointQueryParameters2D.xml
index c9fe484516..82a32b79e0 100644
--- a/doc/classes/PhysicsPointQueryParameters2D.xml
+++ b/doc/classes/PhysicsPointQueryParameters2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsPointQueryParameters2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 2D point physics query.
+ Provides parameters for [method PhysicsDirectSpaceState2D.intersect_point].
</brief_description>
<description>
- This class contains the position and other parameters to be used for [method PhysicsDirectSpaceState2D.intersect_point].
+ By changing various properties of this object, such as the point position, you can configure the parameters for [method PhysicsDirectSpaceState2D.intersect_point].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsPointQueryParameters3D.xml b/doc/classes/PhysicsPointQueryParameters3D.xml
index a671783399..e28a0ed869 100644
--- a/doc/classes/PhysicsPointQueryParameters3D.xml
+++ b/doc/classes/PhysicsPointQueryParameters3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsPointQueryParameters3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 3D point physics query.
+ Provides parameters for [method PhysicsDirectSpaceState3D.intersect_point].
</brief_description>
<description>
- This class contains the position and other parameters to be used for [method PhysicsDirectSpaceState3D.intersect_point].
+ By changing various properties of this object, such as the point position, you can configure the parameters for [method PhysicsDirectSpaceState3D.intersect_point].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsRayQueryParameters2D.xml b/doc/classes/PhysicsRayQueryParameters2D.xml
index ba0f6c236e..fa1067a245 100644
--- a/doc/classes/PhysicsRayQueryParameters2D.xml
+++ b/doc/classes/PhysicsRayQueryParameters2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsRayQueryParameters2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 2D ray physics query.
+ Provides parameters for [method PhysicsDirectSpaceState2D.intersect_ray].
</brief_description>
<description>
- This class contains the ray position and other parameters to be used for [method PhysicsDirectSpaceState2D.intersect_ray].
+ By changing various properties of this object, such as the ray position, you can configure the parameters for [method PhysicsDirectSpaceState2D.intersect_ray].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsRayQueryParameters3D.xml b/doc/classes/PhysicsRayQueryParameters3D.xml
index f191f6449c..dd3df6db2f 100644
--- a/doc/classes/PhysicsRayQueryParameters3D.xml
+++ b/doc/classes/PhysicsRayQueryParameters3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsRayQueryParameters3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 3D ray physics query.
+ Provides parameters for [method PhysicsDirectSpaceState3D.intersect_ray].
</brief_description>
<description>
- This class contains the ray position and other parameters to be used for [method PhysicsDirectSpaceState3D.intersect_ray].
+ By changing various properties of this object, such as the ray position, you can configure the parameters for [method PhysicsDirectSpaceState3D.intersect_ray].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index 4ed65e7bfb..e7b5e4132b 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer2D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Server interface for low-level 2D physics access.
+ A server interface for low-level 2D physics access.
</brief_description>
<description>
PhysicsServer2D is the server responsible for all 2D physics. It can directly create and manipulate all physics objects:
- A [i]space[/i] is a self-contained world for a physics simulation. It contains bodies, areas, and joints. Its state can be queried for collision and intersection information, and several parameters of the simulation can be modified.
- - A [i]shape[/i] is a geometric figure such as a circle, a rectangle, a capsule, or a polygon. It can be used for collision detection by adding it to a body/area, possibly with an extra transformation relative to the body/area's origin. Bodies/areas can have multiple (transformed) shapes added to them, and a single shape can be added to bodies/areas multiple times with different local transformations.
+ - A [i]shape[/i] is a geometric shape such as a circle, a rectangle, a capsule, or a polygon. It can be used for collision detection by adding it to a body/area, possibly with an extra transformation relative to the body/area's origin. Bodies/areas can have multiple (transformed) shapes added to them, and a single shape can be added to bodies/areas multiple times with different local transformations.
- A [i]body[/i] is a physical object which can be in static, kinematic, or rigid mode. Its state (such as position and velocity) can be queried and updated. A force integration callback can be set to customize the body's physics.
- An [i]area[/i] is a region in space which can be used to detect bodies and areas entering and exiting it. A body monitoring callback can be set to report entering/exiting body shapes, and similarly an area monitoring callback can be set. Gravity and damping can be overridden within the area by setting area parameters.
- A [i]joint[/i] is a constraint, either between two bodies or on one body relative to a point. Parameters such as the joint bias and the rest length of a spring joint can be adjusted.
- Physics objects in the physics server may be created and manipulated independently; they do not have to be tied to nodes in the scene tree.
- [b]Note:[/b] All the physics nodes use the physics server internally. Adding a physics node to the scene tree will cause a corresponding physics object to be created in the physics server. A rigid body node registers a callback that updates the node's transform with the transform of the respective body object in the physics server (every physics update). An area node registers a callback to inform the area node about overlaps with the respective area object in the physics server. The raycast node queries the direct state of the relevant space in the physics server.
+ Physics objects in [PhysicsServer2D] may be created and manipulated independently; they do not have to be tied to nodes in the scene tree.
+ [b]Note:[/b] All the 2D physics nodes use the physics server internally. Adding a physics node to the scene tree will cause a corresponding physics object to be created in the physics server. A rigid body node registers a callback that updates the node's transform with the transform of the respective body object in the physics server (every physics update). An area node registers a callback to inform the area node about overlaps with the respective area object in the physics server. The raycast node queries the direct state of the relevant space in the physics server.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsServer2DExtension.xml b/doc/classes/PhysicsServer2DExtension.xml
index dbab9076a4..96d2f45fc3 100644
--- a/doc/classes/PhysicsServer2DExtension.xml
+++ b/doc/classes/PhysicsServer2DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer2DExtension" inherits="PhysicsServer2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsServer2D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsServer2D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsServer2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsServer2DManager.xml b/doc/classes/PhysicsServer2DManager.xml
index 6b8bb85ae5..5fc161207b 100644
--- a/doc/classes/PhysicsServer2DManager.xml
+++ b/doc/classes/PhysicsServer2DManager.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer2DManager" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Manager for 2D physics server implementations.
+ A singleton for managing [PhysicsServer2D] implementations.
</brief_description>
<description>
- [PhysicsServer2DManager] is the API for registering [PhysicsServer2D] implementations, and for setting the default implementation.
+ [PhysicsServer2DManager] is the API for registering [PhysicsServer2D] implementations and for setting the default implementation.
[b]Note:[/b] It is not possible to switch physics servers at runtime. This class is only used on startup at the server initialization level, by Godot itself and possibly by GDExtensions.
</description>
<tutorials>
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index 492d738639..22f7579017 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -1,10 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer3D" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Server interface for low-level physics access.
+ A server interface for low-level 3D physics access.
</brief_description>
<description>
- PhysicsServer3D is the server responsible for all 3D physics. It can create many kinds of physics objects, but does not insert them on the node tree.
+ PhysicsServer2D is the server responsible for all 2D physics. It can directly create and manipulate all physics objects:
+ - A [i]space[/i] is a self-contained world for a physics simulation. It contains bodies, areas, and joints. Its state can be queried for collision and intersection information, and several parameters of the simulation can be modified.
+ - A [i]shape[/i] is a geometric shape such as a sphere, a box, a cylinder, or a polygon. It can be used for collision detection by adding it to a body/area, possibly with an extra transformation relative to the body/area's origin. Bodies/areas can have multiple (transformed) shapes added to them, and a single shape can be added to bodies/areas multiple times with different local transformations.
+ - A [i]body[/i] is a physical object which can be in static, kinematic, or rigid mode. Its state (such as position and velocity) can be queried and updated. A force integration callback can be set to customize the body's physics.
+ - An [i]area[/i] is a region in space which can be used to detect bodies and areas entering and exiting it. A body monitoring callback can be set to report entering/exiting body shapes, and similarly an area monitoring callback can be set. Gravity and damping can be overridden within the area by setting area parameters.
+ - A [i]joint[/i] is a constraint, either between two bodies or on one body relative to a point. Parameters such as the joint bias and the rest length of a spring joint can be adjusted.
+ Physics objects in [PhysicsServer3D] may be created and manipulated independently; they do not have to be tied to nodes in the scene tree.
+ [b]Note:[/b] All the 3D physics nodes use the physics server internally. Adding a physics node to the scene tree will cause a corresponding physics object to be created in the physics server. A rigid body node registers a callback that updates the node's transform with the transform of the respective body object in the physics server (every physics update). An area node registers a callback to inform the area node about overlaps with the respective area object in the physics server. The raycast node queries the direct state of the relevant space in the physics server.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsServer3DExtension.xml b/doc/classes/PhysicsServer3DExtension.xml
index e6cce53594..cddf696554 100644
--- a/doc/classes/PhysicsServer3DExtension.xml
+++ b/doc/classes/PhysicsServer3DExtension.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer3DExtension" inherits="PhysicsServer3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides virtual methods that can be overridden to create custom [PhysicsServer3D] implementations.
</brief_description>
<description>
+ This class extends [PhysicsServer3D] by providing additional virtual methods that can be overridden. When these methods are overridden, they will be called instead of the internal methods of the physics server.
+ Intended for use with GDExtension to create custom implementations of [PhysicsServer3D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsServer3DManager.xml b/doc/classes/PhysicsServer3DManager.xml
index 33a45ca43a..fbc1111861 100644
--- a/doc/classes/PhysicsServer3DManager.xml
+++ b/doc/classes/PhysicsServer3DManager.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer3DManager" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Manager for 3D physics server implementations.
+ A singleton for managing [PhysicsServer3D] implementations.
</brief_description>
<description>
- [PhysicsServer3DManager] is the API for registering [PhysicsServer3D] implementations, and for setting the default implementation.
+ [PhysicsServer3DManager] is the API for registering [PhysicsServer3D] implementations and for setting the default implementation.
[b]Note:[/b] It is not possible to switch physics servers at runtime. This class is only used on startup at the server initialization level, by Godot itself and possibly by GDExtensions.
</description>
<tutorials>
diff --git a/doc/classes/PhysicsServer3DRenderingServerHandler.xml b/doc/classes/PhysicsServer3DRenderingServerHandler.xml
index d2a4ced0d7..11c82e0327 100644
--- a/doc/classes/PhysicsServer3DRenderingServerHandler.xml
+++ b/doc/classes/PhysicsServer3DRenderingServerHandler.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer3DRenderingServerHandler" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ A class used to provide [method PhysicsServer3DExtension._soft_body_update_rendering_server] with a rendering handler for soft bodies.
</brief_description>
<description>
</description>
diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml
index c133e6d403..fe4f902d75 100644
--- a/doc/classes/PhysicsShapeQueryParameters2D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsShapeQueryParameters2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 2D shape physics query.
+ Provides parameters for [method PhysicsDirectSpaceState2D.intersect_shape].
</brief_description>
<description>
- This class contains the shape and other parameters for [PhysicsDirectSpaceState2D] intersection/collision queries.
+ By changing various properties of this object, such as the shape, you can configure the parameters for [method PhysicsDirectSpaceState2D.intersect_shape].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml
index 7f3106174c..a8b443a6bd 100644
--- a/doc/classes/PhysicsShapeQueryParameters3D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsShapeQueryParameters3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 3D shape physics query.
+ Provides parameters for [method PhysicsDirectSpaceState3D.intersect_shape].
</brief_description>
<description>
- This class contains the shape and other parameters for [PhysicsDirectSpaceState3D] intersection/collision queries.
+ By changing various properties of this object, such as the shape, you can configure the parameters for [method PhysicsDirectSpaceState3D.intersect_shape].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsTestMotionParameters2D.xml b/doc/classes/PhysicsTestMotionParameters2D.xml
index ce9b425156..31394d188e 100644
--- a/doc/classes/PhysicsTestMotionParameters2D.xml
+++ b/doc/classes/PhysicsTestMotionParameters2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsTestMotionParameters2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 2D body motion test.
+ Provides parameters for [method PhysicsServer2D.body_test_motion].
</brief_description>
<description>
- This class contains parameters used in [method PhysicsServer2D.body_test_motion].
+ By changing various properties of this object, such as the motion, you can configure the parameters for [method PhysicsServer2D.body_test_motion].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsTestMotionParameters3D.xml b/doc/classes/PhysicsTestMotionParameters3D.xml
index 364b255519..a7c85c363c 100644
--- a/doc/classes/PhysicsTestMotionParameters3D.xml
+++ b/doc/classes/PhysicsTestMotionParameters3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsTestMotionParameters3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Parameters to be sent to a 3D body motion test.
+ Provides parameters for [method PhysicsServer3D.body_test_motion].
</brief_description>
<description>
- This class contains parameters used in [method PhysicsServer3D.body_test_motion].
+ By changing various properties of this object, such as the motion, you can configure the parameters for [method PhysicsServer3D.body_test_motion].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsTestMotionResult2D.xml b/doc/classes/PhysicsTestMotionResult2D.xml
index 63330a0674..db882889cc 100644
--- a/doc/classes/PhysicsTestMotionResult2D.xml
+++ b/doc/classes/PhysicsTestMotionResult2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsTestMotionResult2D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Result from a 2D body motion test.
+ Describes the motion and collision result from [method PhysicsServer2D.body_test_motion].
</brief_description>
<description>
- This class contains the motion and collision result from [method PhysicsServer2D.body_test_motion].
+ Describes the motion and collision result from [method PhysicsServer2D.body_test_motion].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PhysicsTestMotionResult3D.xml b/doc/classes/PhysicsTestMotionResult3D.xml
index 09020b772f..c15324c741 100644
--- a/doc/classes/PhysicsTestMotionResult3D.xml
+++ b/doc/classes/PhysicsTestMotionResult3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsTestMotionResult3D" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Result from a 3D body motion test.
+ Describes the motion and collision result from [method PhysicsServer3D.body_test_motion].
</brief_description>
<description>
- This class contains the motion and collision result from [method PhysicsServer3D.body_test_motion].
+ Describes the motion and collision result from [method PhysicsServer3D.body_test_motion].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PinJoint2D.xml b/doc/classes/PinJoint2D.xml
index b3e09594c7..8c3fd935c6 100644
--- a/doc/classes/PinJoint2D.xml
+++ b/doc/classes/PinJoint2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PinJoint2D" inherits="Joint2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Pin joint for 2D shapes.
+ A physics joint that attaches two 2D physics bodies at a single point, allowing them to freely rotate.
</brief_description>
<description>
- Pin joint for 2D rigid bodies. It pins two bodies (dynamic or static) together.
+ A physics joint that attaches two 2D physics bodies at a single point, allowing them to freely rotate. For example, a [RigidBody2D] can be attached to a [StaticBody2D] to create a pendulum or a seesaw.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PinJoint3D.xml b/doc/classes/PinJoint3D.xml
index 869d0e1d8b..c02c4c960f 100644
--- a/doc/classes/PinJoint3D.xml
+++ b/doc/classes/PinJoint3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PinJoint3D" inherits="Joint3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Pin joint for 3D PhysicsBodies.
+ A physics joint that attaches two 3D physics bodies at a single point, allowing them to freely rotate.
</brief_description>
<description>
- Pin joint for 3D rigid bodies. It pins 2 bodies (dynamic or static) together. See also [Generic6DOFJoint3D].
+ A physics joint that attaches two 2D physics bodies at a single point, allowing them to freely rotate. For example, a [RigidBody3D] can be attached to a [StaticBody3D] to create a pendulum or a seesaw.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index 6a048cfffd..fa29244c2a 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Plane" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Plane in hessian form.
+ A plane in Hessian normal form.
</brief_description>
<description>
- Plane represents a normalized plane equation. Basically, "normal" is the normal of the plane (a,b,c normalized), and "d" is the distance from the origin to the plane (in the direction of "normal"). "Over" or "Above" the plane is considered the side of the plane towards where the normal is pointing.
+ Represents a normalized plane equation. [member normal] is the normal of the plane (a, b, c normalized), and [member d] is the distance from the origin to the plane (in the direction of "normal"). "Over" or "Above" the plane is considered the side of the plane towards where the normal is pointing.
</description>
<tutorials>
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml
index 8c9abcf07a..cacf4ee7f2 100644
--- a/doc/classes/Popup.xml
+++ b/doc/classes/Popup.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Popup" inherits="Window" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Popup is a base window container for popup-like subwindows.
+ Base class for contextual windows and panels with fixed position.
</brief_description>
<description>
- Popup is a base window container for popup-like subwindows. It's a modal by default (see [member Window.popup_window]) and has helpers for custom popup behavior.
+ [Popup] is a base class for contextual windows and panels with fixed position. It's a modal by default (see [member Window.popup_window]) and provides methods for implementing custom popup behavior.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 2f1d4a528a..2b91236f56 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PopupMenu" inherits="Popup" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- PopupMenu displays a list of options.
+ A modal window used to display a list of options.
</brief_description>
<description>
- [PopupMenu] is a modal window used to display a list of options. They are popular in toolbars or context menus.
- The size of a [PopupMenu] can be limited by using [member Window.max_size]. If the height of the list of items is larger than the maximum height of the [PopupMenu], a [ScrollContainer] within the popup will allow the user to scroll the contents.
- If no maximum size is set, or if it is set to 0, the [PopupMenu] height will be limited by its parent rect.
- All [code]set_*[/code] methods allow negative item index, which makes the item accessed from the last one.
+ [PopupMenu] is a modal window used to display a list of options. Useful for toolbars and context menus.
+ The size of a [PopupMenu] can be limited by using [member Window.max_size]. If the height of the list of items is larger than the maximum height of the [PopupMenu], a [ScrollContainer] within the popup will allow the user to scroll the contents. If no maximum size is set, or if it is set to [code]0[/code], the [PopupMenu] height will be limited by its parent rect.
+ All [code]set_*[/code] methods allow negative item indices, i.e. [code]-1[/code] to access the last item, [code]-2[/code] to select the second-to-last item, and so on.
[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports searching within the list while the control is focused. Press a key that matches the first letter of an item's name to select the first item starting with the given letter. After that point, there are two ways to perform incremental search: 1) Press the same key again before the timeout duration to select the next item starting with the same letter. 2) Press letter keys that match the rest of the word before the timeout duration to match to select the item in question directly. Both of these actions will be reset to the beginning of the list if the timeout duration has passed since the last keystroke was registered. You can adjust the timeout duration by changing [member ProjectSettings.gui/timers/incremental_search_max_interval_msec].
[b]Note:[/b] The ID values used for items are limited to 32 bits, not full 64 bits of [int]. This has a range of [code]-2^32[/code] to [code]2^32 - 1[/code], i.e. [code]-2147483648[/code] to [code]2147483647[/code].
</description>
diff --git a/doc/classes/PopupPanel.xml b/doc/classes/PopupPanel.xml
index 2fe98281c1..a60d64e730 100644
--- a/doc/classes/PopupPanel.xml
+++ b/doc/classes/PopupPanel.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PopupPanel" inherits="Popup" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Class for displaying popups with a panel background.
+ A popup with a panel background.
</brief_description>
<description>
- Class for displaying popups with a panel background. In some cases it might be simpler to use than [Popup], since it provides a configurable background. If you are making windows, better check [Window].
- If any [Control] node is added as a child of this [PopupPanel], it will be stretched to fit the panel's size (similar to how [PanelContainer] works).
+ A popup with a configurable panel background. Any child controls added to this node will be stretched to fit the panel's size (similar to how [PanelContainer] works). If you are making windows, see [Window].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml
index 0e91181551..cf39fb4247 100644
--- a/doc/classes/ProgressBar.xml
+++ b/doc/classes/ProgressBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ProgressBar" inherits="Range" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- General-purpose progress bar.
+ A control used for visual representation of a percentage.
</brief_description>
<description>
- General-purpose progress bar. Shows fill percentage from right to left.
+ A control used for visual representation of a percentage. Shows fill percentage from right to left.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index add2faa962..7ee5fcba00 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ProjectSettings" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Contains global variables accessible from everywhere.
+ Stores globally-accessible variables.
</brief_description>
<description>
- Contains global variables accessible from everywhere. Use [method get_setting], [method set_setting] or [method has_setting] to access them. Variables stored in [code]project.godot[/code] are also loaded into ProjectSettings, making this object very useful for reading custom game configuration options.
+ Stores variables that can be accessed from everywhere. Use [method get_setting], [method set_setting] or [method has_setting] to access them. Variables stored in [code]project.godot[/code] are also loaded into [ProjectSettings], making this object very useful for reading custom game configuration options.
When naming a Project Settings property, use the full path to the setting including the category. For example, [code]"application/config/name"[/code] for the project name. Category and property names can be viewed in the Project Settings dialog.
[b]Feature tags:[/b] Project settings can be overridden for specific platforms and configurations (debug, release, ...) using [url=$DOCS_URL/tutorials/export/feature_tags.html]feature tags[/url].
[b]Overriding:[/b] Any project setting can be overridden by creating a file named [code]override.cfg[/code] in the project's root directory. This can also be used in exported projects by placing this file in the same directory as the project binary. Overriding will still take the base project settings' [url=$DOCS_URL/tutorials/export/feature_tags.html]feature tags[/url] in account. Therefore, make sure to [i]also[/i] override the setting with the desired feature tags if you want them to override base project settings on all platforms and configurations.
@@ -747,7 +747,7 @@
[b]Note:[/b] This setting is implemented only on macOS.
</member>
<member name="display/window/size/initial_position" type="Vector2i" setter="" getter="" default="Vector2i(0, 0)">
- Main window initial position (in virtual desktop coordinates), this settings is used only if [member display/window/size/initial_position_type] is set to "Absolute" ([code]0[/code]).
+ Main window initial position (in virtual desktop coordinates), this setting is used only if [member display/window/size/initial_position_type] is set to "Absolute" ([code]0[/code]).
</member>
<member name="display/window/size/initial_position_type" type="int" setter="" getter="" default="1">
Main window initial position.
@@ -756,7 +756,7 @@
[code]2[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set the screen.
</member>
<member name="display/window/size/initial_screen" type="int" setter="" getter="" default="0">
- Main window initial screen, this settings is used only if [member display/window/size/initial_position_type] is set to "Other Screen Center" ([code]2[/code]).
+ Main window initial screen, this setting is used only if [member display/window/size/initial_position_type] is set to "Other Screen Center" ([code]2[/code]).
</member>
<member name="display/window/size/mode" type="int" setter="" getter="" default="0">
Main window mode. See [enum DisplayServer.WindowMode] for possible values and how each mode behaves.
diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml
index f0ddc99efc..49392ce6f2 100644
--- a/doc/classes/Projection.xml
+++ b/doc/classes/Projection.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Projection" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 3D projection (4x4 matrix).
+ A 4×4 matrix for 3D projective transformations.
</brief_description>
<description>
A 4x4 matrix used for 3D projective transformations. It can represent transformations such as translation, rotation, scaling, shearing, and perspective division. It consists of four [Vector4] columns.
- For purely linear transformations (translation, rotation, and scale), it is recommended to use [Transform3D], as it is more performant and has a lower memory footprint.
+ For purely linear transformations (translation, rotation, and scale), it is recommended to use [Transform3D], as it is more performant and requires less memory.
Used internally as [Camera3D]'s projection matrix.
</description>
<tutorials>
diff --git a/doc/classes/RDPipelineColorBlendStateAttachment.xml b/doc/classes/RDPipelineColorBlendStateAttachment.xml
index 4892536814..783c8b1864 100644
--- a/doc/classes/RDPipelineColorBlendStateAttachment.xml
+++ b/doc/classes/RDPipelineColorBlendStateAttachment.xml
@@ -32,8 +32,8 @@
[codeblock]
var attachment = RDPipelineColorBlendStateAttachment.new()
attachment.enable_blend = true
- attachment.alpha_blend_op = RenderingDevice.BLEND_OP_SUBTRACT
- attachment.color_blend_op = RenderingDevice.BLEND_OP_SUBTRACT
+ attachment.alpha_blend_op = RenderingDevice.BLEND_OP_REVERSE_SUBTRACT
+ attachment.color_blend_op = RenderingDevice.BLEND_OP_REVERSE_SUBTRACT
attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA
attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE
attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA
diff --git a/doc/classes/RID.xml b/doc/classes/RID.xml
index dea55a32e5..907a322df8 100644
--- a/doc/classes/RID.xml
+++ b/doc/classes/RID.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RID" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Handle for a [Resource]'s unique ID.
+ A handle for a [Resource]'s unique identifier.
</brief_description>
<description>
The RID [Variant] type is used to access a low-level resource by its unique ID. RIDs are opaque, which means they do not grant access to the resource by themselves. They are used by the low-level server classes, such as [DisplayServer], [RenderingServer], [TextServer], etc.
diff --git a/doc/classes/RandomNumberGenerator.xml b/doc/classes/RandomNumberGenerator.xml
index c3ced76787..66b0f89023 100644
--- a/doc/classes/RandomNumberGenerator.xml
+++ b/doc/classes/RandomNumberGenerator.xml
@@ -1,18 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RandomNumberGenerator" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A class for generating pseudo-random numbers.
+ Provides methods for generating pseudo-random numbers.
</brief_description>
<description>
RandomNumberGenerator is a class for generating pseudo-random numbers. It currently uses [url=https://www.pcg-random.org/]PCG32[/url].
- [b]Note:[/b] The underlying algorithm is an implementation detail. As a result, it should not be depended upon for reproducible random streams across Godot versions.
+ [b]Note:[/b] The underlying algorithm is an implementation detail and should not be depended upon.
To generate a random float number (within a given range) based on a time-dependant seed:
[codeblock]
var rng = RandomNumberGenerator.new()
func _ready():
var my_random_number = rng.randf_range(-10.0, 10.0)
[/codeblock]
- [b]Note:[/b] The default values of [member seed] and [member state] properties are pseudo-random, and change when calling [method randomize]. The [code]0[/code] value documented here is a placeholder, and not the actual default seed.
</description>
<tutorials>
<link title="Random number generation">$DOCS_URL/tutorials/math/random_number_generation.html</link>
@@ -66,6 +65,7 @@
Initializes the random number generator state based on the given seed value. A given seed will give a reproducible sequence of pseudo-random numbers.
[b]Note:[/b] The RNG does not have an avalanche effect, and can output similar random streams given similar seeds. Consider using a hash function to improve your seed quality if they're sourced externally.
[b]Note:[/b] Setting this property produces a side effect of changing the internal [member state], so make sure to initialize the seed [i]before[/i] modifying the [member state]:
+ [b]Note:[/b] The default value of this property is pseudo-random, and changes when calling [method randomize]. The [code]0[/code] value documented here is a placeholder, and not the actual default seed.
[codeblock]
var rng = RandomNumberGenerator.new()
rng.seed = hash("Godot")
@@ -83,6 +83,7 @@
print(rng.randf()) # Prints the same value as in previous.
[/codeblock]
[b]Note:[/b] Do not set state to arbitrary values, since the random number generator requires the state to have certain qualities to behave properly. It should only be set to values that came from the state property itself. To initialize the random number generator with arbitrary input, use [member seed] instead.
+ [b]Note:[/b] The default value of this property is pseudo-random, and changes when calling [method randomize]. The [code]0[/code] value documented here is a placeholder, and not the actual default seed.
</member>
</members>
</class>
diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml
index 78489b30d0..a6b29f9e26 100644
--- a/doc/classes/Range.xml
+++ b/doc/classes/Range.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Range" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Abstract base class for range-based controls.
+ Abstract base class for controls that represent a number within a range.
</brief_description>
<description>
- Range is a base class for [Control] nodes that change a floating-point [member value] between a [member min_value] and [member max_value], using a configured [member step] and [member page] size. See e.g. [ScrollBar] and [Slider] for examples of higher level nodes using Range.
+ Range is an abstract base class for controls that represent a number within a range, using a configured [member step] and [member page] size. See e.g. [ScrollBar] and [Slider] for examples of higher-level nodes using Range.
</description>
<tutorials>
</tutorials>
@@ -45,26 +45,26 @@
If [code]true[/code], [member value] may be less than [member min_value].
</member>
<member name="exp_edit" type="bool" setter="set_exp_ratio" getter="is_ratio_exp" default="false">
- If [code]true[/code], and [code]min_value[/code] is greater than 0, [code]value[/code] will be represented exponentially rather than linearly.
+ If [code]true[/code], and [member min_value] is greater than 0, [member value] will be represented exponentially rather than linearly.
</member>
<member name="max_value" type="float" setter="set_max" getter="get_max" default="100.0">
- Maximum value. Range is clamped if [code]value[/code] is greater than [code]max_value[/code].
+ Maximum value. Range is clamped if [member value] is greater than [member max_value].
</member>
<member name="min_value" type="float" setter="set_min" getter="get_min" default="0.0">
- Minimum value. Range is clamped if [code]value[/code] is less than [code]min_value[/code].
+ Minimum value. Range is clamped if [member value] is less than [member min_value].
</member>
<member name="page" type="float" setter="set_page" getter="get_page" default="0.0">
- Page size. Used mainly for [ScrollBar]. ScrollBar's length is its size multiplied by [code]page[/code] over the difference between [code]min_value[/code] and [code]max_value[/code].
+ Page size. Used mainly for [ScrollBar]. ScrollBar's length is its size multiplied by [member page] over the difference between [member min_value] and [member max_value].
</member>
<member name="ratio" type="float" setter="set_as_ratio" getter="get_as_ratio">
The value mapped between 0 and 1.
</member>
<member name="rounded" type="bool" setter="set_use_rounded_values" getter="is_using_rounded_values" default="false">
- If [code]true[/code], [code]value[/code] will always be rounded to the nearest integer.
+ If [code]true[/code], [member value] will always be rounded to the nearest integer.
</member>
<member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="0" />
<member name="step" type="float" setter="set_step" getter="get_step" default="0.01">
- If greater than 0, [code]value[/code] will always be rounded to a multiple of [code]step[/code]. If [code]rounded[/code] is also [code]true[/code], [code]value[/code] will first be rounded to a multiple of [code]step[/code] then rounded to the nearest integer.
+ If greater than 0, [member value] will always be rounded to a multiple of this property's value. If [member rounded] is also [code]true[/code], [member value] will first be rounded to a multiple of this property's value, then rounded to the nearest integer.
</member>
<member name="value" type="float" setter="set_value" getter="get_value" default="0.0">
Range's current value. Changing this property (even via code) will trigger [signal value_changed] signal. Use [method set_value_no_signal] if you want to avoid it.
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index 266b2a38ae..bcf1e364e9 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RayCast2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Query the closest object intersecting a ray.
+ A ray in 2D space, used to find the first [CollisionObject2D] it intersects.
</brief_description>
<description>
- A RayCast represents a line from its origin to its destination position, [member target_position]. It is used to query the 2D space in order to find the closest object along the path of the ray.
- RayCast2D can ignore some objects by adding them to the exception list via [method add_exception], by setting proper filtering with collision layers, or by filtering object types with type masks.
- RayCast2D can be configured to report collisions with [Area2D]s ([member collide_with_areas]) and/or [PhysicsBody2D]s ([member collide_with_bodies]).
- Only enabled raycasts will be able to query the space and report collisions.
- RayCast2D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
+ A raycast represents a ray from its origin to its [member target_position] that finds the closest [CollisionObject2D] along its path, if it intersects any. This is useful for a lot of things, such as
+ [RayCast2D] can ignore some objects by adding them to an exception list, by making its detection reporting ignore [Area2D]s ([member collide_with_areas]) or [PhysicsBody2D]s ([member collide_with_bodies]), or by configuring physics layers.
+ [RayCast2D] calculates intersection every physics frame, and it holds the result until the next physics frame. For an immediate raycast, or if you want to configure a [RayCast2D] multiple times within the same physics frame, use [method force_raycast_update].
+ To sweep over a region of 2D space, you can approximate the region with multiple [RayCast2D]s or use [ShapeCast2D].
</description>
<tutorials>
<link title="Ray-casting">$DOCS_URL/tutorials/physics/ray-casting.html</link>
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index 2ebed77f35..fa2badb1db 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RayCast3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Query the closest object intersecting a ray.
+ A ray in 3D space, used to find the first [CollisionObject3D] it intersects.
</brief_description>
<description>
- A RayCast represents a line from its origin to its destination position, [member target_position]. It is used to query the 3D space in order to find the closest object along the path of the ray.
- RayCast3D can ignore some objects by adding them to the exception list via [method add_exception] or by setting proper filtering with collision layers and masks.
- RayCast3D can be configured to report collisions with [Area3D]s ([member collide_with_areas]) and/or [PhysicsBody3D]s ([member collide_with_bodies]).
- Only enabled raycasts will be able to query the space and report collisions.
- RayCast3D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame), use [method force_raycast_update] after adjusting the raycast.
+ A raycast represents a ray from its origin to its [member target_position] that finds the closest [CollisionObject3D] along its path, if it intersects any. This is useful for a lot of things, such as
+ [RayCast3D] can ignore some objects by adding them to an exception list, by making its detection reporting ignore [Area3D]s ([member collide_with_areas]) or [PhysicsBody3D]s ([member collide_with_bodies]), or by configuring physics layers.
+ [RayCast3D] calculates intersection every physics frame, and it holds the result until the next physics frame. For an immediate raycast, or if you want to configure a [RayCast3D] multiple times within the same physics frame, use [method force_raycast_update].
+ To sweep over a region of 3D space, you can approximate the region with multiple [RayCast3D]s or use [ShapeCast3D].
</description>
<tutorials>
<link title="Ray-casting">$DOCS_URL/tutorials/physics/ray-casting.html</link>
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index c402040c65..344db842be 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Rect2" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 2D axis-aligned bounding box using floating point coordinates.
+ A 2D axis-aligned bounding box using floating-point coordinates.
</brief_description>
<description>
[Rect2] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index ba20bb60e6..31e5879ab4 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Rect2i" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 2D axis-aligned bounding box using integer coordinates.
+ A 2D axis-aligned bounding box using integer coordinates.
</brief_description>
<description>
[Rect2i] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
diff --git a/doc/classes/RectangleShape2D.xml b/doc/classes/RectangleShape2D.xml
index 42e47eacac..5d0ccea297 100644
--- a/doc/classes/RectangleShape2D.xml
+++ b/doc/classes/RectangleShape2D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RectangleShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Rectangle shape resource for 2D physics.
+ A 2D rectangle shape used for physics collision.
</brief_description>
<description>
- 2D rectangle shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. This shape is useful for modeling box-like 2D objects.
- [b]Performance:[/b] Being a primitive collision shape, [RectangleShape2D] is fast to check collisions against (though not as fast as [CircleShape2D]).
+ A 2D rectangle shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D].
+ [b]Performance:[/b] [RectangleShape2D] is fast to check collisions against. It is faster than [CapsuleShape2D], but slower than [CircleShape2D].
</description>
<tutorials>
<link title="2D Pong Demo">https://godotengine.org/asset-library/asset/121</link>
diff --git a/doc/classes/ReferenceRect.xml b/doc/classes/ReferenceRect.xml
index 5272980099..fc6b6287f5 100644
--- a/doc/classes/ReferenceRect.xml
+++ b/doc/classes/ReferenceRect.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ReferenceRect" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Reference frame for GUI.
+ A rectangle hint for designing UIs.
</brief_description>
<description>
- A rectangle box that displays only a [member border_color] border color around its rectangle. [ReferenceRect] has no fill [Color]. If you need to display a rectangle filled with a solid color, consider using [ColorRect] instead.
+ A rectangle box that displays only a colored border around its rectangle. It is used to visualize the extents of a [Control].
</description>
<tutorials>
</tutorials>
<members>
<member name="border_color" type="Color" setter="set_border_color" getter="get_border_color" default="Color(1, 0, 0, 1)">
- Sets the border [Color] of the [ReferenceRect].
+ Sets the border color of the [ReferenceRect].
</member>
<member name="border_width" type="float" setter="set_border_width" getter="get_border_width" default="1.0">
Sets the border width of the [ReferenceRect]. The border grows both inwards and outwards with respect to the rectangle box.
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 98e2730740..26a7ae6aca 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -68,7 +68,7 @@
<param index="0" name="allow_draw_overlap" type="bool" default="false" />
<description>
Starts a list of compute commands created with the [code]compute_*[/code] methods. The returned value should be passed to other [code]compute_list_*[/code] functions.
- If [code]allow_draw_overlap[/code] is true, you may have one draw list running at the same time as one compute list. Multiple compute lists cannot be created at the same time; you must finish the previous compute list first using [method compute_list_end].
+ If [param allow_draw_overlap] is [code]true[/code], you may have one draw list running at the same time as one compute list. Multiple compute lists cannot be created at the same time; you must finish the previous compute list first using [method compute_list_end].
A simple compute operation might look like this (code is not a complete example):
[codeblock]
var rd = RenderingDevice.new()
@@ -368,7 +368,7 @@
<param index="1" name="view_count" type="int" default="1" />
<description>
Creates a new framebuffer format with the specified [param attachments] and [param view_count]. Returns the new framebuffer's unique framebuffer format ID.
- If [code]view_count[/code] is greater than or equal to [code]2[/code], enables multiview which is used for VR rendering. This requires support for the Vulkan multiview extension.
+ If [param view_count] is greater than or equal to [code]2[/code], enables multiview which is used for VR rendering. This requires support for the Vulkan multiview extension.
</description>
</method>
<method name="framebuffer_format_create_empty">
@@ -384,7 +384,7 @@
<param index="1" name="passes" type="RDFramebufferPass[]" />
<param index="2" name="view_count" type="int" default="1" />
<description>
- Creates a multipass framebuffer format with the specified [param attachments], [param passes] and [param view_count] and returns its ID. If [code]view_count[/code] is greater than or equal to [code]2[/code], enables multiview which is used for VR rendering. This requires support for the Vulkan multiview extension.
+ Creates a multipass framebuffer format with the specified [param attachments], [param passes] and [param view_count] and returns its ID. If [param view_count] is greater than or equal to [code]2[/code], enables multiview which is used for VR rendering. This requires support for the Vulkan multiview extension.
</description>
</method>
<method name="framebuffer_format_get_texture_samples">
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 59286acccc..4b0bdc5329 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -3622,7 +3622,7 @@
<param index="1" name="size" type="int" />
<param index="2" name="use_16_bits" type="bool" default="false" />
<description>
- Sets the [param size] of the shadow atlas's images (used for omni and spot lights) on the viewport specified by the [param viewport] RID. The value is rounded up to the nearest power of 2. If [code]use_16_bits[/code] is [code]true[/code], use 16 bits for the omni/spot shadow depth map. Enabling this results in shadows having less precision and may result in shadow acne, but can lead to performance improvements on some devices.
+ Sets the [param size] of the shadow atlas's images (used for omni and spot lights) on the viewport specified by the [param viewport] RID. The value is rounded up to the nearest power of 2. If [param use_16_bits] is [code]true[/code], use 16 bits for the omni/spot shadow depth map. Enabling this results in shadows having less precision and may result in shadow acne, but can lead to performance improvements on some devices.
[b]Note:[/b] If this is set to [code]0[/code], no positional shadows will be visible at all. This can improve performance significantly on low-end systems by reducing both the CPU and GPU load (as fewer draw calls are needed to draw the scene without shadows).
</description>
</method>
@@ -4030,10 +4030,10 @@
Array is a vertex color array.
</constant>
<constant name="ARRAY_TEX_UV" value="4" enum="ArrayType">
- Array is an UV coordinates array.
+ Array is a UV coordinates array.
</constant>
<constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType">
- Array is an UV coordinates array for the second set of UV coordinates.
+ Array is a UV coordinates array for the second set of UV coordinates.
</constant>
<constant name="ARRAY_CUSTOM0" value="6" enum="ArrayType">
Array is a custom data array for the first set of custom data.
@@ -4102,10 +4102,10 @@
Flag used to mark a vertex color array.
</constant>
<constant name="ARRAY_FORMAT_TEX_UV" value="16" enum="ArrayFormat" is_bitfield="true">
- Flag used to mark an UV coordinates array.
+ Flag used to mark a UV coordinates array.
</constant>
<constant name="ARRAY_FORMAT_TEX_UV2" value="32" enum="ArrayFormat" is_bitfield="true">
- Flag used to mark an UV coordinates array for the second UV coordinates.
+ Flag used to mark a UV coordinates array for the second UV coordinates.
</constant>
<constant name="ARRAY_FORMAT_CUSTOM0" value="64" enum="ArrayFormat" is_bitfield="true">
Flag used to mark an array of custom per-vertex data for the first set of custom data.
diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml
index 6f256ccaf6..7d2cb57421 100644
--- a/doc/classes/Resource.xml
+++ b/doc/classes/Resource.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Resource" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all resources.
+ Base class for serializable objects.
</brief_description>
<description>
Resource is the base class for all Godot-specific resource types, serving primarily as data containers. Since they inherit from [RefCounted], resources are reference-counted and freed when no longer in use. They can also be nested within other resources, and saved on disk. Once loaded from disk, further attempts to load a resource by [member resource_path] returns the same reference. [PackedScene], one of the most common [Object]s in a Godot project, is also a resource, uniquely capable of storing and instantiating the [Node]s it contains as many times as desired.
@@ -91,7 +91,7 @@
An optional name for this resource. When defined, its value is displayed to represent the resource in the Inspector dock. For built-in scripts, the name is displayed as part of the tab name in the script editor.
</member>
<member name="resource_path" type="String" setter="set_path" getter="get_path" default="&quot;&quot;">
- The unique path to this resource. If it has been saved to disk, the value will be its filepath. If the resource is exclusively contained within a scene, the value will be the [PackedScene]'s filepath, followed by an unique identifier.
+ The unique path to this resource. If it has been saved to disk, the value will be its filepath. If the resource is exclusively contained within a scene, the value will be the [PackedScene]'s filepath, followed by a unique identifier.
[b]Note:[/b] Setting this property manually may fail if a resource with the same path has already been previously loaded. If necessary, use [method take_over_path].
</member>
</members>
diff --git a/doc/classes/ResourceImporter.xml b/doc/classes/ResourceImporter.xml
index 9977e0e5bc..bafd6145f3 100644
--- a/doc/classes/ResourceImporter.xml
+++ b/doc/classes/ResourceImporter.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourceImporter" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for the implementation of core resource importers.
+ Base class for resource importers.
</brief_description>
<description>
- This is the base class for the resource importers implemented in core. To implement your own resource importers using editor plugins, see [EditorImportPlugin].
+ This is the base class for Godot's resource importers. To implement your own resource importers using editor plugins, see [EditorImportPlugin].
</description>
<tutorials>
<link title="Import plugins">$DOCS_URL/tutorials/plugins/editor/import_plugins.html</link>
diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml
index f804b5a25d..cf52f5017c 100644
--- a/doc/classes/ResourceLoader.xml
+++ b/doc/classes/ResourceLoader.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourceLoader" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Singleton used to load resource files.
+ A singleton for loading resource files.
</brief_description>
<description>
- Singleton used to load resource files from the filesystem.
+ A singleton used to load resource files from the filesystem.
It uses the many [ResourceFormatLoader] classes registered in the engine (either built-in or from a plugin) to load files into memory and convert them to a format that can be used by the engine.
[b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data].
</description>
diff --git a/doc/classes/ResourcePreloader.xml b/doc/classes/ResourcePreloader.xml
index 2128485c9a..16b2c13b47 100644
--- a/doc/classes/ResourcePreloader.xml
+++ b/doc/classes/ResourcePreloader.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourcePreloader" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Preloads a list of resources inside a scene.
+ A node used to preload sub-resources inside a scene.
</brief_description>
<description>
This node is used to preload sub-resources inside a scene, so when the scene is loaded, all the resources are ready to use and can be retrieved from the preloader. You can add the resources using the ResourcePreloader tab when the node is selected.
diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml
index d6ae8973f1..f173f34c5a 100644
--- a/doc/classes/ResourceSaver.xml
+++ b/doc/classes/ResourceSaver.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourceSaver" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Singleton for saving Godot-specific resource types.
+ A singleton for saving [Resource]s to the filesystem.
</brief_description>
<description>
- Singleton for saving Godot-specific resource types to the filesystem.
- It uses the many [ResourceFormatSaver] classes registered in the engine (either built-in or from a plugin) to save engine-specific resource data to text-based (e.g. [code].tres[/code] or [code].tscn[/code]) or binary files (e.g. [code].res[/code] or [code].scn[/code]).
+ A singleton for saving resource types to the filesystem.
+ It uses the many [ResourceFormatSaver] classes registered in the engine (either built-in or from a plugin) to save resource data to text-based (e.g. [code].tres[/code] or [code].tscn[/code]) or binary files (e.g. [code].res[/code] or [code].scn[/code]).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ResourceUID.xml b/doc/classes/ResourceUID.xml
index 0ff6620049..e3e18512ac 100644
--- a/doc/classes/ResourceUID.xml
+++ b/doc/classes/ResourceUID.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourceUID" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Singleton for managing a cache of resource UIDs within a project.
+ A singleton that manages the unique identifiers of all resources within a project.
</brief_description>
<description>
- Resources can not only be referenced using their resource paths [code]res://[/code], but alternatively through a unique identifier specified via [code]uid://[/code].
- Using UIDs allows for the engine to keep references between resources intact, even if the files get renamed or moved.
- This singleton is responsible for keeping track of all registered resource UIDs of a project, generating new UIDs and converting between the string and integer representation.
+ Resource UIDs (Unique IDentifiers) allow the engine to keep references between resources intact, even if files can renamed or moved. They can be accessed with [code]uid://[/code].
+ [ResourceUID] keeps track of all registered resource UIDs in a project, generates new UIDs, and converts between their string and integer representations.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index c33290e8a5..7d91987e7f 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RichTextEffect" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A custom effect for use with [RichTextLabel].
+ A custom effect for a [RichTextLabel].
</brief_description>
<description>
- A custom effect for use with [RichTextLabel].
+ A custom effect for a [RichTextLabel].
[b]Note:[/b] For a [RichTextEffect] to be usable, a BBCode tag must be defined as a member variable called [code]bbcode[/code] in the script.
[codeblocks]
[gdscript]
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 4a243a70ce..3b1d79af2a 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RichTextLabel" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Label that displays rich text.
+ A control for displaying text that can contain different font styles, images, and basic formatting.
</brief_description>
<description>
- Rich text can contain custom text, fonts, images and some basic formatting. The label manages these as an internal tag stack. It also adapts itself to given width/heights.
+ A control for displaying text that can contain custom fonts, images, and basic formatting. [RichTextLabel] manages these as an internal tag stack. It also adapts itself to given width/heights.
[b]Note:[/b] Assignments to [member text] clear the tag stack and reconstruct it from the property's contents. Any edits made to [member text] will erase previous edits made from other manual sources such as [method append_text] and the [code]push_*[/code] / [method pop] methods.
[b]Note:[/b] RichTextLabel doesn't support entangled BBCode tags. For example, instead of using [code][b]bold[i]bold italic[/b]italic[/i][/code], use [code][b]bold[i]bold italic[/i][/b][i]italic[/i][/code].
- [b]Note:[/b] [code]push_*/pop[/code] functions won't affect BBCode.
- [b]Note:[/b] Unlike [Label], RichTextLabel doesn't have a [i]property[/i] to horizontally align text to the center. Instead, enable [member bbcode_enabled] and surround the text in a [code][center][/code] tag as follows: [code][center]Example[/center][/code]. There is currently no built-in way to vertically align text either, but this can be emulated by relying on anchors/containers and the [member fit_content] property.
+ [b]Note:[/b] [code]push_*/pop_*[/code] functions won't affect BBCode.
+ [b]Note:[/b] Unlike [Label], [RichTextLabel] doesn't have a [i]property[/i] to horizontally align text to the center. Instead, enable [member bbcode_enabled] and surround the text in a [code][center][/code] tag as follows: [code][center]Example[/center][/code]. There is currently no built-in way to vertically align text either, but this can be emulated by relying on anchors/containers and the [member fit_content] property.
</description>
<tutorials>
<link title="BBCode in RichTextLabel">$DOCS_URL/tutorials/ui/bbcode_in_richtextlabel.html</link>
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index 24372e51e0..d9f0229359 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RigidBody2D" inherits="PhysicsBody2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics Body which is moved by 2D physics simulation. Useful for objects that have gravity and can be pushed by other objects.
+ A 2D physics body that is moved by a physics simulation.
</brief_description>
<description>
- This node implements simulated 2D physics. You do not control a RigidBody2D directly. Instead, you apply forces to it (gravity, impulses, etc.) and the physics simulation calculates the resulting movement based on its mass, friction, and other physical properties.
- You can switch the body's behavior using [member lock_rotation], [member freeze], and [member freeze_mode].
- [b]Note:[/b] You should not change a RigidBody2D's [code]position[/code] or [code]linear_velocity[/code] every frame or even very often. If you need to directly affect the body's state, use [method _integrate_forces], which allows you to directly access the physics state.
- Please also keep in mind that physics bodies manage their own transform which overwrites the ones you set. So any direct or indirect transformation (including scaling of the node or its parent) will be visible in the editor only, and immediately reset at runtime.
- If you need to override the default physics behavior or add a transformation at runtime, you can write a custom force integration. See [member custom_integrator].
+ [RigidBody2D] implements full 2D physics. It cannot be controlled directly, instead, you must apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate the resulting movement, rotation, react to collisions, and affect other physics bodies in its path.
+ The body's behavior can be adjusted via [member lock_rotation], [member freeze], and [member freeze_mode]. By changing various properties of the object, such as [member mass], you can control how the physics simulation acts on it.
+ A rigid body will always maintain its shape and size, even when forces are applied to it. It is useful for objects that can be interacted with in an environment, such as a tree that can be knocked over or a stack of crates that can be pushed around.
+ If you need to override the default physics behavior, you can write a custom force integration function. See [member custom_integrator].
+ [b]Note:[/b] Changing the 2D transform or [member linear_velocity] of a [RigidBody2D] very often may lead to some unpredictable behaviors. If you need to directly affect the body, prefer [method _integrate_forces] as it allows you to directly access the physics state.
</description>
<tutorials>
<link title="2D Physics Platformer Demo">https://godotengine.org/asset-library/asset/119</link>
diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml
index 3bd660d8dd..ee0648cd8b 100644
--- a/doc/classes/RigidBody3D.xml
+++ b/doc/classes/RigidBody3D.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RigidBody3D" inherits="PhysicsBody3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics Body which is moved by 3D physics simulation. Useful for objects that have gravity and can be pushed by other objects.
+ A 3D physics body that is moved by a physics simulation.
</brief_description>
<description>
- This is the node that implements full 3D physics. This means that you do not control a RigidBody3D directly. Instead, you can apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate the resulting movement, collision, bouncing, rotating, etc.
- You can switch the body's behavior using [member lock_rotation], [member freeze], and [member freeze_mode].
- [b]Note:[/b] Don't change a RigidBody3D's position every frame or very often. Sporadic changes work fine, but physics runs at a different granularity (fixed Hz) than usual rendering (process callback) and maybe even in a separate thread, so changing this from a process loop may result in strange behavior. If you need to directly affect the body's state, use [method _integrate_forces], which allows you to directly access the physics state.
+ [RigidBody3D] implements full 3D physics. It cannot be controlled directly, instead, you must apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate the resulting movement, rotation, react to collisions, and affect other physics bodies in its path.
+ The body's behavior can be adjusted via [member lock_rotation], [member freeze], and [member freeze_mode]. By changing various properties of the object, such as [member mass], you can control how the physics simulation acts on it.
+ A rigid body will always maintain its shape and size, even when forces are applied to it. It is useful for objects that can be interacted with in an environment, such as a tree that can be knocked over or a stack of crates that can be pushed around.
If you need to override the default physics behavior, you can write a custom force integration function. See [member custom_integrator].
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ [b]Note:[/b] Changing the 3D transform or [member linear_velocity] of a [RigidBody3D] very often may lead to some unpredictable behaviors. If you need to directly affect the body, prefer [method _integrate_forces] as it allows you to directly access the physics state.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/SceneState.xml b/doc/classes/SceneState.xml
index 6aeaf85a67..52586be162 100644
--- a/doc/classes/SceneState.xml
+++ b/doc/classes/SceneState.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SceneState" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A script interface to a scene file's data.
+ Provides access to a scene file's information.
</brief_description>
<description>
- Maintains a list of resources, nodes, exported, and overridden properties, and built-in scripts associated with a scene.
+ Maintains a list of resources, nodes, exported and overridden properties, and built-in scripts associated with a scene. They cannot be modified from a [SceneState], only accessed. Useful for peeking into what a [PackedScene] contains without instantiating it.
This class cannot be instantiated directly, it is retrieved for a given scene as the result of [method PackedScene.get_state].
</description>
<tutorials>
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
index 854c727f7b..b64e770dbc 100644
--- a/doc/classes/ScriptCreateDialog.xml
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ScriptCreateDialog" inherits="ConfirmationDialog" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- The Editor's popup dialog for creating new [Script] files.
+ Godot editor's popup dialog for creating new [Script] files.
</brief_description>
<description>
The [ScriptCreateDialog] creates script files according to a given template for a given scripting language. The standard use is to configure its fields prior to calling one of the [method Window.popup] methods.
diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml
index 9c9650bfef..98e6cf202b 100644
--- a/doc/classes/ScriptEditor.xml
+++ b/doc/classes/ScriptEditor.xml
@@ -4,6 +4,7 @@
Godot editor's script editor.
</brief_description>
<description>
+ Godot editor's script editor.
[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_script_editor].
</description>
<tutorials>
diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml
index 7020cd6af2..c1c12d366a 100644
--- a/doc/classes/ScriptEditorBase.xml
+++ b/doc/classes/ScriptEditorBase.xml
@@ -4,7 +4,7 @@
Base editor for editing scripts in the [ScriptEditor].
</brief_description>
<description>
- Base editor for editing scripts in the [ScriptEditor], this does not include documentation items.
+ Base editor for editing scripts in the [ScriptEditor]. This does not include documentation items.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ScrollBar.xml b/doc/classes/ScrollBar.xml
index e0d4f7cb43..3437f0e941 100644
--- a/doc/classes/ScrollBar.xml
+++ b/doc/classes/ScrollBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ScrollBar" inherits="Range" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for scroll bars.
+ Abstract base class for scrollbars.
</brief_description>
<description>
- Scrollbars are a [Range]-based [Control], that display a draggable area (the size of the page). Horizontal ([HScrollBar]) and Vertical ([VScrollBar]) versions are available.
+ Abstract base class for scrollbars, typically used to navigate through content that extends beyond the visible area of a control. Scrollbars are [Range]-based controls.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml
index cfc4ca6b4f..9026f4a5d0 100644
--- a/doc/classes/ScrollContainer.xml
+++ b/doc/classes/ScrollContainer.xml
@@ -1,15 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ScrollContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A helper node for displaying scrollable elements such as lists.
+ A container used to provide scrollbars to a child control when needed.
</brief_description>
<description>
- A ScrollContainer node meant to contain a [Control] child.
- ScrollContainers will automatically create a scrollbar child ([HScrollBar], [VScrollBar], or both) when needed and will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.custom_minimum_size] of the Control relative to the ScrollContainer.
- Works great with a [Panel] control. You can set [constant Control.SIZE_EXPAND] on the children's size flags, so they will upscale to the ScrollContainer's size if it's larger (scroll is invisible for the chosen dimension).
+ A container used to provide a child control with scrollbars when needed. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.custom_minimum_size] of the Control relative to the ScrollContainer.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="ensure_control_visible">
diff --git a/doc/classes/SegmentShape2D.xml b/doc/classes/SegmentShape2D.xml
index 2a775c3488..661235a177 100644
--- a/doc/classes/SegmentShape2D.xml
+++ b/doc/classes/SegmentShape2D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SegmentShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Segment shape resource for 2D physics.
+ A 2D line segment shape used for physics collision.
</brief_description>
<description>
- 2D segment shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. Consists of two points, [code]a[/code] and [code]b[/code].
- [b]Performance:[/b] Being a primitive collision shape, [SegmentShape2D] is fast to check collisions against (though not as fast as [CircleShape2D]).
+ A 2D line segment shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Semaphore.xml b/doc/classes/Semaphore.xml
index 32eb69fe8c..48a5da30f9 100644
--- a/doc/classes/Semaphore.xml
+++ b/doc/classes/Semaphore.xml
@@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Semaphore" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A synchronization semaphore.
+ A synchronization mechanism used to control access to a shared resource by [Thread]s.
</brief_description>
<description>
- A synchronization semaphore which can be used to synchronize multiple [Thread]s. Initialized to zero on creation. Be careful to avoid deadlocks. For a binary version, see [Mutex].
- [b]Warning:[/b]
- To guarantee that the operating system is able to perform proper cleanup (no crashes, no deadlocks), these conditions must be met:
- - By the time a [Semaphore]'s reference count reaches zero and therefore it is destroyed, no threads must be waiting on it.
- - By the time a [Thread]'s reference count reaches zero and therefore it is destroyed, it must not be waiting on any semaphore.
+ A synchronization semaphore that can be used to synchronize multiple [Thread]s. Initialized to zero on creation. For a binary version, see [Mutex].
+ [b]Warning:[/b] Semaphores must be used carefully to avoid deadlocks.
+ [b]Warning:[/b] To guarantee that the operating system is able to perform proper cleanup (no crashes, no deadlocks), these conditions must be met:
+ - When a [Semaphore]'s reference count reaches zero and it is therefore destroyed, no threads must be waiting on it.
+ - When a [Thread]'s reference count reaches zero and it is therefore destroyed, it must not be waiting on any semaphore.
</description>
<tutorials>
<link title="Using multiple threads">$DOCS_URL/tutorials/performance/using_multiple_threads.html</link>
+ <link title="Thread-safe APIs">$DOCS_URL/tutorials/performance/thread_safe_apis.html</link>
</tutorials>
<methods>
<method name="post">
diff --git a/doc/classes/SeparationRayShape2D.xml b/doc/classes/SeparationRayShape2D.xml
index 6d9e2000a4..a8440b5289 100644
--- a/doc/classes/SeparationRayShape2D.xml
+++ b/doc/classes/SeparationRayShape2D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SeparationRayShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Separation ray shape resource for 2D physics.
+ A 2D ray shape used for physics collision that tries to separate itself from any collider.
</brief_description>
<description>
- 2D separation ray shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. A ray is not really a collision body; instead, it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
- [b]Performance:[/b] Being a primitive collision shape, [SeparationRayShape2D] is fast to check collisions against.
+ A 2D ray shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D]. When a [SeparationRayShape2D] collides with an object, it tries to separate itself from it by moving its endpoint to the collision point. It can for example be used for spears falling from the sky.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SeparationRayShape3D.xml b/doc/classes/SeparationRayShape3D.xml
index ee85f49467..d8670e40d7 100644
--- a/doc/classes/SeparationRayShape3D.xml
+++ b/doc/classes/SeparationRayShape3D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SeparationRayShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Separation ray shape resource for 3D physics.
+ A 3D ray shape used for physics collision that tries to separate itself from any collider.
</brief_description>
<description>
- 3D separation ray shape to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node. A ray is not really a collision body; instead, it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
- [b]Performance:[/b] Being a primitive collision shape, [SeparationRayShape3D] is fast to check collisions against.
+ A 3D ray shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D]. When a [SeparationRayShape3D] collides with an object, it tries to separate itself from it by moving its endpoint to the collision point. It can for example be used for spears falling from the sky.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Separator.xml b/doc/classes/Separator.xml
index 212a38e389..4c393d1787 100644
--- a/doc/classes/Separator.xml
+++ b/doc/classes/Separator.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Separator" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for separators.
+ Abstract base class for separators.
</brief_description>
<description>
- Separator is a [Control] used for separating other controls. It's purely a visual decoration. Horizontal ([HSeparator]) and Vertical ([VSeparator]) versions are available.
+ Abstract base class for separators, used for separating other controls. [Separator]s are purely visual and normally drawn as a [StyleBoxLine].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Shape2D.xml b/doc/classes/Shape2D.xml
index f7f221ee7d..c1070b9cdd 100644
--- a/doc/classes/Shape2D.xml
+++ b/doc/classes/Shape2D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Shape2D" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all 2D shapes.
+ Abstract base class for 2D shapes used for physics collision.
</brief_description>
<description>
- Base class for all 2D shapes. All 2D shape types inherit from this.
+ Abstract base class for all 2D shapes, intended for use in physics.
+ [b]Performance:[/b] Primitive shapes, especially [CircleShape2D], are fast to check collisions against. [ConvexPolygonShape2D] is slower, and [ConcavePolygonShape2D] is the slowest.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/Shape3D.xml b/doc/classes/Shape3D.xml
index dee428ccad..cc9d77a581 100644
--- a/doc/classes/Shape3D.xml
+++ b/doc/classes/Shape3D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Shape3D" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all 3D shape resources.
+ Abstract base class for 3D shapes used for physics collision.
</brief_description>
<description>
- Base class for all 3D shape resources. Nodes that inherit from this can be used as shapes for a [PhysicsBody3D] or [Area3D] objects.
+ Abstract base class for all 3D shapes, intended for use in physics.
+ [b]Performance:[/b] Primitive shapes, especially [SphereShape3D], are fast to check collisions against. [ConvexPolygonShape3D] and [HeightMapShape3D] are slower, and [ConcavePolygonShape3D] is the slowest.
</description>
<tutorials>
<link title="Physics introduction">$DOCS_URL/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/ShapeCast2D.xml b/doc/classes/ShapeCast2D.xml
index 6a443248a9..6be5a39da1 100644
--- a/doc/classes/ShapeCast2D.xml
+++ b/doc/classes/ShapeCast2D.xml
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ShapeCast2D" inherits="Node2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node for physics collision sweep and immediate overlap queries. Similar to the [RayCast2D] node.
+ A 2D shape that sweeps a region of space to detect [CollisionObject2D]s.
</brief_description>
<description>
- Shape casting allows to detect collision objects by sweeping the [member shape] along the cast direction determined by [member target_position] (useful for things like beam weapons).
- Immediate collision overlaps can be done with the [member target_position] set to [code]Vector2(0, 0)[/code] and by calling [method force_shapecast_update] within the same [b]physics frame[/b]. This also helps to overcome some limitations of [Area2D] when used as a continuous detection area, often requiring waiting a couple of frames before collision information is available to [Area2D] nodes, and when using the signals creates unnecessary complexity.
- The node can detect multiple collision objects, but it's usually used to detect the first collision.
- [b]Note:[/b] shape casting is more computationally expensive compared to ray casting.
+ Shape casting allows to detect collision objects by sweeping its [member shape] along the cast direction determined by [member target_position]. This is similar to [RayCast2D], but it allows for sweeping a region of space, rather than just a straight line. [ShapeCast2D] can detect multiple collision objects. It is useful for things like wide laser beams or snapping a simple shape to a floor.
+ Immediate collision overlaps can be done with the [member target_position] set to [code]Vector2(0, 0)[/code] and by calling [method force_shapecast_update] within the same physics frame. This helps to overcome some limitations of [Area2D] when used as an instantaneous detection area, as collision information isn't immediately available to it.
+ [b]Note:[/b] Shape casting is more computationally expensive than ray casting.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ShapeCast3D.xml b/doc/classes/ShapeCast3D.xml
index 920529711f..e9b5877ed8 100644
--- a/doc/classes/ShapeCast3D.xml
+++ b/doc/classes/ShapeCast3D.xml
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ShapeCast3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Node for physics collision sweep and immediate overlap queries. Similar to the [RayCast3D] node.
+ A 3D shape that sweeps a region of space to detect [CollisionObject3D]s.
</brief_description>
<description>
- Shape casting allows to detect collision objects by sweeping the [member shape] along the cast direction determined by [member target_position] (useful for things like beam weapons).
- Immediate collision overlaps can be done with the [member target_position] set to [code]Vector3(0, 0, 0)[/code] and by calling [method force_shapecast_update] within the same [b]physics frame[/b]. This also helps to overcome some limitations of [Area3D] when used as a continuous detection area, often requiring waiting a couple of frames before collision information is available to [Area3D] nodes, and when using the signals creates unnecessary complexity.
- The node can detect multiple collision objects, but it's usually used to detect the first collision.
- [b]Note:[/b] Shape casting is more computationally expensive compared to ray casting.
+ Shape casting allows to detect collision objects by sweeping its [member shape] along the cast direction determined by [member target_position]. This is similar to [RayCast3D], but it allows for sweeping a region of space, rather than just a straight line. [ShapeCast3D] can detect multiple collision objects. It is useful for things like wide laser beams or snapping a simple shape to a floor.
+ Immediate collision overlaps can be done with the [member target_position] set to [code]Vector3(0, 0, 0)[/code] and by calling [method force_shapecast_update] within the same physics frame. This helps to overcome some limitations of [Area3D] when used as an instantaneous detection area, as collision information isn't immediately available to it.
+ [b]Note:[/b] Shape casting is more computationally expensive than ray casting.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml
index 79a009e00e..ada533153c 100644
--- a/doc/classes/Signal.xml
+++ b/doc/classes/Signal.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Signal" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Built-in type representing a signal defined in an object.
+ A built-in type representing a signal of an [Object].
</brief_description>
<description>
[Signal] is a built-in [Variant] type that represents a signal of an [Object] instance. Like all [Variant] types, it can be stored in variables and passed to functions. Signals allow all connected [Callable]s (and by extension their respective objects) to listen and react to events, without directly referencing one another. This keeps the code flexible and easier to manage.
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml
index 8f40c63104..d410c5840c 100644
--- a/doc/classes/Skeleton3D.xml
+++ b/doc/classes/Skeleton3D.xml
@@ -5,8 +5,8 @@
</brief_description>
<description>
[Skeleton3D] provides an interface for managing a hierarchy of bones, including pose, rest and animation (see [Animation]). It can also use ragdoll physics.
- The overall transform of a bone with respect to the skeleton is determined by the following hierarchical order: rest pose, custom pose and pose.
- Note that "global pose" below refers to the overall transform of the bone with respect to skeleton, so it not the actual global/world transform of the bone.
+ The overall transform of a bone with respect to the skeleton is determined by bone pose. Bone rest defines the initial transform of the bone pose.
+ Note that "global pose" below refers to the overall transform of the bone with respect to skeleton, so it is not the actual global/world transform of the bone.
To setup different types of inverse kinematics, consider using [SkeletonIK3D], or add a custom IK implementation in [method Node._process] as a child node.
</description>
<tutorials>
@@ -118,7 +118,7 @@
<return type="Transform3D" />
<param index="0" name="bone_idx" type="int" />
<description>
- Returns the pose transform of the specified bone. Pose is applied on top of the custom pose, which is applied on top the rest pose.
+ Returns the pose transform of the specified bone.
</description>
</method>
<method name="get_bone_pose_position" qualifiers="const">
diff --git a/doc/classes/Slider.xml b/doc/classes/Slider.xml
index 802b02cab1..fa5cdeb5c5 100644
--- a/doc/classes/Slider.xml
+++ b/doc/classes/Slider.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Slider" inherits="Range" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for GUI sliders.
+ Abstract base class for sliders.
</brief_description>
<description>
- Base class for GUI sliders.
- [b]Note:[/b] The [signal Range.changed] and [signal Range.value_changed] signals are part of the [Range] class which this class inherits from.
+ Abstract base class for sliders, used to adjust a value by moving a grabber along a horizontal or vertical axis. Sliders are [Range]-based controls.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SliderJoint3D.xml b/doc/classes/SliderJoint3D.xml
index f44bc6650d..11e38878e9 100644
--- a/doc/classes/SliderJoint3D.xml
+++ b/doc/classes/SliderJoint3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SliderJoint3D" inherits="Joint3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Slider between two PhysicsBodies in 3D.
+ A physics joint that restricts the movement of a 3D physics body along an axis relative to another physics body.
</brief_description>
<description>
- Slides across the X axis of the pivot object. See also [Generic6DOFJoint3D].
+ A physics joint that restricts the movement of a 3D physics body along an axis relative to another physics body. For example, Body A could be a [StaticBody3D] representing a piston base, while Body B could be a [RigidBody3D] representing the piston head, moving up and down.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml
index bbf51114bd..ee390995a9 100644
--- a/doc/classes/SoftBody3D.xml
+++ b/doc/classes/SoftBody3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SoftBody3D" inherits="MeshInstance3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A soft mesh physics body.
+ A deformable 3D physics mesh.
</brief_description>
<description>
- A deformable physics body. Used to create elastic or deformable objects such as cloth, rubber, or other flexible materials.
- [b]Note:[/b] There are many known bugs in [SoftBody3D]. Therefore, it's not recommended to use them for things that can affect gameplay (such as a player character made entirely out of soft bodies).
+ A deformable 3D physics mesh. Used to create elastic or deformable objects such as cloth, rubber, or other flexible materials.
+ [b]Note:[/b] There are many known bugs in [SoftBody3D]. Therefore, it's not recommended to use them for things that can affect gameplay (such as trampolines).
</description>
<tutorials>
<link title="SoftBody">$DOCS_URL/tutorials/physics/soft_body.html</link>
diff --git a/doc/classes/SphereShape3D.xml b/doc/classes/SphereShape3D.xml
index 32f56dd47d..69ddb4fb5e 100644
--- a/doc/classes/SphereShape3D.xml
+++ b/doc/classes/SphereShape3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SphereShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Sphere shape resource for 3D collisions.
+ A 3D sphere shape used for physics collision.
</brief_description>
<description>
- 3D sphere shape to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node. This shape is useful for modeling sphere-like 3D objects.
- [b]Performance:[/b] Being a primitive collision shape, [SphereShape3D] is the fastest collision shape to check collisions against, as it only requires a distance check with the shape's origin.
+ A 3D sphere shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
+ [b]Performance:[/b] [SphereShape3D] is fast to check collisions against. It is faster than [BoxShape3D], [CapsuleShape3D], and [CylinderShape3D].
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml
index 26e1578150..8fbd97e78b 100644
--- a/doc/classes/SpinBox.xml
+++ b/doc/classes/SpinBox.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SpinBox" inherits="Range" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Numerical input text field.
+ An input field for numbers.
</brief_description>
<description>
- SpinBox is a numerical input text field. It allows entering integers and floats.
+ [SpinBox] is a numerical input text field. It allows entering integers and floating point numbers.
[b]Example:[/b]
[codeblocks]
[gdscript]
diff --git a/doc/classes/SplitContainer.xml b/doc/classes/SplitContainer.xml
index b7ca8f8cbe..a75203c8e3 100644
--- a/doc/classes/SplitContainer.xml
+++ b/doc/classes/SplitContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SplitContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Container for splitting and adjusting.
+ A container that splits two child controls horizontally or vertically and provides a grabber for adjusting the split ratio.
</brief_description>
<description>
- Container for splitting two [Control]s vertically or horizontally, with a grabber that allows adjusting the split offset or ratio.
+ A container that accepts only two child controls, then arranges them horizontally or vertically and creates a divisor between them. The divisor can be dragged around to change the size relation between the child controls.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="clamp_split_offset">
diff --git a/doc/classes/SpringArm3D.xml b/doc/classes/SpringArm3D.xml
index c9b8e00d40..61135fc9d0 100644
--- a/doc/classes/SpringArm3D.xml
+++ b/doc/classes/SpringArm3D.xml
@@ -1,13 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SpringArm3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- A helper node, mostly used in 3rd person cameras.
+ A 3D raycast that dynamically moves its children near the collision point.
</brief_description>
<description>
- The SpringArm3D node is a node that casts a ray (or collision shape) along its z axis and moves all its direct children to the collision point, minus a margin.
- The most common use case for this is to make a 3rd person camera that reacts to collisions in the environment.
- The SpringArm3D will either cast a ray, or if a shape is given, it will cast the shape in the direction of its z axis.
- If you use the SpringArm3D as a camera controller for your player, you might need to exclude the player's collider from the SpringArm3D's collision check.
+ [SpringArm3D] casts a ray or a shape along its Z axis and moves all its direct children to the collision point, with an optional margin. This is useful for 3rd person cameras that move closer to the player when inside a tight space (you may need to exclude the player's collider from the [SpringArm3D]'s collision check.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/StaticBody2D.xml b/doc/classes/StaticBody2D.xml
index 46c4f4fbb4..571b9e4307 100644
--- a/doc/classes/StaticBody2D.xml
+++ b/doc/classes/StaticBody2D.xml
@@ -1,14 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StaticBody2D" inherits="PhysicsBody2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics body for 2D physics which is static or moves only by script (without affecting other bodies on its path). Useful for floors and walls.
+ A 2D physics body that can't be moved by external forces. When moved manually, it doesn't affect other bodies in its path.
</brief_description>
<description>
- Static body for 2D physics.
- A static body is a simple body that doesn't move under physics simulation, i.e. it can't be moved by external forces or contacts but its transformation can still be updated manually by the user. It is ideal for implementing objects in the environment, such as walls or platforms. In contrast to [RigidBody2D], it doesn't consume any CPU resources as long as they don't move.
- They have extra functionalities to move and affect other bodies:
- [b]Static transform change:[/b] Static bodies [i]can[/i] be moved by animation or script. In this case, they are just teleported and don't affect other bodies on their path. Use [AnimatableBody2D] instead of [StaticBody2D] if you need a moving static body that affects other bodies on its path.
- [b]Constant velocity:[/b] When [member constant_linear_velocity] or [member constant_angular_velocity] is set, static bodies don't move themselves but affect touching bodies as if they were moving. This is useful for simulating conveyor belts or conveyor wheels.
+ A static 2D physics body. It can't be moved by external forces or contacts, but can be moved manually by other means such as code, [AnimationPlayer]s (with [member AnimationPlayer.playback_process_mode] set to [code]ANIMATION_PROCESS_PHYSICS[/code]), and [RemoteTransform2D].
+ When [StaticBody2D] is moved, it is teleported to its new position without affecting other physics bodies in its path. If this is not desired, use [AnimatableBody2D] instead.
+ [StaticBody2D] is useful for completely static objects like floors and walls, as well as moving surfaces like conveyor belts and circular revolving platforms (by using [member constant_linear_velocity] and [member constant_angular_velocity]).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/StaticBody3D.xml b/doc/classes/StaticBody3D.xml
index 82001fc972..7b2d15a5e4 100644
--- a/doc/classes/StaticBody3D.xml
+++ b/doc/classes/StaticBody3D.xml
@@ -1,15 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StaticBody3D" inherits="PhysicsBody3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics body for 3D physics which is static or moves only by script (without affecting other bodies on its path). Useful for floors and walls.
+ A 3D physics body that can't be moved by external forces. When moved manually, it doesn't affect other bodies in its path.
</brief_description>
<description>
- Static body for 3D physics.
- A static body is a simple body that doesn't move under physics simulation, i.e. it can't be moved by external forces or contacts but its transformation can still be updated manually by the user. It is ideal for implementing objects in the environment, such as walls or platforms. In contrast to [RigidBody3D], it doesn't consume any CPU resources as long as they don't move.
- They have extra functionalities to move and affect other bodies:
- [b]Static transform change:[/b] Static bodies [i]can[/i] be moved by animation or script. In this case, they are just teleported and don't affect other bodies on their path. Use [AnimatableBody3D] instead of [StaticBody3D] if you need a moving static body that affects other bodies on its path.
- [b]Constant velocity:[/b] When [member constant_linear_velocity] or [member constant_angular_velocity] is set, static bodies don't move themselves but affect touching bodies as if they were moving. This is useful for simulating conveyor belts or conveyor wheels.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ A static 3D physics body. It can't be moved by external forces or contacts, but can be moved manually by other means such as code, [AnimationPlayer]s (with [member AnimationPlayer.playback_process_mode] set to [code]ANIMATION_PROCESS_PHYSICS[/code]), and [RemoteTransform3D].
+ When [StaticBody3D] is moved, it is teleported to its new position without affecting other physics bodies in its path. If this is not desired, use [AnimatableBody3D] instead.
+ [StaticBody3D] is useful for completely static objects like floors and walls, as well as moving surfaces like conveyor belts and circular revolving platforms (by using [member constant_linear_velocity] and [member constant_angular_velocity]).
</description>
<tutorials>
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml
index c293f4ba5f..d754c9c73c 100644
--- a/doc/classes/StreamPeer.xml
+++ b/doc/classes/StreamPeer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeer" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Abstraction and base class for stream-based protocols.
+ Abstract base class for interacting with streams.
</brief_description>
<description>
- StreamPeer is an abstraction and base class for stream-based protocols (such as TCP). It provides an API for sending and receiving data through streams as raw data or strings.
+ StreamPeer is an abstract base class mostly used for stream-based protocols (such as TCP). It provides an API for sending and receiving data through streams as raw data or strings.
[b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android.
</description>
<tutorials>
@@ -101,7 +101,7 @@
<return type="String" />
<param index="0" name="bytes" type="int" default="-1" />
<description>
- Gets an UTF-8 string with byte-length [param bytes] from the stream (this decodes the string sent as UTF-8). If [param bytes] is negative (default) the length will be read from the stream using the reverse process of [method put_utf8_string].
+ Gets a UTF-8 string with byte-length [param bytes] from the stream (this decodes the string sent as UTF-8). If [param bytes] is negative (default) the length will be read from the stream using the reverse process of [method put_utf8_string].
</description>
</method>
<method name="get_var">
@@ -218,7 +218,7 @@
<param index="0" name="value" type="String" />
<description>
Puts a zero-terminated UTF-8 string into the stream prepended by a 32 bits unsigned integer representing its size.
- [b]Note:[/b] To put an UTF-8 string without prepending its size, you can use [method put_data]:
+ [b]Note:[/b] To put a UTF-8 string without prepending its size, you can use [method put_data]:
[codeblocks]
[gdscript]
put_data("Hello world".to_utf8_buffer())
diff --git a/doc/classes/StreamPeerBuffer.xml b/doc/classes/StreamPeerBuffer.xml
index 608e1b678f..a947edea81 100644
--- a/doc/classes/StreamPeerBuffer.xml
+++ b/doc/classes/StreamPeerBuffer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeerBuffer" inherits="StreamPeer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Data buffer stream peer.
+ A stream peer used to handle binary data streams.
</brief_description>
<description>
- Data buffer stream peer that uses a byte array as the stream. This object can be used to handle binary data from network sessions. To handle binary data stored in files, [FileAccess] can be used directly.
+ A data buffer stream peer that uses a byte array as the stream. This object can be used to handle binary data from network sessions. To handle binary data stored in files, [FileAccess] can be used directly.
A [StreamPeerBuffer] object keeps an internal cursor which is the offset in bytes to the start of the buffer. Get and put operations are performed at the cursor position and will move the cursor accordingly.
</description>
<tutorials>
diff --git a/doc/classes/StreamPeerGZIP.xml b/doc/classes/StreamPeerGZIP.xml
index 59fd10ebb8..7166b57f58 100644
--- a/doc/classes/StreamPeerGZIP.xml
+++ b/doc/classes/StreamPeerGZIP.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeerGZIP" inherits="StreamPeer" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Stream peer handling GZIP and deflate compression/decompresison.
+ A stream peer that handles GZIP and deflate compression/decompression.
</brief_description>
<description>
- This class allows to compress or decompress data using GZIP/deflate in a streaming fashion. This is particularly useful when compressing or decompressing files that has to be sent through the network without having to allocate them all in memory.
+ This class allows to compress or decompress data using GZIP/deflate in a streaming fashion. This is particularly useful when compressing or decompressing files that have to be sent through the network without needing to allocate them all in memory.
After starting the stream via [method start_compression] (or [method start_decompression]), calling [method StreamPeer.put_partial_data] on this stream will compress (or decompress) the data, writing it to the internal buffer. Calling [method StreamPeer.get_available_bytes] will return the pending bytes in the internal buffer, and [method StreamPeer.get_partial_data] will retrieve the compressed (or decompressed) bytes from it. When the stream is over, you must call [method finish] to ensure the internal buffer is properly flushed (make sure to call [method StreamPeer.get_available_bytes] on last time to check if more data needs to be read after that).
</description>
<tutorials>
diff --git a/doc/classes/StreamPeerTCP.xml b/doc/classes/StreamPeerTCP.xml
index c89daeb4b5..209e178df2 100644
--- a/doc/classes/StreamPeerTCP.xml
+++ b/doc/classes/StreamPeerTCP.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeerTCP" inherits="StreamPeer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- TCP stream peer.
+ A stream peer that handles TCP connections.
</brief_description>
<description>
- TCP stream peer. This object can be used to connect to TCP servers, or also is returned by a TCP server.
+ A stream peer that handles TCP connections. This object can be used to connect to TCP servers, or also is returned by a TCP server.
[b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android.
</description>
<tutorials>
diff --git a/doc/classes/StreamPeerTLS.xml b/doc/classes/StreamPeerTLS.xml
index 8cf0b646a5..ca402f7caa 100644
--- a/doc/classes/StreamPeerTLS.xml
+++ b/doc/classes/StreamPeerTLS.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeerTLS" inherits="StreamPeer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- TLS stream peer.
+ A stream peer that handles TLS connections.
</brief_description>
<description>
- TLS stream peer. This object can be used to connect to a TLS server or accept a single TLS client connection.
+ A stream peer that handles TLS connections. This object can be used to connect to a TLS server or accept a single TLS client connection.
[b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android.
</description>
<tutorials>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index d1bc24db13..cc78f46b08 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="String" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Built-in string Variant type.
+ A built-in type for strings.
</brief_description>
<description>
This is the built-in string Variant type (and the one used by GDScript). Strings may contain any number of Unicode characters, and expose methods useful for manipulating and generating strings. Strings are reference-counted and use a copy-on-write approach (every modification to a string returns a new [String]), so passing them around is cheap in resources.
@@ -180,7 +180,7 @@
<param index="0" name="position" type="int" />
<param index="1" name="chars" type="int" default="1" />
<description>
- Returns a string with [param chars] characters erased starting from [param position]. If [param chars] goes beyond the string's length given the specified [param position], fewer characters will be erased from the returned string. Returns an empty string if either [code]position[/code] or [code]chars[/code] is negative. Returns the original string unmodified if [param chars] is [code]0[/code].
+ Returns a string with [param chars] characters erased starting from [param position]. If [param chars] goes beyond the string's length given the specified [param position], fewer characters will be erased from the returned string. Returns an empty string if either [param position] or [param chars] is negative. Returns the original string unmodified if [param chars] is [code]0[/code].
</description>
</method>
<method name="find" qualifiers="const">
diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml
index 3d3ac6e91f..a8b9ee5f3d 100644
--- a/doc/classes/StringName.xml
+++ b/doc/classes/StringName.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StringName" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- An optimized string type for unique names.
+ A built-in type for unique strings.
</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.
+ [StringName]s are immutable strings designed for general-purpose representation of unique names (also called "string interning"). Two [StringName]s with the same value are the same object. Comparing them is extremely fast compared to regular [String]s.
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.
+ See also [NodePath], which is a similar concept specifically designed to store pre-parsed scene tree paths.
+ All of [String]'s methods are available in this class too. They convert the [StringName] into a string, and they also return a string. This is highly inefficient and should only be used if the string is desired.
[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].
</description>
<tutorials>
@@ -163,7 +163,7 @@
<param index="0" name="position" type="int" />
<param index="1" name="chars" type="int" default="1" />
<description>
- Returns a string with [param chars] characters erased starting from [param position]. If [param chars] goes beyond the string's length given the specified [param position], fewer characters will be erased from the returned string. Returns an empty string if either [code]position[/code] or [code]chars[/code] is negative. Returns the original string unmodified if [param chars] is [code]0[/code].
+ Returns a string with [param chars] characters erased starting from [param position]. If [param chars] goes beyond the string's length given the specified [param position], fewer characters will be erased from the returned string. Returns an empty string if either [param position] or [param chars] is negative. Returns the original string unmodified if [param chars] is [code]0[/code].
</description>
</method>
<method name="find" qualifiers="const">
diff --git a/doc/classes/StyleBox.xml b/doc/classes/StyleBox.xml
index 8675c46d68..c4aeb59f22 100644
--- a/doc/classes/StyleBox.xml
+++ b/doc/classes/StyleBox.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StyleBox" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for drawing stylized boxes for the UI.
+ Abstract base class for defining stylized boxes for UI elements.
</brief_description>
<description>
- StyleBox is [Resource] that provides an abstract base class for drawing stylized boxes for the UI. StyleBoxes are used for drawing the styles of buttons, line edit backgrounds, tree backgrounds, etc. and also for testing a transparency mask for pointer signals. If mask test fails on a StyleBox assigned as mask to a control, clicks and motion signals will go through it to the one below.
- [b]Note:[/b] For children of [Control] that have [i]Theme Properties[/i], the [code]focus[/code] [StyleBox] is displayed over the [code]normal[/code], [code]hover[/code] or [code]pressed[/code] [StyleBox]. This makes the [code]focus[/code] [StyleBox] more reusable across different nodes.
+ [StyleBox] is an abstract base class for drawing stylized boxes for UI elements. It is used for panels, buttons, [LineEdit] backgrounds, [Tree] backgrounds, etc. and also for testing a transparency mask for pointer signals. If mask test fails on a [StyleBox] assigned as mask to a control, clicks and motion signals will go through it to the one below.
+ [b]Note:[/b] For control nodes that have [i]Theme Properties[/i], the [code]focus[/code] [StyleBox] is displayed over the [code]normal[/code], [code]hover[/code] or [code]pressed[/code] [StyleBox]. This makes the [code]focus[/code] [StyleBox] more reusable across different nodes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/StyleBoxEmpty.xml b/doc/classes/StyleBoxEmpty.xml
index 8a88e459b3..253cf7b4af 100644
--- a/doc/classes/StyleBoxEmpty.xml
+++ b/doc/classes/StyleBoxEmpty.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StyleBoxEmpty" inherits="StyleBox" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Empty stylebox (does not display anything).
+ An empty [StyleBox] (does not display anything).
</brief_description>
<description>
- Empty stylebox (really does not display anything).
+ An empty [StyleBox] that can be used to display nothing instead of the default style (e.g. it can "disable" [code]focus[/code] styles).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml
index d5ab282037..be026b9ff2 100644
--- a/doc/classes/StyleBoxFlat.xml
+++ b/doc/classes/StyleBoxFlat.xml
@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StyleBoxFlat" inherits="StyleBox" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Customizable [StyleBox] with a given set of parameters (no texture required).
+ A customizable [StyleBox] that doesn't use a texture.
</brief_description>
<description>
- This [StyleBox] can be used to achieve all kinds of looks without the need of a texture. The following properties are customizable:
- - Color
- - Border width (individual width for each border)
- - Rounded corners (individual radius for each corner)
- - Shadow (with blur and offset)
+ By configuring various properties of this style box, you can achieve many common looks without the need of a texture. This includes optionally rounded borders, antialiasing, shadows, and skew.
Setting corner radius to high values is allowed. As soon as corners overlap, the stylebox will switch to a relative system.
[b]Example:[/b]
[codeblock]
diff --git a/doc/classes/StyleBoxLine.xml b/doc/classes/StyleBoxLine.xml
index 06bbaf18c2..e2351b948f 100644
--- a/doc/classes/StyleBoxLine.xml
+++ b/doc/classes/StyleBoxLine.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StyleBoxLine" inherits="StyleBox" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- [StyleBox] that displays a single line.
+ A [StyleBox] that displays a single line of a given color and thickness.
</brief_description>
<description>
- [StyleBox] that displays a single line of a given color and thickness. It can be used to draw things like separators.
+ A [StyleBox] that displays a single line of a given color and thickness. The line can be either horizontal or vertical. Useful for separators.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml
index d5a3c7d2ea..8b8598df9f 100644
--- a/doc/classes/StyleBoxTexture.xml
+++ b/doc/classes/StyleBoxTexture.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StyleBoxTexture" inherits="StyleBox" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Texture-based nine-patch [StyleBox].
+ A texture-based nine-patch [StyleBox].
</brief_description>
<description>
- Texture-based nine-patch [StyleBox], in a way similar to [NinePatchRect]. This stylebox performs a 3×3 scaling of a texture, where only the center cell is fully stretched. This makes it possible to design bordered styles regardless of the stylebox's size.
+ A texture-based nine-patch [StyleBox], in a way similar to [NinePatchRect]. This stylebox performs a 3×3 scaling of a texture, where only the center cell is fully stretched. This makes it possible to design bordered styles regardless of the stylebox's size.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml
index d90290da73..b6fded5621 100644
--- a/doc/classes/SubViewport.xml
+++ b/doc/classes/SubViewport.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SubViewport" inherits="Viewport" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Creates a sub-view into the screen.
+ An interface to a game world that doesn't create a window or draw to the screen directly.
</brief_description>
<description>
- [SubViewport] is a [Viewport] that isn't a [Window], i.e. it doesn't draw anything by itself. To display something, [SubViewport]'s [member size] must be non-zero and it should be either put inside a [SubViewportContainer] or assigned to a [ViewportTexture].
+ [SubViewport] Isolates a rectangular region of a scene to be displayed independently. This can be used, for example, to display UI in 3D space.
+ [b]Note:[/b] [SubViewport] is a [Viewport] that isn't a [Window], i.e. it doesn't draw anything by itself. To display anything, [SubViewport] must have a non-zero size and be either put inside a [SubViewportContainer] or assigned to a [ViewportTexture].
</description>
<tutorials>
<link title="Using Viewports">$DOCS_URL/tutorials/rendering/viewports.html</link>
diff --git a/doc/classes/SubViewportContainer.xml b/doc/classes/SubViewportContainer.xml
index 6bb038ecc1..64f62d53d8 100644
--- a/doc/classes/SubViewportContainer.xml
+++ b/doc/classes/SubViewportContainer.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SubViewportContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control for holding [SubViewport]s.
+ A container used for displaying the contents of a [SubViewport].
</brief_description>
<description>
- A [Container] node that holds a [SubViewport]. It uses the [SubViewport]'s size as minimum size, unless [member stretch] is enabled.
- [b]Note:[/b] Changing a SubViewportContainer's [member Control.scale] will cause its contents to appear distorted. To change its visual size without causing distortion, adjust the node's margins instead (if it's not already in a container).
- [b]Note:[/b] The SubViewportContainer forwards mouse-enter and mouse-exit notifications to its sub-viewports.
+ A container that displays the contents of underlying [SubViewport] child nodes. It uses the combined size of the [SubViewport]s as minimum size, unless [member stretch] is enabled.
+ [b]Note:[/b] Changing a [SubViewportContainer]'s [member Control.scale] will cause its contents to appear distorted. To change its visual size without causing distortion, adjust the node's margins instead (if it's not already in a container).
+ [b]Note:[/b] The [SubViewportContainer] forwards mouse-enter and mouse-exit notifications to its sub-viewports.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml
index 04452431c3..4b333a979c 100644
--- a/doc/classes/SurfaceTool.xml
+++ b/doc/classes/SurfaceTool.xml
@@ -242,7 +242,7 @@
<param index="0" name="index" type="int" />
<description>
Specifies the smooth group to use for the [i]next[/i] vertex. If this is never called, all vertices will have the default smooth group of [code]0[/code] and will be smoothed with adjacent vertices of the same group. To produce a mesh with flat normals, set the smooth group to [code]-1[/code].
- [b]Note:[/b] This function actually takes an [code]uint32_t[/code], so C# users should use [code]uint32.MaxValue[/code] instead of [code]-1[/code] to produce a mesh with flat normals.
+ [b]Note:[/b] This function actually takes a [code]uint32_t[/code], so C# users should use [code]uint32.MaxValue[/code] instead of [code]-1[/code] to produce a mesh with flat normals.
</description>
</method>
<method name="set_tangent">
diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml
index 34063adbb0..3815d6d2fe 100644
--- a/doc/classes/SyntaxHighlighter.xml
+++ b/doc/classes/SyntaxHighlighter.xml
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SyntaxHighlighter" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base Syntax highlighter resource for [TextEdit].
+ Base class for syntax highlighters. Provides syntax highlighting data to a [TextEdit].
</brief_description>
<description>
- Base syntax highlighter resource all syntax highlighters extend from, provides syntax highlighting data to [TextEdit].
- The associated [TextEdit] node will call into the [SyntaxHighlighter] on an as-needed basis.
- [b]Note:[/b] Each Syntax highlighter instance should not be shared across multiple [TextEdit] nodes.
+ Base class for syntax highlighters. Provides syntax highlighting data to a [TextEdit]. The associated [TextEdit] will call into the [SyntaxHighlighter] on an as-needed basis.
+ [b]Note:[/b] A [SyntaxHighlighter] instance should not be used across multiple [TextEdit] nodes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/SystemFont.xml b/doc/classes/SystemFont.xml
index f815c45476..f4bf6678d1 100644
--- a/doc/classes/SystemFont.xml
+++ b/doc/classes/SystemFont.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SystemFont" inherits="Font" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Font loaded from a system font.
- [b]Note:[/b] This class is implemented on iOS, Linux, macOS and Windows, on other platforms it will fallback to default theme font.
+ A font loaded from a system font. Falls back to a default theme font if not implemented on the host OS.
</brief_description>
<description>
[SystemFont] loads a font from a system font with the first matching name from [member font_names].
It will attempt to match font style, but it's not guaranteed.
The returned font might be part of a font collection or be a variable font with OpenType "weight", "width" and/or "italic" features set.
You can create [FontVariation] of the system font for fine control over its features.
+ [b]Note:[/b] This class is implemented on iOS, Linux, macOS and Windows, on other platforms it will fallback to default theme font.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index 07b1f3a173..cdbe9d933a 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TabBar" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Tab bar control.
+ A control that provides a horizontal bar with tabs.
</brief_description>
<description>
- Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interacting with children.
+ A control that provides a horizontal bar with tabs. Similar to [TabContainer] but is only in charge of drawing tabs, not interacting with children.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index 8081003320..ebf9bb2584 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TabContainer" inherits="Container" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Tabbed container.
+ A container that creates a tab for each child control, displaying only the active tab's control.
</brief_description>
<description>
- Arranges [Control] children into a tabbed view, creating a tab for each one. The active tab's corresponding [Control] has its [code]visible[/code] property set to [code]true[/code], and all other children's to [code]false[/code].
- Ignores non-[Control] children.
- [b]Note:[/b] The drawing of the clickable tabs themselves is handled by this node. Adding [TabBar]s as children is not needed.
+ Arranges child controls into a tabbed view, creating a tab for each one. The active tab's corresponding control is made visible, while all other child controls are hidden. Ignores non-control children.
+ [b]Note:[/b] The drawing of the clickable tabs is handled by this node; [TabBar] is not needed.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<methods>
<method name="get_current_tab_control" qualifiers="const">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index d207eec24c..d042a0b9a7 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextEdit" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Multiline text editing control.
+ A multiline text editor.
</brief_description>
<description>
- TextEdit is meant for editing large, multiline text. It also has facilities for editing code, such as syntax highlighting support and multiple levels of undo/redo.
+ A multiline text editor. It also has limited facilities for editing code, such as syntax highlighting support. For more advanced facilities for editing code, see [CodeEdit].
[b]Note:[/b] Most viewport, caret and edit methods contain a [code]caret_index[/code] argument for [member caret_multiple] support. The argument should be one of the following: [code]-1[/code] for all carets, [code]0[/code] for the main caret, or greater than [code]0[/code] for secondary carets.
[b]Note:[/b] When holding down [kbd]Alt[/kbd], the vertical scroll wheel will scroll 5 times as fast as it would normally do. This also works in the Godot script editor.
</description>
diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml
index db0b5384cc..93cd8065e2 100644
--- a/doc/classes/TextLine.xml
+++ b/doc/classes/TextLine.xml
@@ -4,7 +4,7 @@
Holds a line of text.
</brief_description>
<description>
- Abstraction over [TextServer] for handling single line of text.
+ Abstraction over [TextServer] for handling a single line of text.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index a6eabd415c..c7e9880fe7 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -4,7 +4,7 @@
Holds a paragraph of text.
</brief_description>
<description>
- Abstraction over [TextServer] for handling paragraph of text.
+ Abstraction over [TextServer] for handling a single paragraph of text.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 807be99da3..6d4ecb255e 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServer" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Interface for the fonts and complex text layouts.
+ A server interface for font management and text rendering.
</brief_description>
<description>
- [TextServer] is the API backend for managing fonts, and rendering complex text.
+ [TextServer] is the API backend for managing fonts and rendering text.
</description>
<tutorials>
</tutorials>
@@ -12,7 +12,7 @@
<method name="create_font">
<return type="RID" />
<description>
- Creates new, empty font cache entry resource. To free the resulting resource, use [method free_rid] method.
+ Creates a new, empty font cache entry resource. To free the resulting resource, use the [method free_rid] method.
</description>
</method>
<method name="create_shaped_text">
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index 171318b96d..7efd5a2a75 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerExtension" inherits="TextServer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for TextServer custom implementations (plugins).
+ Base class for custom [TextServer] implementations (plugins).
</brief_description>
<description>
- External TextServer implementations should inherit from this class.
+ External [TextServer] implementations should inherit from this class.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TextServerManager.xml b/doc/classes/TextServerManager.xml
index 6c5cb3e7b8..129b367cf4 100644
--- a/doc/classes/TextServerManager.xml
+++ b/doc/classes/TextServerManager.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerManager" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Manager for the font and complex text layout servers.
+ A singleton for managing [TextServer] implementations.
</brief_description>
<description>
- [TextServerManager] is the API backend for loading, enumeration and switching [TextServer]s.
+ [TextServerManager] is the API backend for loading, enumerating, and switching [TextServer]s.
[b]Note:[/b] Switching text server at runtime is possible, but will invalidate all fonts and text buffers. Make sure to unload all controls, fonts, and themes before doing so.
</description>
<tutorials>
@@ -14,14 +14,14 @@
<return type="void" />
<param index="0" name="interface" type="TextServer" />
<description>
- Registers an [TextServer] interface.
+ Registers a [TextServer] interface.
</description>
</method>
<method name="find_interface" qualifiers="const">
<return type="TextServer" />
<param index="0" name="name" type="String" />
<description>
- Finds an interface by its name.
+ Finds an interface by its [param name].
</description>
</method>
<method name="get_interface" qualifiers="const">
@@ -40,7 +40,7 @@
<method name="get_interfaces" qualifiers="const">
<return type="Dictionary[]" />
<description>
- Returns a list of available interfaces the index and name of each interface.
+ Returns a list of available interfaces, with the index and name of each interface.
</description>
</method>
<method name="get_primary_interface" qualifiers="const">
@@ -53,7 +53,7 @@
<return type="void" />
<param index="0" name="interface" type="TextServer" />
<description>
- Removes interface. All fonts and shaped text caches should be freed before removing interface.
+ Removes an interface. All fonts and shaped text caches should be freed before removing an interface.
</description>
</method>
<method name="set_primary_interface">
diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml
index 69733c3fd0..79ee8e44ab 100644
--- a/doc/classes/TextureRect.xml
+++ b/doc/classes/TextureRect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextureRect" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control for drawing textures.
+ A control that displays a texture.
</brief_description>
<description>
- Used to draw icons and sprites in a user interface. The texture's placement can be controlled with the [member stretch_mode] property. It can scale, tile, or stay centered inside its bounding rectangle.
+ A control that displays a texture, for example an icon inside a GUI. The texture's placement can be controlled with the [member stretch_mode] property. It can scale, tile, or stay centered inside its bounding rectangle.
</description>
<tutorials>
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index 2da8c7f28f..f01a6da36b 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Theme" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Theme resource for styling/skinning [Control]s and [Window]s.
+ A resource used for styling/skinning [Control]s and [Window]s.
</brief_description>
<description>
- A theme resource is used for styling/skinning [Control] and [Window] nodes. While individual controls can be styled using their local theme overrides (see [method Control.add_theme_color_override]), theme resources allow you to store and apply the same settings between all controls sharing the same type (e.g. style all [Button]s the same). One theme resource can be used for the entire project, but you can also set a separate theme resource to a branch of control nodes. A theme resources assigned to a control node applies to the control itself, as well as all of its direct and indirect children (as long as a chain of controls is uninterrupted).
+ A resource used for styling/skinning [Control] and [Window] nodes. While individual controls can be styled using their local theme overrides (see [method Control.add_theme_color_override]), theme resources allow you to store and apply the same settings across all controls sharing the same type (e.g. style all [Button]s the same). One theme resource can be used for the entire project, but you can also set a separate theme resource to a branch of control nodes. A theme resource assigned to a control applies to the control itself, as well as all of its direct and indirect children (as long as a chain of controls is uninterrupted).
Use [member ProjectSettings.gui/theme/custom] to set up a project-scope theme that will be available to every control in your project.
Use [member Control.theme] of any control node to set up a theme that will be available to that control and all of its direct and indirect children.
</description>
diff --git a/doc/classes/ThemeDB.xml b/doc/classes/ThemeDB.xml
index a1e6de64c7..9eb694467b 100644
--- a/doc/classes/ThemeDB.xml
+++ b/doc/classes/ThemeDB.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ThemeDB" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- An engine singleton providing access to static [Theme] information, such as default and project theme, and fallback values.
+ A singleton that provides access to static information about [Theme] resources used by the engine and by your project.
</brief_description>
<description>
- This engine singleton provides access to static information about [Theme] resources used by the engine and by your projects. You can fetch the default engine theme, as well as your project configured theme.
+ This singleton provides access to static information about [Theme] resources used by the engine and by your projects. You can fetch the default engine theme, as well as your project configured theme.
[ThemeDB] also contains fallback values for theme properties.
</description>
<tutorials>
diff --git a/doc/classes/Thread.xml b/doc/classes/Thread.xml
index fcb803b15a..a7f33eb539 100644
--- a/doc/classes/Thread.xml
+++ b/doc/classes/Thread.xml
@@ -7,7 +7,7 @@
A unit of execution in a process. Can run methods on [Object]s simultaneously. The use of synchronization via [Mutex] or [Semaphore] is advised if working with shared objects.
[b]Note:[/b] Breakpoints won't break on code if it's running in a thread. This is a current limitation of the GDScript debugger.
[b]Warning:[/b]
- To guarantee that the operating system is able to perform proper cleanup (no crashes, no deadlocks), these conditions must be met by the time a [Thread]'s reference count reaches zero and therefore it is destroyed:
+ To ensure proper cleanup without crashes or deadlocks, when a [Thread]'s reference count reaches zero and it is therefore destroyed, the following conditions must be met:
- It must not have any [Mutex] objects locked.
- It must not be waiting on any [Semaphore] objects.
- [method wait_to_finish] should have been called on it.
diff --git a/doc/classes/Time.xml b/doc/classes/Time.xml
index a2d704bc45..c5c505652e 100644
--- a/doc/classes/Time.xml
+++ b/doc/classes/Time.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Time" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Time singleton for working with time.
+ A singleton for working with time data.
</brief_description>
<description>
The Time singleton allows converting time between various formats and also getting time information from the system.
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index 67d11c173d..4fde29641b 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Transform2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 2D transformation (2×3 matrix).
+ A 2×3 matrix representing a 2D transformation.
</brief_description>
<description>
- 2×3 matrix (2 rows, 3 columns) used for 2D linear transformations. It can represent transformations such as translation, rotation, or scaling. It consists of three [Vector2] values: [member x], [member y], and the [member origin].
+ A 2×3 matrix (2 rows, 3 columns) used for 2D linear transformations. It can represent transformations such as translation, rotation, and scaling. It consists of three [Vector2] values: [member x], [member y], and the [member origin].
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml
index c01268779a..4134d1335f 100644
--- a/doc/classes/Transform3D.xml
+++ b/doc/classes/Transform3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Transform3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- 3D transformation (3×4 matrix).
+ A 3×4 matrix representing a 3D transformation.
</brief_description>
<description>
- 3×4 matrix (3 rows, 4 columns) used for 3D linear transformations. It can represent transformations such as translation, rotation, or scaling. It consists of a [member basis] (first 3 columns) and a [Vector3] for the [member origin] (last column).
+ A 3×4 matrix (3 rows, 4 columns) used for 3D linear transformations. It can represent transformations such as translation, rotation, and scaling. It consists of a [member basis] (first 3 columns) and a [Vector3] for the [member origin] (last column).
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
diff --git a/doc/classes/Translation.xml b/doc/classes/Translation.xml
index b31a84b540..661af9dc38 100644
--- a/doc/classes/Translation.xml
+++ b/doc/classes/Translation.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Translation" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Language Translation.
+ A language translation that maps a collection of strings to their individual translations.
</brief_description>
<description>
- Translations are resources that can be loaded and unloaded on demand. They map a string to another string.
+ [Translation]s are resources that can be loaded and unloaded on demand. They map a collection of strings to their individual translations, and they also provide convenience methods for pluralization.
</description>
<tutorials>
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index 155a7d4bdd..459831a4dc 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TranslationServer" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Server that manages all translations.
+ The server responsible for language translations.
</brief_description>
<description>
- Server that manages all translations. Translations can be set to it and removed from it.
+ The server that manages all language translations. Translations can be added to or removed from it.
</description>
<tutorials>
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
@@ -29,13 +29,13 @@
<param index="0" name="locale_a" type="String" />
<param index="1" name="locale_b" type="String" />
<description>
- Compares two locales and return similarity score between [code]0[/code](no match) and [code]10[/code](full match).
+ Compares two locales and returns a similarity score between [code]0[/code] (no match) and [code]10[/code] (full match).
</description>
</method>
<method name="get_all_countries" qualifiers="const">
<return type="PackedStringArray" />
<description>
- Returns array of known country codes.
+ Returns an array of known country codes.
</description>
</method>
<method name="get_all_languages" qualifiers="const">
@@ -47,21 +47,21 @@
<method name="get_all_scripts" qualifiers="const">
<return type="PackedStringArray" />
<description>
- Returns array of known script codes.
+ Returns an array of known script codes.
</description>
</method>
<method name="get_country_name" qualifiers="const">
<return type="String" />
<param index="0" name="country" type="String" />
<description>
- Returns readable country name for the [param country] code.
+ Returns a readable country name for the [param country] code.
</description>
</method>
<method name="get_language_name" qualifiers="const">
<return type="String" />
<param index="0" name="language" type="String" />
<description>
- Returns readable language name for the [param language] code.
+ Returns a readable language name for the [param language] code.
</description>
</method>
<method name="get_loaded_locales" qualifiers="const">
@@ -88,7 +88,7 @@
<return type="String" />
<param index="0" name="script" type="String" />
<description>
- Returns readable script name for the [param script] code.
+ Returns a readable script name for the [param script] code.
</description>
</method>
<method name="get_tool_locale">
@@ -138,7 +138,7 @@
<return type="String" />
<param index="0" name="locale" type="String" />
<description>
- Returns [param locale] string standardized to match known locales (e.g. [code]en-US[/code] would be matched to [code]en_US[/code]).
+ Returns a [param locale] string standardized to match known locales (e.g. [code]en-US[/code] would be matched to [code]en_US[/code]).
</description>
</method>
<method name="translate" qualifiers="const">
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index afe0088a26..48171349b2 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Tree" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control to show a tree of items.
+ A control used to show a set of internal [TreeItem]s in a hierarchical structure.
</brief_description>
<description>
- This shows a tree of items that can be selected, expanded and collapsed. The tree can have multiple columns with custom controls like text editing, buttons and popups. It can be useful for structured displays and interactions.
- Trees are built via code, using [TreeItem] objects to create the structure. They have a single root but multiple roots can be simulated if a dummy hidden root is added.
+ A control used to show a set of internal [TreeItem]s in a hierarchical structure. The tree items can be selected, expanded and collapsed. The tree can have multiple columns with custom controls like [LineEdit]s, buttons and popups. It can be useful for structured displays and interactions.
+ Trees are built via code, using [TreeItem] objects to create the structure. They have a single root, but multiple roots can be simulated with [member hide_root]:
[codeblocks]
[gdscript]
func _ready():
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index ffa79ed085..2bd8f57bd2 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TreeItem" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control for a single item inside a [Tree].
+ An internal control for a single item inside [Tree].
</brief_description>
<description>
- Control for a single item inside a [Tree]. May have child [TreeItem]s and be styled as well as contain buttons.
- You can remove a [TreeItem] by using [method Object.free].
- [b]Note:[/b] The ID values used for buttons are limited to 32 bits, not full 64 bits of [int]. This has a range of [code]-2^32[/code] to [code]2^32 - 1[/code], i.e. [code]-2147483648[/code] to [code]2147483647[/code].
+ A single item of a [Tree] control. It can contain other [TreeItem]s as children, which allows it to create a hierarchy. It can also contain text and buttons. [TreeItem] is not a [Node], it is internal to the [Tree].
+ To create a [TreeItem], use [method Tree.create_item] or [method TreeItem.create_child]. To remove a [TreeItem], use [method Object.free].
+ [b]Note:[/b] The ID values used for buttons are 32-bit, unlike [int] which is always 64-bit. They go from [code]-2147483648[/code] to [code]2147483647[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml
index 216cfe3d63..9b9bf7f569 100644
--- a/doc/classes/UndoRedo.xml
+++ b/doc/classes/UndoRedo.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="UndoRedo" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- General-purpose helper to manage undo/redo operations.
+ Provides a high-level interface for implementing undo and redo operations.
</brief_description>
<description>
- UndoRedo works by registering methods and property changes inside "actions".
- Common behavior is to create an action, then add do/undo calls to functions or property changes, then committing the action.
- Here's an example on how to add an UndoRedo action:
+ UndoRedo works by registering methods and property changes inside "actions". You can create an action, then provide ways to do and undo this action using function calls and property changes, then commit the action.
+ When an action is committed, all of the [code]do_*[/code] methods will run. If the [method undo] method is used, the [code]undo_*[/code] methods will run. If the [method redo] method is used, once again, all of the [code]do_*[/code] methods will run.
+ Here's an example on how to add an action:
[codeblocks]
[gdscript]
var undo_redo = UndoRedo.new()
@@ -57,7 +57,7 @@
[/csharp]
[/codeblocks]
[method create_action], [method add_do_method], [method add_undo_method], [method add_do_property], [method add_undo_property], and [method commit_action] should be called one after the other, like in the example. Not doing so could lead to crashes.
- If you don't need to register a method, you can leave [method add_do_method] and [method add_undo_method] out; the same goes for properties. You can also register more than one method/property.
+ If you don't need to register a method, you can leave [method add_do_method] and [method add_undo_method] out; the same goes for properties. You can also register more than one method/property in the order they should run.
If you are making an [EditorPlugin] and want to integrate into the editor's undo history, use [EditorUndoRedoManager] instead.
</description>
<tutorials>
diff --git a/doc/classes/VBoxContainer.xml b/doc/classes/VBoxContainer.xml
index ae63059f1e..b746a29bd0 100644
--- a/doc/classes/VBoxContainer.xml
+++ b/doc/classes/VBoxContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VBoxContainer" inherits="BoxContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical box container.
+ A container that arranges its child controls vertically.
</brief_description>
<description>
- Vertical box container. See [BoxContainer].
+ A variant of [BoxContainer] that can only arrange its child controls vertically. Child controls are rearranged automatically when their minimum size changes.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
</tutorials>
<theme_items>
diff --git a/doc/classes/VFlowContainer.xml b/doc/classes/VFlowContainer.xml
index d3ee93dad4..21a8ed71ce 100644
--- a/doc/classes/VFlowContainer.xml
+++ b/doc/classes/VFlowContainer.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VFlowContainer" inherits="FlowContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical flow container.
+ A container that arranges its child controls vertically and wraps them around at the borders.
</brief_description>
<description>
- Vertical version of [FlowContainer].
+ A variant of [FlowContainer] that can only arrange its child controls vertically, wrapping them around at the borders. This is similar to how text in a book wraps around when no more words can fit on a line, except vertically.
</description>
<tutorials>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="h_separation" data_type="constant" type="int" default="4">
diff --git a/doc/classes/VScrollBar.xml b/doc/classes/VScrollBar.xml
index c10fe39ab2..3a6acb529a 100644
--- a/doc/classes/VScrollBar.xml
+++ b/doc/classes/VScrollBar.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VScrollBar" inherits="ScrollBar" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical scroll bar.
+ A vertical scrollbar that goes from top (min) to bottom (max).
</brief_description>
<description>
- Vertical version of [ScrollBar], which goes from top (min) to bottom (max).
+ A vertical scrollbar, typically used to navigate through content that extends beyond the visible height of a control. It is a [Range]-based control and goes from top (min) to bottom (max). Note that this direction is the opposite of [VSlider]'s.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VSeparator.xml b/doc/classes/VSeparator.xml
index e649014358..fcd33d7c7f 100644
--- a/doc/classes/VSeparator.xml
+++ b/doc/classes/VSeparator.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VSeparator" inherits="Separator" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical version of [Separator].
+ A vertical line used for separating other controls.
</brief_description>
<description>
- Vertical version of [Separator]. Even though it looks vertical, it is used to separate objects horizontally.
+ A vertical separator used for separating other controls that are arranged [b]horizontally[/b]. [VSeparator] is purely visual and normally drawn as a [StyleBoxLine].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index b1906ccef2..5c1d61d0f9 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VSlider" inherits="Slider" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical slider.
+ A vertical slider that goes from bottom (min) to top (max).
</brief_description>
<description>
- Vertical slider. See [Slider]. This one goes from bottom (min) to top (max).
- [b]Note:[/b] The [signal Range.changed] and [signal Range.value_changed] signals are part of the [Range] class which this class inherits from.
+ A vertical slider, used to adjust a value by moving a grabber along a vertical axis. It is a [Range]-based control and goes from bottom (min) to top (max). Note that this direction is the opposite of [VScrollBar]'s.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VSplitContainer.xml b/doc/classes/VSplitContainer.xml
index 72ec3bfc99..45aba9736c 100644
--- a/doc/classes/VSplitContainer.xml
+++ b/doc/classes/VSplitContainer.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VSplitContainer" inherits="SplitContainer" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vertical split container.
+ A container that splits two child controls vertically and provides a grabber for adjusting the split ratio.
</brief_description>
<description>
- Vertical split container. See [SplitContainer]. This goes from top to bottom.
+ A container that accepts only two child controls, then arranges them vertically and creates a divisor between them. The divisor can be dragged around to change the size relation between the child controls.
</description>
<tutorials>
- <link title="GUI containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
+ <link title="Using Containers">$DOCS_URL/tutorials/ui/gui_containers.html</link>
</tutorials>
<theme_items>
<theme_item name="autohide" data_type="constant" type="int" default="1">
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index 215d05bfec..4f237b5c2e 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -20,7 +20,7 @@
var boo = "Boo is a string!";
var ref = new RefCounted(); // var is especially useful when used together with a constructor.
- // Godot also provides a Variant type that works like an union of all the Variant-compatible types.
+ // Godot also provides a Variant type that works like a union of all the Variant-compatible types.
Variant fooVar = 2; // fooVar is dynamically an integer (stored as a `long` in the Variant type).
fooVar = "Now fooVar is a string!";
fooVar = new RefCounted(); // fooVar is a GodotObject.
@@ -43,8 +43,7 @@
# To get the name of the underlying Object type, you need the `get_class()` method.
print("foo is a(n) %s" % foo.get_class()) # inject the class name into a formatted string.
# Note also that there is not yet any way to get a script's `class_name` string easily.
- # To fetch that value, you can use [member ProjectSettings.get_global_class_list].
- # Open your project.godot file to see it up close.
+ # To fetch that value, you can use ProjectSettings.get_global_class_list().
[/gdscript]
[csharp]
Variant foo = 2;
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 73f6f4be47..6c9d96860a 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector2" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 2D math using floating point coordinates.
+ A 2D vector using floating point coordinates.
</brief_description>
<description>
- 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
+ A 2-element structure that can be used to represent 2D coordinates or any other pair of numeric values.
It uses floating-point coordinates. By default, these floating-point values use 32-bit precision, unlike [float] which is always 64-bit. If double precision is needed, compile the engine with the option [code]precision=double[/code].
See [Vector2i] for its integer counterpart.
[b]Note:[/b] In a boolean context, a Vector2 will evaluate to [code]false[/code] if it's equal to [code]Vector2(0, 0)[/code]. Otherwise, a Vector2 will always evaluate to [code]true[/code].
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index 6ce7c2e7b3..7f7f420afe 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector2i" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 2D math using integer coordinates.
+ A 2D vector using integer coordinates.
</brief_description>
<description>
- 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
+ A 2-element structure that can be used to represent 2D grid coordinates or any other pair of integers.
It uses integer coordinates and is therefore preferable to [Vector2] when exact precision is required. Note that the values are limited to 32 bits, and unlike [Vector2] this cannot be configured with an engine build option. Use [int] or [PackedInt64Array] if 64-bit values are needed.
[b]Note:[/b] In a boolean context, a Vector2i will evaluate to [code]false[/code] if it's equal to [code]Vector2i(0, 0)[/code]. Otherwise, a Vector2i will always evaluate to [code]true[/code].
</description>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 511d84d24d..d4ecf008f2 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector3" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 3D math using floating point coordinates.
+ A 3D vector using floating point coordinates.
</brief_description>
<description>
- 3-element structure that can be used to represent positions in 3D space or any other triplet of numeric values.
+ A 3-element structure that can be used to represent 3D coordinates or any other triplet of numeric values.
It uses floating-point coordinates. By default, these floating-point values use 32-bit precision, unlike [float] which is always 64-bit. If double precision is needed, compile the engine with the option [code]precision=double[/code].
See [Vector3i] for its integer counterpart.
[b]Note:[/b] In a boolean context, a Vector3 will evaluate to [code]false[/code] if it's equal to [code]Vector3(0, 0, 0)[/code]. Otherwise, a Vector3 will always evaluate to [code]true[/code].
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index 5b86fba30e..b01e5bd486 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector3i" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 3D math using integer coordinates.
+ A 3D vector using integer coordinates.
</brief_description>
<description>
- 3-element structure that can be used to represent positions in 3D space or any other triplet of numeric values.
+ A 3-element structure that can be used to represent 3D grid coordinates or any other triplet of integers.
It uses integer coordinates and is therefore preferable to [Vector3] when exact precision is required. Note that the values are limited to 32 bits, and unlike [Vector3] this cannot be configured with an engine build option. Use [int] or [PackedInt64Array] if 64-bit values are needed.
[b]Note:[/b] In a boolean context, a Vector3i will evaluate to [code]false[/code] if it's equal to [code]Vector3i(0, 0, 0)[/code]. Otherwise, a Vector3i will always evaluate to [code]true[/code].
</description>
diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml
index cf829194e5..a89663a54a 100644
--- a/doc/classes/Vector4.xml
+++ b/doc/classes/Vector4.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector4" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 4D math using floating point coordinates.
+ A 4D vector using floating point coordinates.
</brief_description>
<description>
- 4-element structure that can be used to represent any quadruplet of numeric values.
+ A 4-element structure that can be used to represent 4D coordinates or any other quadruplet of numeric values.
It uses floating-point coordinates. By default, these floating-point values use 32-bit precision, unlike [float] which is always 64-bit. If double precision is needed, compile the engine with the option [code]precision=double[/code].
See [Vector4i] for its integer counterpart.
[b]Note:[/b] In a boolean context, a Vector4 will evaluate to [code]false[/code] if it's equal to [code]Vector4(0, 0, 0, 0)[/code]. Otherwise, a Vector4 will always evaluate to [code]true[/code].
diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml
index c2e03016bf..e6aa9ed720 100644
--- a/doc/classes/Vector4i.xml
+++ b/doc/classes/Vector4i.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector4i" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Vector used for 4D math using integer coordinates.
+ A 4D vector using integer coordinates.
</brief_description>
<description>
- 4-element structure that can be used to represent 4D grid coordinates or sets of integers.
+ A 4-element structure that can be used to represent 4D grid coordinates or any other quadruplet of integers.
It uses integer coordinates and is therefore preferable to [Vector4] when exact precision is required. Note that the values are limited to 32 bits, and unlike [Vector4] this cannot be configured with an engine build option. Use [int] or [PackedInt64Array] if 64-bit values are needed.
+ [b]Note:[/b] In a boolean context, a Vector4i will evaluate to [code]false[/code] if it's equal to [code]Vector4i(0, 0, 0, 0)[/code]. Otherwise, a Vector3i will always evaluate to [code]true[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VehicleBody3D.xml b/doc/classes/VehicleBody3D.xml
index 911547a214..e5e5386d81 100644
--- a/doc/classes/VehicleBody3D.xml
+++ b/doc/classes/VehicleBody3D.xml
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VehicleBody3D" inherits="RigidBody3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics body that simulates the behavior of a car.
+ A 3D physics body that simulates the behavior of a car.
</brief_description>
<description>
- This node implements all the physics logic needed to simulate a car. It is based on the raycast vehicle system commonly found in physics engines. You will need to add a [CollisionShape3D] for the main body of your vehicle and add [VehicleWheel3D] nodes for the wheels. You should also add a [MeshInstance3D] to this node for the 3D model of your car but this model should not include meshes for the wheels. You should control the vehicle by using the [member brake], [member engine_force], and [member steering] properties and not change the position or orientation of this node directly.
- [b]Note:[/b] The origin point of your VehicleBody3D will determine the center of gravity of your vehicle so it is better to keep this low and move the [CollisionShape3D] and [MeshInstance3D] upwards.
- [b]Note:[/b] This class has known issues and isn't designed to provide realistic 3D vehicle physics. If you want advanced vehicle physics, you will probably have to write your own physics integration using another [PhysicsBody3D] class.
- [b]Warning:[/b] With a non-uniform scale this node will probably not function as expected. Please make sure to keep its scale uniform (i.e. the same on all axes), and change the size(s) of its collision shape(s) instead.
+ This physics body implements all the physics logic needed to simulate a car. It is based on the raycast vehicle system commonly found in physics engines. Aside from a [CollisionShape3D] for the main body of the vehicle, you must also add a [VehicleWheel3D] node for each wheel. You should also add a [MeshInstance3D] to this node for the 3D model of the vehicle, but this model should generally not include meshes for the wheels. You can control the vehicle by using the [member brake], [member engine_force], and [member steering] properties. The position or orientation of this node shouldn't be changed directly.
+ [b]Note:[/b] The origin point of your VehicleBody3D will determine the center of gravity of your vehicle. To make the vehicle more grounded, the origin point is usually kept low, moving the [CollisionShape3D] and [MeshInstance3D] upwards.
+ [b]Note:[/b] This class has known issues and isn't designed to provide realistic 3D vehicle physics. If you want advanced vehicle physics, you may have to write your own physics integration using [CharacterBody3D] or [RigidBody3D].
</description>
<tutorials>
<link title="3D Truck Town Demo">https://godotengine.org/asset-library/asset/524</link>
diff --git a/doc/classes/VehicleWheel3D.xml b/doc/classes/VehicleWheel3D.xml
index 1695cc6bea..c4ebed84c5 100644
--- a/doc/classes/VehicleWheel3D.xml
+++ b/doc/classes/VehicleWheel3D.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VehicleWheel3D" inherits="Node3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Physics object that simulates the behavior of a wheel.
+ A 3D physics body for a [VehicleBody3D] that simulates the behavior of a wheel.
</brief_description>
<description>
- This node needs to be used as a child node of [VehicleBody3D] and simulates the behavior of one of its wheels. This node also acts as a collider to detect if the wheel is touching a surface.
- [b]Note:[/b] This class has known issues and isn't designed to provide realistic 3D vehicle physics. If you want advanced vehicle physics, you will probably have to write your own physics integration using another [PhysicsBody3D] class.
+ A node used as a child of a [VehicleBody3D] parent to simulate the behavior of one of its wheels. This node also acts as a collider to detect if the wheel is touching a surface.
+ [b]Note:[/b] This class has known issues and isn't designed to provide realistic 3D vehicle physics. If you want advanced vehicle physics, you may need to write your own physics integration using another [PhysicsBody3D] class.
</description>
<tutorials>
<link title="3D Truck Town Demo">https://godotengine.org/asset-library/asset/524</link>
diff --git a/doc/classes/VideoStreamPlayer.xml b/doc/classes/VideoStreamPlayer.xml
index 87af2f8c4d..6ba2e42557 100644
--- a/doc/classes/VideoStreamPlayer.xml
+++ b/doc/classes/VideoStreamPlayer.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VideoStreamPlayer" inherits="Control" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Control for playing video streams.
+ A control used for video playback.
</brief_description>
<description>
- Control node for playing video streams using [VideoStream] resources.
+ A control used for playback of [VideoStream] resources.
Supported video formats are [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]) and any format exposed via a GDExtension plugin.
[b]Note:[/b] Due to a bug, VideoStreamPlayer does not support localization remapping yet.
[b]Warning:[/b] On Web, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations.
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 7ff96bb8fd..caab6ee924 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Viewport" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for viewports.
+ Abstract base class for viewports. Encapsulates drawing and interaction with a game world.
</brief_description>
<description>
A Viewport creates a different view into the screen, or a sub-view inside another viewport. Children 2D Nodes will display on it, and children Camera3D 3D nodes will render on it too.
- Optionally, a viewport can have its own 2D or 3D world, so they don't share what they draw with other viewports.
+ Optionally, a viewport can have its own 2D or 3D world, so it doesn't share what it draws with other viewports.
Viewports can also choose to be audio listeners, so they generate positional audio depending on a 2D or 3D camera child of it.
Also, viewports can be assigned to different screens in case the devices have multiple screens.
Finally, viewports can also behave as render targets, in which case they will not be visible unless the associated texture is used to draw.
diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml
index 2f62199813..c7a0223f3a 100644
--- a/doc/classes/ViewportTexture.xml
+++ b/doc/classes/ViewportTexture.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ViewportTexture" inherits="Texture2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Texture which displays the content of a [Viewport].
+ Provides the content of a [Viewport] as a dynamic texture.
</brief_description>
<description>
- Displays the content of a [Viewport] node as a dynamic [Texture2D]. This can be used to mix controls, 2D, and 3D elements in the same scene.
- To create a ViewportTexture in code, use the [method Viewport.get_texture] method on the target viewport.
- [b]Note:[/b] When local to scene, this texture uses [method Resource.setup_local_to_scene] to set the proxy texture and flags in the local viewport. Local to scene viewport textures will return incorrect data until the scene root is ready (see [signal Node.ready]).
+ Provides the content of a [Viewport] as a dynamic [Texture2D]. This can be used to mix controls, 2D game objects, and 3D game objects in the same scene.
+ To create a [ViewportTexture] in code, use the [method Viewport.get_texture] method on the target viewport.
+ [b]Note:[/b] When local to scene, this texture uses [method Resource.setup_local_to_scene] to set the proxy texture and flags in the local viewport. Local to scene [ViewportTexture]s will return incorrect data until the scene root is ready (see [signal Node.ready]).
</description>
<tutorials>
<link title="GUI in 3D Demo">https://godotengine.org/asset-library/asset/127</link>
@@ -16,8 +16,8 @@
</tutorials>
<members>
<member name="viewport_path" type="NodePath" setter="set_viewport_path_in_scene" getter="get_viewport_path_in_scene" default="NodePath(&quot;&quot;)">
- The path to the [Viewport] node to display. This is relative to the scene root, not to the node which uses the texture.
- [b]Note:[/b] In the editor, it is automatically updated when the target viewport's node path changes due to renaming or moving the viewport or its ancestors. At runtime, it may not be able to automatically update due to the inability to determine the scene root.
+ The path to the [Viewport] node to display. This is relative to the scene root, not to the node that uses the texture.
+ [b]Note:[/b] In the editor, this path is automatically updated when the target viewport or one of its ancestors is renamed or moved. At runtime, the path may not be able to automatically update due to the inability to determine the scene root.
</member>
</members>
</class>
diff --git a/doc/classes/WeakRef.xml b/doc/classes/WeakRef.xml
index e2dcbd7f9d..24685e7f53 100644
--- a/doc/classes/WeakRef.xml
+++ b/doc/classes/WeakRef.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="WeakRef" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Holds an [Object], but does not contribute to the reference count if the object is a reference.
+ Holds an [Object]. If the object is [RefCounted], it doesn't update the reference count.
</brief_description>
<description>
- A weakref can hold a [RefCounted], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GlobalScope.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
+ A weakref can hold a [RefCounted] without contributing to the reference counter. A weakref can be created from an [Object] using [method @GlobalScope.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 3adc0d367d..79ba768b79 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Window" inherits="Viewport" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Base class for all windows.
+ Base class for all windows, dialogs, and popups.
</brief_description>
<description>
A node that creates a window. The window can either be a native system window or embedded inside another [Window] (see [member Viewport.gui_embed_subwindows]).
- At runtime, [Window]s will not close automatically when requested. You need to handle it manually using [signal close_requested] (this applies both to clicking close button and clicking outside popup).
+ At runtime, [Window]s will not close automatically when requested. You need to handle it manually using the [signal close_requested] signal (this applies both to pressing the close button and clicking outside of a popup).
</description>
<tutorials>
</tutorials>
@@ -570,8 +570,11 @@
</member>
<member name="extend_to_title" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] contents is expanded to the full size of the window, window title bar is transparent.
+ [b]Note:[/b] This property is implemented only on macOS.
+ [b]Note:[/b] This property only works with native windows.
</member>
<member name="initial_position" type="int" setter="set_initial_position" getter="get_initial_position" enum="Window.WindowInitialPosition" default="0">
+ Specifies the initial type of position for the [Window]. See [enum WindowInitialPosition] constants.
</member>
<member name="max_size" type="Vector2i" setter="set_max_size" getter="get_max_size" default="Vector2i(0, 0)">
If non-zero, the [Window] can't be resized to be bigger than this size.
@@ -584,10 +587,12 @@
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Window.Mode" default="0">
Set's the window's current mode.
[b]Note:[/b] Fullscreen mode is not exclusive full screen on Windows and Linux.
+ [b]Note:[/b] This method only works with native windows, i.e. the main window and [Window]-derived nodes when [member Viewport.gui_embed_subwindows] is disabled in the main viewport.
</member>
<member name="mouse_passthrough" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], all mouse events will be passed to the underlying window of the same application. See also [member mouse_passthrough_polygon].
[b]Note:[/b] This property is implemented on Linux (X11), macOS and Windows.
+ [b]Note:[/b] This property only works with native windows.
</member>
<member name="mouse_passthrough_polygon" type="PackedVector2Array" setter="set_mouse_passthrough_polygon" getter="get_mouse_passthrough_polygon" default="PackedVector2Array()">
Sets a polygonal region of the window which accepts mouse events. Mouse events outside the region will be passed through.
@@ -620,10 +625,12 @@
</member>
<member name="popup_window" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] will be considered a popup. Popups are sub-windows that don't show as separate windows in system's window manager's window list and will send close request when anything is clicked outside of them (unless [member exclusive] is enabled).
+ [b]Note:[/b] This property only works with native windows.
</member>
<member name="position" type="Vector2i" setter="set_position" getter="get_position" default="Vector2i(0, 0)">
The window's position in pixels.
- If [member ProjectSettings.display/window/subwindows/embed_subwindows] is [code]false[/code], the position is in absolute screen coordinates. This typically applies to editor plugins. If the setting is [code]false[/code], the window's position is in the coordinates of its parent [Viewport].
+ If [member ProjectSettings.display/window/subwindows/embed_subwindows] is [code]false[/code], the position is in absolute screen coordinates. This typically applies to editor plugins. If the setting is [code]true[/code], the window's position is in the coordinates of its parent [Viewport].
+ [b]Note:[/b] This property only works if [member initial_position] is set to [constant WINDOW_INITIAL_POSITION_ABSOLUTE].
</member>
<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(100, 100)">
The window's size in pixels.
@@ -636,7 +643,7 @@
The name of a theme type variation used by this [Window] to look up its own theme items. See [member Control.theme_type_variation] for more details.
</member>
<member name="title" type="String" setter="set_title" getter="get_title" default="&quot;&quot;">
- The window's title. If the [Window] is non-embedded, title styles set in [Theme] will have no effect.
+ The window's title. If the [Window] is native, title styles set in [Theme] will have no effect.
</member>
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. The transient window will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
@@ -644,8 +651,8 @@
</member>
<member name="transparent" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window]'s background can be transparent. This is best used with embedded windows.
- [b]Note:[/b] For native windows, this flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code].
[b]Note:[/b] Transparency support is implemented on Linux, macOS and Windows, but availability might vary depending on GPU driver, display manager, and compositor capabilities.
+ [b]Note:[/b] This property has no effect if either [member ProjectSettings.display/window/per_pixel_transparency/allowed], or the window's [member Viewport.transparent_bg] is set to [code]false[/code].
</member>
<member name="unfocusable" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the [Window] can't be focused nor interacted with. It can still be visible.
@@ -683,7 +690,7 @@
<param index="0" name="files" type="PackedStringArray" />
<description>
Emitted when files are dragged from the OS file manager and dropped in the game window. The argument is a list of file paths.
- Note that this method only works with non-embedded windows, i.e. the main window and [Window]-derived nodes when [member Viewport.gui_embed_subwindows] is disabled in the main viewport.
+ Note that this method only works with native windows, i.e. the main window and [Window]-derived nodes when [member Viewport.gui_embed_subwindows] is disabled in the main viewport.
Example usage:
[codeblock]
func _ready():
@@ -780,21 +787,24 @@
The window is floating on top of all other windows. This flag is ignored for full-screen windows. Set with [member always_on_top].
</constant>
<constant name="FLAG_TRANSPARENT" value="3" enum="Flags">
- The window background can be transparent.
- [b]Note:[/b] This flag has no effect if [member ProjectSettings.display/window/per_pixel_transparency/allowed] is set to [code]false[/code]. Set with [member transparent].
+ The window background can be transparent. Set with [member transparent].
+ [b]Note:[/b] This flag has no effect if either [member ProjectSettings.display/window/per_pixel_transparency/allowed], or the window's [member Viewport.transparent_bg] is set to [code]false[/code].
</constant>
<constant name="FLAG_NO_FOCUS" value="4" enum="Flags">
The window can't be focused. No-focus window will ignore all input, except mouse clicks. Set with [member unfocusable].
</constant>
<constant name="FLAG_POPUP" value="5" enum="Flags">
Window is part of menu or [OptionButton] dropdown. This flag can't be changed when the window is visible. An active popup window will exclusively receive all input, without stealing focus from its parent. Popup windows are automatically closed when uses click outside it, or when an application is switched. Popup window must have transient parent set (see [member transient]).
+ [b]Note:[/b] This flag has no effect in embedded windows (unless said window is a [Popup]).
</constant>
<constant name="FLAG_EXTEND_TO_TITLE" value="6" enum="Flags">
Window content is expanded to the full size of the window. Unlike borderless window, the frame is left intact and can be used to resize the window, title bar is transparent, but have minimize/maximize/close buttons. Set with [member extend_to_title].
- [b]Note:[/b] This flag is implemented on macOS.
+ [b]Note:[/b] This flag is implemented only on macOS.
+ [b]Note:[/b] This flag has no effect in embedded windows.
</constant>
<constant name="FLAG_MOUSE_PASSTHROUGH" value="7" enum="Flags">
All mouse events are passed to the underlying window of the same application.
+ [b]Note:[/b] This flag has no effect in embedded windows.
</constant>
<constant name="FLAG_MAX" value="8" enum="Flags">
Max value of the [enum Flags].
diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml
index 89fb084118..c06fc48f12 100644
--- a/doc/classes/World2D.xml
+++ b/doc/classes/World2D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="World2D" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Class that has everything pertaining to a 2D world.
+ A resource that holds all components of a 2D world, such as a canvas and a physics space.
</brief_description>
<description>
- Class that has everything pertaining to a 2D world. A physics space, a visual scenario and a sound space. 2D nodes register their resources into the current 2D world.
+ Class that has everything pertaining to a 2D world: A physics space, a canvas, and a sound space. 2D nodes register their resources into the current 2D world.
</description>
<tutorials>
<link title="Ray-casting">$DOCS_URL/tutorials/physics/ray-casting.html</link>
diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml
index 4ff52b5780..ce5f3d082d 100644
--- a/doc/classes/World3D.xml
+++ b/doc/classes/World3D.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="World3D" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Class that has everything pertaining to a world.
+ A resource that holds all components of a 3D world, such as a visual scenario and a physics space.
</brief_description>
<description>
- Class that has everything pertaining to a world. A physics space, a visual scenario and a sound space. Node3D nodes register their resources into the current world.
+ Class that has everything pertaining to a world: A physics space, a visual scenario, and a sound space. 3D nodes register their resources into the current 3D world.
</description>
<tutorials>
<link title="Ray-casting">$DOCS_URL/tutorials/physics/ray-casting.html</link>
diff --git a/doc/classes/WorldBoundaryShape2D.xml b/doc/classes/WorldBoundaryShape2D.xml
index 32c33f43d5..4ee4b2551c 100644
--- a/doc/classes/WorldBoundaryShape2D.xml
+++ b/doc/classes/WorldBoundaryShape2D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="WorldBoundaryShape2D" inherits="Shape2D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- World boundary (infinite plane) shape resource for 2D physics.
+ A 2D world boundary (half-plane) shape used for physics collision.
</brief_description>
<description>
- 2D world boundary shape to be added as a [i]direct[/i] child of a [PhysicsBody2D] or [Area2D] using a [CollisionShape2D] node. [WorldBoundaryShape2D] works like an infinite plane and will not allow any physics body to go to the negative side. Note that the [member normal] matters; anything "below" the plane will collide with it. If the [WorldBoundaryShape2D] is used in a [PhysicsBody2D], it will cause colliding objects placed "below" it to teleport "above" the plane.
- [b]Performance:[/b] Being a primitive collision shape, [WorldBoundaryShape2D] is fast to check collisions against.
+ A 2D world boundary shape, intended for use in physics. [WorldBoundaryShape2D] works like an infinite straight line that forces all physics bodies to stay above it. The line's normal determines which direction is considered as "above" and in the editor, the smaller line over it represents this direction. It can for example be used for endless flat floors.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/WorldBoundaryShape3D.xml b/doc/classes/WorldBoundaryShape3D.xml
index 80ef163dd1..e8ebe96d38 100644
--- a/doc/classes/WorldBoundaryShape3D.xml
+++ b/doc/classes/WorldBoundaryShape3D.xml
@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="WorldBoundaryShape3D" inherits="Shape3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- World boundary (infinite plane) shape resource for 3D physics.
+ A 3D world boundary (half-space) shape used for physics collision.
</brief_description>
<description>
- 3D world boundary shape to be added as a [i]direct[/i] child of a [PhysicsBody3D] or [Area3D] using a [CollisionShape3D] node. [WorldBoundaryShape3D] works like an infinite plane and will not allow any physics body to go to the negative side. Note that the [Plane]'s normal matters; anything "below" the plane will collide with it. If the [WorldBoundaryShape3D] is used in a [PhysicsBody3D], it will cause colliding objects placed "below" it to teleport "above" the plane.
- [b]Performance:[/b] Being a primitive collision shape, [WorldBoundaryShape3D] is fast to check collisions against.
+ A 3D world boundary shape, intended for use in physics. [WorldBoundaryShape3D] works like an infinite plane that forces all physics bodies to stay above it. The [member plane]'s normal determines which direction is considered as "above" and in the editor, the line over the plane represents this direction. It can for example be used for endless flat floors.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/XMLParser.xml b/doc/classes/XMLParser.xml
index a7b144a711..86732391e4 100644
--- a/doc/classes/XMLParser.xml
+++ b/doc/classes/XMLParser.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="XMLParser" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Provides a low-level interface for creating parsers for XML files.
Low-level class for creating parsers for [url=https://en.wikipedia.org/wiki/XML]XML[/url] files.
</brief_description>
<description>
- This class can serve as base to make custom XML parsers. Since XML is a very flexible standard, this interface is low-level so it can be applied to any possible schema.
+ Provides a low-level interface for creating parsers for [url=https://en.wikipedia.org/wiki/XML]XML[/url] files. This class can serve as base to make custom XML parsers.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/bool.xml b/doc/classes/bool.xml
index dc94d72e25..af54c58f82 100644
--- a/doc/classes/bool.xml
+++ b/doc/classes/bool.xml
@@ -1,90 +1,42 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="bool" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Boolean built-in type.
+ A built-in boolean type.
</brief_description>
<description>
- Boolean is a built-in type. There are two boolean values: [code]true[/code] and [code]false[/code]. You can think of it as a switch with on or off (1 or 0) setting. Booleans are used in programming for logic in condition statements, like [code]if[/code] statements.
- Booleans can be directly used in [code]if[/code] statements. The code below demonstrates this on the [code]if can_shoot:[/code] line. You don't need to use [code]== true[/code], you only need [code]if can_shoot:[/code]. Similarly, use [code]if not can_shoot:[/code] rather than [code]== false[/code].
+ A [bool] is always one of two values: [code]true[/code] or [code]false[/code], similar to a switch that is either on or off. Booleans are used in programming for logic in condition statements.
+ Booleans can be directly used in [code]if[/code] and [code]elif[/code] statements. You don't need to add [code]== true[/code] or [code]== false[/code]:
[codeblocks]
[gdscript]
- var _can_shoot = true
-
- func shoot():
- if _can_shoot:
- pass # Perform shooting actions here.
+ if can_shoot:
+ launch_bullet()
[/gdscript]
[csharp]
- private bool _canShoot = true;
-
- public void Shoot()
+ if (canShoot)
{
- if (_canShoot)
- {
- // Perform shooting actions here.
- }
+ launchBullet();
}
[/csharp]
[/codeblocks]
- The following code will only create a bullet if both conditions are met: action "shoot" is pressed and if [code]can_shoot[/code] is [code]true[/code].
- [b]Note:[/b] [code]Input.is_action_pressed("shoot")[/code] is also a boolean that is [code]true[/code] when "shoot" is pressed and [code]false[/code] when "shoot" isn't pressed.
+ Many common methods and operations return [bool]s, for example, [code]shooting_cooldown &lt;= 0.0[/code] may evaluate to [code]true[/code] or [code]false[/code] depending on the number's value.
+ [bool]s are usually used with the logical operators [code]and[/code], [code]or[/code], and [code]not[/code] to create complex conditions:
[codeblocks]
[gdscript]
- var _can_shoot = true
+ if bullets &gt; 0 and not is_reloading:
+ launch_bullet()
- func shoot():
- if _can_shoot and Input.is_action_pressed("shoot"):
- create_bullet()
+ if bullets == 0 or is_reloading:
+ play_clack_sound()
[/gdscript]
[csharp]
- private bool _canShoot = true;
-
- public void Shoot()
- {
- if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
- {
- CreateBullet();
- }
- }
- [/csharp]
- [/codeblocks]
- The following code will set [code]can_shoot[/code] to [code]false[/code] and start a timer. This will prevent player from shooting until the timer runs out. Next [code]can_shoot[/code] will be set to [code]true[/code] again allowing player to shoot once again.
- [codeblocks]
- [gdscript]
- var _can_shoot = true
- @onready var _cool_down = $CoolDownTimer
-
- func shoot():
- if _can_shoot and Input.is_action_pressed("shoot"):
- create_bullet()
- _can_shoot = false
- _cool_down.start()
-
- func _on_cool_down_timer_timeout():
- _can_shoot = true
- [/gdscript]
- [csharp]
- private bool _canShoot = true;
- private Timer _coolDown;
-
- public override void _Ready()
- {
- _coolDown = GetNode&lt;Timer&gt;("CoolDownTimer");
- }
-
- public void Shoot()
+ if (bullets &gt; 0 &amp;&amp; !isReloading)
{
- if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
- {
- CreateBullet();
- _canShoot = false;
- _coolDown.Start();
- }
+ launchBullet();
}
- public void OnCoolDownTimerTimeout()
+ if (bullets == 0 || isReloading)
{
- _canShoot = true;
+ playClackSound();
}
[/csharp]
[/codeblocks]
@@ -109,14 +61,14 @@
<return type="bool" />
<param index="0" name="from" type="float" />
<description>
- Cast a [float] value to a boolean value, this method will return [code]false[/code] if [code]0.0[/code] is passed in, and [code]true[/code] for all other floats.
+ Cast a [float] value to a boolean value. This method will return [code]false[/code] if [code]0.0[/code] is passed in, and [code]true[/code] for all other values.
</description>
</constructor>
<constructor name="bool">
<return type="bool" />
<param index="0" name="from" type="int" />
<description>
- Cast an [int] value to a boolean value, this method will return [code]false[/code] if [code]0[/code] is passed in, and [code]true[/code] for all other ints.
+ Cast an [int] value to a boolean value. This method will return [code]false[/code] if [code]0[/code] is passed in, and [code]true[/code] for all other values.
</description>
</constructor>
</constructors>
diff --git a/doc/classes/float.xml b/doc/classes/float.xml
index 3b8c55576f..fa0d4e6367 100644
--- a/doc/classes/float.xml
+++ b/doc/classes/float.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="float" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Float built-in type.
+ A built-in type for floating point numbers.
</brief_description>
<description>
- The [float] built-in type is a 64-bit double-precision floating-point number, equivalent to [code]double[/code] in C++. This type has 14 reliable decimal digits of precision. The [float] type can be stored in [Variant], which is the generic type used by the engine. The maximum value of [float] is approximately [code]1.79769e308[/code], and the minimum is approximately [code]-1.79769e308[/code].
+ The [float] built-in type is a 64-bit double-precision floating-point number, equivalent to [code]double[/code] in C++. This type has 14 reliable decimal digits of precision. The maximum value of [float] is approximately [code]1.79769e308[/code], and the minimum is approximately [code]-1.79769e308[/code].
Many methods and properties in the engine use 32-bit single-precision floating-point numbers instead, equivalent to [code]float[/code] in C++, which have 6 reliable decimal digits of precision. For data structures such as [Vector2] and [Vector3], Godot uses 32-bit floating-point numbers by default, but it can be changed to use 64-bit doubles if Godot is compiled with the [code]precision=double[/code] option.
- Math done using the [float] type is not guaranteed to be exact or deterministic, and will often result in small errors. You should usually use the [method @GlobalScope.is_equal_approx] and [method @GlobalScope.is_zero_approx] methods instead of [code]==[/code] to compare [float] values for equality.
+ Math done using the [float] type is not guaranteed to be exact and will often result in small errors. You should usually use the [method @GlobalScope.is_equal_approx] and [method @GlobalScope.is_zero_approx] methods instead of [code]==[/code] to compare [float] values for equality.
</description>
<tutorials>
<link title="Wikipedia: Double-precision floating-point format">https://en.wikipedia.org/wiki/Double-precision_floating-point_format</link>
@@ -67,7 +67,7 @@
<return type="Color" />
<param index="0" name="right" type="Color" />
<description>
- Multiplies each component of the [Color] by the given [float].
+ Multiplies each component of the [Color], including the alpha, by the given [float].
[codeblock]
print(1.5 * Color(0.5, 0.5, 0.5)) # Color(0.75, 0.75, 0.75)
[/codeblock]
diff --git a/doc/classes/int.xml b/doc/classes/int.xml
index ab624bb8a3..1bf318fe8e 100644
--- a/doc/classes/int.xml
+++ b/doc/classes/int.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="int" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Built-in integer Variant type.
+ A built-in type for integers.
</brief_description>
<description>
Signed 64-bit integer type. This means that it can take values from [code]-2^63[/code] to [code]2^63 - 1[/code], i.e. from [code]-9223372036854775808[/code] to [code]9223372036854775807[/code]. When it exceeds these bounds, it will wrap around.
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 19f2cfd47d..5d3e8ad39d 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -175,7 +175,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
state.light_uniforms[index].color[i] = l->color[i];
}
- state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate
+ state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
if (state.shadow_fb != 0) {
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
@@ -238,7 +238,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
state.light_uniforms[index].color[i] = l->color[i];
}
- state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate
+ state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
if (state.shadow_fb != 0) {
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index abf13fe5ab..29e9ada72b 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -268,10 +268,17 @@ void ShaderGLES3::_get_uniform_locations(Version::Specialization &spec, Version
}
}
// textures
- for (int i = 0; i < p_version->texture_uniforms.size(); i++) {
- String native_uniform_name = _mkid(p_version->texture_uniforms[i]);
+ int texture_index = 0;
+ for (uint32_t i = 0; i < p_version->texture_uniforms.size(); i++) {
+ String native_uniform_name = _mkid(p_version->texture_uniforms[i].name);
GLint location = glGetUniformLocation(spec.id, (native_uniform_name).ascii().get_data());
- glUniform1i(location, i + base_texture_index);
+ Vector<int32_t> texture_uniform_bindings;
+ int texture_count = p_version->texture_uniforms[i].array_size;
+ for (int j = 0; j < texture_count; j++) {
+ texture_uniform_bindings.append(texture_index + base_texture_index);
+ texture_index++;
+ }
+ glUniform1iv(location, texture_uniform_bindings.size(), texture_uniform_bindings.ptr());
}
glUseProgram(0);
@@ -674,7 +681,7 @@ void ShaderGLES3::_initialize_version(Version *p_version) {
_save_to_cache(p_version);
}
-void ShaderGLES3::version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize) {
+void ShaderGLES3::version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const LocalVector<ShaderGLES3::TextureUniformData> &p_texture_uniforms, bool p_initialize) {
Version *version = version_owner.get_or_null(p_version);
ERR_FAIL_COND(!version);
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index 565434bb36..c095c41e79 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -54,6 +54,12 @@
#include <stdio.h>
class ShaderGLES3 {
+public:
+ struct TextureUniformData {
+ StringName name;
+ int array_size;
+ };
+
protected:
struct TexUnitPair {
const char *name;
@@ -85,7 +91,7 @@ private:
// Specializations use #ifdefs to toggle behavior on and off for performance, on supporting hardware, they will compile a version with everything enabled, and then compile more copies to improve performance
// Use specializations to enable and disabled advanced features, use variants to toggle behavior when different data may be used (e.g. using a samplerArray vs a sampler, or doing a depth prepass vs a color pass)
struct Version {
- Vector<StringName> texture_uniforms;
+ LocalVector<TextureUniformData> texture_uniforms;
CharString uniforms;
CharString vertex_globals;
CharString fragment_globals;
@@ -242,7 +248,7 @@ protected:
public:
RID version_create();
- void version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize = false);
+ void version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const LocalVector<ShaderGLES3::TextureUniformData> &p_texture_uniforms, bool p_initialize = false);
bool version_is_valid(RID p_version);
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index ae3892fb61..e47e3ae9a3 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -648,7 +648,7 @@ void main() {
vec4 base_color = color;
#ifdef MODE_LIGHT_ONLY
- color = vec4(0.0);
+ float light_only_alpha = 0.0;
#elif !defined(MODE_UNSHADED)
color *= canvas_modulation;
#endif
@@ -691,6 +691,9 @@ void main() {
}
light_blend_compute(light_base, light_color, color.rgb);
+#ifdef MODE_LIGHT_ONLY
+ light_only_alpha += light_color.a;
+#endif
}
// Positional Lights
@@ -788,8 +791,15 @@ void main() {
}
light_blend_compute(light_base, light_color, color.rgb);
+#ifdef MODE_LIGHT_ONLY
+ light_only_alpha += light_color.a;
+#endif
}
#endif
+#ifdef MODE_LIGHT_ONLY
+ color.a *= light_only_alpha;
+#endif
+
frag_color = color;
}
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index db74708214..d92c1b94ae 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -2950,6 +2950,18 @@ void MaterialStorage::material_update_dependency(RID p_material, DependencyTrack
}
}
+LocalVector<ShaderGLES3::TextureUniformData> get_texture_uniform_data(const Vector<ShaderCompiler::GeneratedCode::Texture> &texture_uniforms) {
+ LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data;
+ for (int i = 0; i < texture_uniforms.size(); i++) {
+ int num_textures = texture_uniforms[i].array_size;
+ if (num_textures == 0) {
+ num_textures = 1;
+ }
+ texture_uniform_data.push_back({ texture_uniforms[i].name, num_textures });
+ }
+ return texture_uniform_data;
+}
+
/* Canvas Shader Data */
void CanvasShaderData::set_code(const String &p_code) {
@@ -3017,12 +3029,9 @@ void CanvasShaderData::set_code(const String &p_code) {
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
- Vector<StringName> texture_uniform_names;
- for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
- texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
- }
+ LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);
- MaterialStorage::get_singleton()->shaders.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+ MaterialStorage::get_singleton()->shaders.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_data);
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.canvas_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -3065,23 +3074,38 @@ void CanvasMaterialData::update_parameters(const HashMap<StringName, Variant> &p
update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size);
}
+static void bind_uniforms_generic(const Vector<RID> &p_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, int texture_offset = 0, const RS::CanvasItemTextureFilter *filter_mapping = filter_from_uniform, const RS::CanvasItemTextureRepeat *repeat_mapping = repeat_from_uniform) {
+ const RID *textures = p_textures.ptr();
+ const ShaderCompiler::GeneratedCode::Texture *texture_uniforms = p_texture_uniforms.ptr();
+ int texture_uniform_index = 0;
+ int texture_uniform_count = 0;
+ for (int ti = 0; ti < p_textures.size(); ti++) {
+ ERR_FAIL_COND_MSG(texture_uniform_index >= p_texture_uniforms.size(), "texture_uniform_index out of bounds");
+ GLES3::Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
+ const ShaderCompiler::GeneratedCode::Texture &texture_uniform = texture_uniforms[texture_uniform_index];
+ if (texture) {
+ glActiveTexture(GL_TEXTURE0 + texture_offset + ti);
+ glBindTexture(target_from_type[texture_uniform.type], texture->tex_id);
+ if (texture->render_target) {
+ texture->render_target->used_in_frame = true;
+ }
+
+ texture->gl_set_filter(filter_mapping[int(texture_uniform.filter)]);
+ texture->gl_set_repeat(repeat_mapping[int(texture_uniform.repeat)]);
+ }
+ texture_uniform_count++;
+ if (texture_uniform_count >= texture_uniform.array_size) {
+ texture_uniform_index++;
+ texture_uniform_count = 0;
+ }
+ }
+}
+
void CanvasMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_LOCATION, uniform_buffer);
- RID *textures = texture_cache.ptrw();
- ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
- for (int ti = 0; ti < texture_cache.size(); ti++) {
- Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
- glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is used by the base texture
- glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
- if (texture->render_target) {
- texture->render_target->used_in_frame = true;
- }
-
- texture->gl_set_filter(filter_from_uniform_canvas[int(texture_uniforms[ti].filter)]);
- texture->gl_set_repeat(repeat_from_uniform_canvas[int(texture_uniforms[ti].repeat)]);
- }
+ bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1, filter_from_uniform_canvas, repeat_from_uniform_canvas); // Start at GL_TEXTURE1 because texture slot 0 is used by the base texture
}
CanvasMaterialData::~CanvasMaterialData() {
@@ -3172,12 +3196,9 @@ void SkyShaderData::set_code(const String &p_code) {
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
- Vector<StringName> texture_uniform_names;
- for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
- texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
- }
+ LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);
- MaterialStorage::get_singleton()->shaders.sky_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+ MaterialStorage::get_singleton()->shaders.sky_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_data);
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.sky_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -3235,19 +3256,7 @@ void SkyMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
- RID *textures = texture_cache.ptrw();
- ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
- for (int ti = 0; ti < texture_cache.size(); ti++) {
- Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
- glActiveTexture(GL_TEXTURE0 + ti);
- glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
- if (texture->render_target) {
- texture->render_target->used_in_frame = true;
- }
-
- texture->gl_set_filter(filter_from_uniform[int(texture_uniforms[ti].filter)]);
- texture->gl_set_repeat(repeat_from_uniform[int(texture_uniforms[ti].repeat)]);
- }
+ bind_uniforms_generic(texture_cache, shader_data->texture_uniforms);
}
////////////////////////////////////////////////////////////////////////////////
@@ -3435,12 +3444,9 @@ void SceneShaderData::set_code(const String &p_code) {
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
- Vector<StringName> texture_uniform_names;
- for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
- texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
- }
+ LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);
- MaterialStorage::get_singleton()->shaders.scene_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+ MaterialStorage::get_singleton()->shaders.scene_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_data);
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.scene_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -3517,19 +3523,7 @@ void SceneMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
- RID *textures = texture_cache.ptrw();
- ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
- for (int ti = 0; ti < texture_cache.size(); ti++) {
- Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
- glActiveTexture(GL_TEXTURE0 + ti);
- glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
- if (texture->render_target) {
- texture->render_target->used_in_frame = true;
- }
-
- texture->gl_set_filter(filter_from_uniform[int(texture_uniforms[ti].filter)]);
- texture->gl_set_repeat(repeat_from_uniform[int(texture_uniforms[ti].repeat)]);
- }
+ bind_uniforms_generic(texture_cache, shader_data->texture_uniforms);
}
/* Particles SHADER */
@@ -3575,12 +3569,9 @@ void ParticlesShaderData::set_code(const String &p_code) {
}
}
- Vector<StringName> texture_uniform_names;
- for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
- texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
- }
+ LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);
- MaterialStorage::get_singleton()->shaders.particles_process_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+ MaterialStorage::get_singleton()->shaders.particles_process_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_data);
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.particles_process_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -3631,19 +3622,7 @@ void ParticleProcessMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, GLES3::PARTICLES_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
- RID *textures = texture_cache.ptrw();
- ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
- for (int ti = 0; ti < texture_cache.size(); ti++) {
- Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
- glActiveTexture(GL_TEXTURE1 + ti); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture.
- glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
- if (texture->render_target) {
- texture->render_target->used_in_frame = true;
- }
-
- texture->gl_set_filter(filter_from_uniform[int(texture_uniforms[ti].filter)]);
- texture->gl_set_repeat(repeat_from_uniform[int(texture_uniforms[ti].repeat)]);
- }
+ bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture.
}
#endif // !GLES3_ENABLED
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 3fd54e9180..14c2b3166f 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -751,7 +751,53 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
}
void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
- texture_owner.initialize_rid(p_texture, Texture());
+ ERR_FAIL_COND(p_layers.is_empty());
+
+ ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
+ ERR_FAIL_COND_MSG(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY, "Cubemap Arrays are not supported in the GL Compatibility backend.");
+
+ Ref<Image> image = p_layers[0];
+ {
+ int valid_width = 0;
+ int valid_height = 0;
+ bool valid_mipmaps = false;
+ Image::Format valid_format = Image::FORMAT_MAX;
+
+ for (int i = 0; i < p_layers.size(); i++) {
+ ERR_FAIL_COND(p_layers[i]->is_empty());
+
+ if (i == 0) {
+ valid_width = p_layers[i]->get_width();
+ valid_height = p_layers[i]->get_height();
+ valid_format = p_layers[i]->get_format();
+ valid_mipmaps = p_layers[i]->has_mipmaps();
+ } else {
+ ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);
+ ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);
+ ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);
+ ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);
+ }
+ }
+ }
+
+ Texture texture;
+ texture.width = image->get_width();
+ texture.height = image->get_height();
+ texture.alloc_width = texture.width;
+ texture.alloc_height = texture.height;
+ texture.mipmaps = image->get_mipmap_count() + 1;
+ texture.format = image->get_format();
+ texture.type = Texture::TYPE_LAYERED;
+ texture.layered_type = p_layered_type;
+ texture.target = GL_TEXTURE_2D_ARRAY;
+ texture.layers = p_layers.size();
+ _get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
+ texture.active = true;
+ glGenTextures(1, &texture.tex_id);
+ texture_owner.initialize_rid(p_texture, texture);
+ for (int i = 0; i < p_layers.size(); i++) {
+ _texture_set_data(p_texture, p_layers[i], 1, i == 0);
+ }
}
void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
@@ -1148,6 +1194,10 @@ uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) c
}
void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {
+ _texture_set_data(p_texture, p_image, p_layer, false);
+}
+
+void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool initialize) {
Texture *texture = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND(!texture);
@@ -1257,6 +1307,9 @@ void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image,
} else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (texture->target == GL_TEXTURE_2D_ARRAY) {
+ if (initialize) {
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, format, type, nullptr);
+ }
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 0, format, type, &read[ofs]);
} else {
glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index c6bdd39dbd..2b939aa7fa 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -451,6 +451,8 @@ private:
void _render_target_clear_sdf(RenderTarget *rt);
Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const;
+ void _texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool initialize);
+
struct RenderTargetSDF {
CanvasSdfShaderGLES3 shader;
RID shader_version;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 43fc581023..fe45894c52 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1026,7 +1026,6 @@ void CodeTextEditor::update_editor_settings() {
// Appearance: Gutters
text_editor->set_draw_line_numbers(EDITOR_GET("text_editor/appearance/gutters/show_line_numbers"));
text_editor->set_line_numbers_zero_padded(EDITOR_GET("text_editor/appearance/gutters/line_numbers_zero_padded"));
- text_editor->set_draw_bookmarks_gutter(EDITOR_GET("text_editor/appearance/gutters/show_bookmark_gutter"));
// Appearance: Minimap
text_editor->set_draw_minimap(EDITOR_GET("text_editor/appearance/minimap/show_minimap"));
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index aaf106a1c7..6d345a1d84 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -291,12 +291,13 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
p_type_category == TypeCategory::OTHER_TYPE;
bool is_virtual = ClassDB::class_exists(p_type) && ClassDB::is_virtual(p_type);
+ r_item->set_meta(SNAME("__instantiable"), can_instantiate && !is_virtual);
+
if (can_instantiate && !is_virtual) {
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
} else {
r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled"));
r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
- r_item->set_selectable(0, false);
}
bool is_deprecated = EditorHelp::get_doc_data()->class_list[p_type].is_deprecated;
@@ -395,6 +396,11 @@ void CreateDialog::_confirmed() {
return;
}
+ TreeItem *selected = search_options->get_selected();
+ if (!selected->get_meta("__instantiable", true)) {
+ return;
+ }
+
{
Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("create_recent." + base_type), FileAccess::WRITE);
if (f.is_valid()) {
@@ -421,7 +427,7 @@ void CreateDialog::_text_changed(const String &p_newtext) {
void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
Ref<InputEventKey> k = p_ie;
- if (k.is_valid()) {
+ if (k.is_valid() && k->is_pressed()) {
switch (k->get_keycode()) {
case Key::UP:
case Key::DOWN:
@@ -430,6 +436,13 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
search_options->gui_input(k);
search_box->accept_event();
} break;
+ case Key::SPACE: {
+ TreeItem *ti = search_options->get_selected();
+ if (ti) {
+ ti->set_collapsed(!ti->is_collapsed());
+ }
+ search_box->accept_event();
+ } break;
default:
break;
}
diff --git a/editor/editor_builders.py b/editor/editor_builders.py
index 2a4f79548f..ce6abeb07a 100644
--- a/editor/editor_builders.py
+++ b/editor/editor_builders.py
@@ -37,6 +37,7 @@ def make_doc_header(target, source, env):
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _DOC_DATA_RAW_H\n")
g.write("#define _DOC_DATA_RAW_H\n")
+ g.write('static const char *_doc_data_hash = "' + str(hash(buf)) + '";\n')
g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
g.write("static const unsigned char _doc_data_compressed[] = {\n")
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 5d3037b4ec..596a2dfac1 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -485,6 +485,24 @@ EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
return editor_plugins[p_idx];
}
+void EditorData::add_extension_editor_plugin(const StringName &p_class_name, EditorPlugin *p_plugin) {
+ ERR_FAIL_COND(extension_editor_plugins.has(p_class_name));
+ extension_editor_plugins.insert(p_class_name, p_plugin);
+}
+
+void EditorData::remove_extension_editor_plugin(const StringName &p_class_name) {
+ extension_editor_plugins.erase(p_class_name);
+}
+
+bool EditorData::has_extension_editor_plugin(const StringName &p_class_name) {
+ return extension_editor_plugins.has(p_class_name);
+}
+
+EditorPlugin *EditorData::get_extension_editor_plugin(const StringName &p_class_name) {
+ EditorPlugin **plugin = extension_editor_plugins.getptr(p_class_name);
+ return plugin == nullptr ? nullptr : *plugin;
+}
+
void EditorData::add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon) {
ERR_FAIL_COND_MSG(p_script.is_null(), "It's not a reference to a valid Script object.");
CustomType ct;
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 7ca04b5680..28fe13e537 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -124,6 +124,7 @@ public:
private:
Vector<EditorPlugin *> editor_plugins;
+ HashMap<StringName, EditorPlugin *> extension_editor_plugins;
struct PropertyData {
String name;
@@ -170,6 +171,11 @@ public:
int get_editor_plugin_count() const;
EditorPlugin *get_editor_plugin(int p_idx);
+ void add_extension_editor_plugin(const StringName &p_class_name, EditorPlugin *p_plugin);
+ void remove_extension_editor_plugin(const StringName &p_class_name);
+ bool has_extension_editor_plugin(const StringName &p_class_name);
+ EditorPlugin *get_extension_editor_plugin(const StringName &p_class_name);
+
void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks should have this signature: void (Object* undo_redo, Object *modified_object, String property, Variant new_value)
void remove_undo_redo_inspector_hook_callback(Callable p_callable);
const Vector<Callable> get_undo_redo_inspector_hook_callback();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 2b8cace2f1..17aa763983 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -2258,7 +2258,7 @@ String EditorHelp::get_cache_full_path() {
static bool first_attempt = true;
static String _compute_doc_version_hash() {
- return uitos(ClassDB::get_api_hash(ClassDB::API_CORE)) + "-" + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR));
+ return vformat("%d/%d/%s", ClassDB::get_api_hash(ClassDB::API_CORE), ClassDB::get_api_hash(ClassDB::API_EDITOR), _doc_data_hash);
}
void EditorHelp::_load_doc_thread(void *p_udata) {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 415193c6d5..2e86979039 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1341,11 +1341,7 @@ void EditorInspectorSection::_notification(int p_what) {
Color light_font_color = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
// Can we fit the long version of the revertable count text?
- if (revertable_properties.size() == 1) {
- num_revertable_str = "(1 change)";
- } else {
- num_revertable_str = vformat("(%d changes)", revertable_properties.size());
- }
+ num_revertable_str = vformat(TTRN("(%d change)", "(%d changes)", revertable_properties.size()), revertable_properties.size());
num_revertable_width = light_font->get_string_size(num_revertable_str, HORIZONTAL_ALIGNMENT_LEFT, -1.0f, light_font_size, TextServer::JUSTIFICATION_NONE).x;
if (label_width + separation + num_revertable_width > available) {
// We'll have to use the short version.
@@ -2813,18 +2809,22 @@ void EditorInspector::update_tree() {
category->label = label;
if (use_doc_hints) {
+ String descr = "";
// Sets the category tooltip to show documentation.
if (!class_descr_cache.has(doc_name)) {
- String descr;
DocTools *dd = EditorHelp::get_doc_data();
HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(doc_name);
if (E) {
descr = DTR(E->value.brief_description);
}
- class_descr_cache[doc_name] = descr;
+ if (ClassDB::class_exists(doc_name)) {
+ class_descr_cache[doc_name] = descr; // Do not cache the class description of scripts.
+ }
+ } else {
+ descr = class_descr_cache[doc_name];
}
- category->set_tooltip_text(p.name + "::" + (class_descr_cache[doc_name].is_empty() ? "" : class_descr_cache[doc_name]));
+ category->set_tooltip_text(p.name + "::" + descr);
}
// Add editors at the start of a category.
@@ -3217,7 +3217,9 @@ void EditorInspector::update_tree() {
}
}
- doc_info_cache[classname][propname] = doc_info;
+ if (ClassDB::class_exists(classname)) {
+ doc_info_cache[classname][propname] = doc_info; // Do not cache the doc information of scripts.
+ }
}
}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 191f28fe46..1ce31e59ac 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -149,6 +149,7 @@ public:
Object *get_edited_object();
StringName get_edited_property() const;
+ inline Variant get_edited_property_value() const { return object->get(property); }
EditorInspector *get_parent_inspector() const;
void set_doc_path(const String &p_doc_path);
diff --git a/editor/editor_interface.h b/editor/editor_interface.h
index 1436bf83af..95fa0dd64f 100644
--- a/editor/editor_interface.h
+++ b/editor/editor_interface.h
@@ -41,6 +41,7 @@ class EditorCommandPalette;
class EditorFileSystem;
class EditorInspector;
class EditorPaths;
+class EditorPlugin;
class EditorResourcePreview;
class EditorSelection;
class EditorSettings;
@@ -83,6 +84,9 @@ public:
void set_plugin_enabled(const String &p_plugin, bool p_enabled);
bool is_plugin_enabled(const String &p_plugin) const;
+ void add_editor_plugin(EditorPlugin *p_plugin);
+ void remove_editor_plugin(EditorPlugin *p_plugin);
+
// Editor GUI.
Control *get_base_control() const;
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 7431166291..b37debbd70 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -389,6 +389,7 @@ EditorLog::EditorLog() {
// Log - Rich Text Label.
log = memnew(RichTextLabel);
+ log->set_threaded(true);
log->set_use_bbcode(true);
log->set_scroll_follow(true);
log->set_selection_enabled(true);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ce7702d5b0..188b01ff94 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -789,6 +789,7 @@ void EditorNode::_notification(int p_what) {
help_menu->set_item_icon(help_menu->get_item_index(HELP_DOCS), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
help_menu->set_item_icon(help_menu->get_item_index(HELP_QA), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
help_menu->set_item_icon(help_menu->get_item_index(HELP_REPORT_A_BUG), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
+ help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), gui_base->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")));
help_menu->set_item_icon(help_menu->get_item_index(HELP_SUGGEST_A_FEATURE), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
help_menu->set_item_icon(help_menu->get_item_index(HELP_SEND_DOCS_FEEDBACK), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
help_menu->set_item_icon(help_menu->get_item_index(HELP_COMMUNITY), gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
@@ -2895,6 +2896,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case HELP_REPORT_A_BUG: {
OS::get_singleton()->shell_open("https://github.com/godotengine/godot/issues");
} break;
+ case HELP_COPY_SYSTEM_INFO: {
+ String info = _get_system_info();
+ DisplayServer::get_singleton()->clipboard_set(info);
+ } break;
case HELP_SUGGEST_A_FEATURE: {
OS::get_singleton()->shell_open("https://github.com/godotengine/godot-proposals#readme");
} break;
@@ -3239,6 +3244,30 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan
}
}
+void EditorNode::add_extension_editor_plugin(const StringName &p_class_name) {
+ ERR_FAIL_COND_MSG(!ClassDB::class_exists(p_class_name), vformat("No such editor plugin registered: %s", p_class_name));
+ ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_class_name, SNAME("EditorPlugin")), vformat("Class is not an editor plugin: %s", p_class_name));
+ ERR_FAIL_COND_MSG(singleton->editor_data.has_extension_editor_plugin(p_class_name), vformat("Editor plugin already added for class: %s", p_class_name));
+
+ EditorPlugin *plugin = Object::cast_to<EditorPlugin>(ClassDB::instantiate(p_class_name));
+ singleton->editor_data.add_extension_editor_plugin(p_class_name, plugin);
+ add_editor_plugin(plugin);
+}
+
+void EditorNode::remove_extension_editor_plugin(const StringName &p_class_name) {
+ // If we're exiting, the editor plugins will get cleaned up anyway, so don't do anything.
+ if (singleton->exiting) {
+ return;
+ }
+
+ ERR_FAIL_COND_MSG(!singleton->editor_data.has_extension_editor_plugin(p_class_name), vformat("No editor plugin added for class: %s", p_class_name));
+
+ EditorPlugin *plugin = singleton->editor_data.get_extension_editor_plugin(p_class_name);
+ remove_editor_plugin(plugin);
+ memfree(plugin);
+ singleton->editor_data.remove_extension_editor_plugin(p_class_name);
+}
+
void EditorNode::_update_addon_config() {
if (_initializing_plugins) {
return;
@@ -4331,6 +4360,98 @@ void EditorNode::progress_end_task_bg(const String &p_task) {
singleton->progress_hb->end_task(p_task);
}
+String EditorNode::_get_system_info() const {
+ String distribution_name = OS::get_singleton()->get_distribution_name();
+ if (distribution_name.is_empty()) {
+ distribution_name = OS::get_singleton()->get_name();
+ }
+ if (distribution_name.is_empty()) {
+ distribution_name = "Other";
+ }
+ const String distribution_version = OS::get_singleton()->get_version();
+
+ String godot_version = "Godot v" + String(VERSION_FULL_CONFIG);
+ if (String(VERSION_BUILD) != "official") {
+ String hash = String(VERSION_HASH);
+ hash = hash.is_empty() ? String("unknown") : vformat("(%s)", hash.left(9));
+ godot_version += " " + hash;
+ }
+
+ String driver_name = GLOBAL_GET("rendering/rendering_device/driver");
+ String rendering_method = GLOBAL_GET("rendering/renderer/rendering_method");
+
+ const String rendering_device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name();
+
+ RenderingDevice::DeviceType device_type = RenderingServer::get_singleton()->get_video_adapter_type();
+ String device_type_string;
+ switch (device_type) {
+ case RenderingDevice::DeviceType::DEVICE_TYPE_INTEGRATED_GPU:
+ device_type_string = "integrated";
+ break;
+ case RenderingDevice::DeviceType::DEVICE_TYPE_DISCRETE_GPU:
+ device_type_string = "dedicated";
+ break;
+ case RenderingDevice::DeviceType::DEVICE_TYPE_VIRTUAL_GPU:
+ device_type_string = "virtual";
+ break;
+ case RenderingDevice::DeviceType::DEVICE_TYPE_CPU:
+ device_type_string = "(software emulation on CPU)";
+ break;
+ case RenderingDevice::DeviceType::DEVICE_TYPE_OTHER:
+ case RenderingDevice::DeviceType::DEVICE_TYPE_MAX:
+ break; // Can't happen, but silences warning for DEVICE_TYPE_MAX
+ }
+
+ const Vector<String> video_adapter_driver_info = OS::get_singleton()->get_video_adapter_driver_info();
+
+ const String processor_name = OS::get_singleton()->get_processor_name();
+ const int processor_count = OS::get_singleton()->get_processor_count();
+
+ // Prettify
+ if (driver_name == "vulkan") {
+ driver_name = "Vulkan";
+ } else if (driver_name == "opengl3") {
+ driver_name = "GLES3";
+ }
+ if (rendering_method == "forward_plus") {
+ rendering_method = "Forward+";
+ } else if (rendering_method == "mobile") {
+ rendering_method = "Mobile";
+ } else if (rendering_method == "gl_compatibility") {
+ rendering_method = "Compatibility";
+ }
+
+ // Join info.
+ Vector<String> info;
+ info.push_back(godot_version);
+ if (!distribution_version.is_empty()) {
+ info.push_back(distribution_name + " " + distribution_version);
+ } else {
+ info.push_back(distribution_name);
+ }
+ info.push_back(vformat("%s (%s)", driver_name, rendering_method));
+
+ String graphics;
+ if (!device_type_string.is_empty()) {
+ graphics = device_type_string + " ";
+ }
+ graphics += rendering_device_name;
+ if (video_adapter_driver_info.size() == 2) { // This vector is always either of length 0 or 2.
+ String vad_name = video_adapter_driver_info[0];
+ String vad_version = video_adapter_driver_info[1]; // Version could be potentially empty on Linux/BSD.
+ if (!vad_version.is_empty()) {
+ graphics += vformat(" (%s; %s)", vad_name, vad_version);
+ } else {
+ graphics += vformat(" (%s)", vad_name);
+ }
+ }
+ info.push_back(graphics);
+
+ info.push_back(vformat("%s (%d Threads)", processor_name, processor_count));
+
+ return String(" - ").join(info);
+}
+
Ref<Texture2D> EditorNode::_file_dialog_get_icon(const String &p_path) {
EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem_path(p_path.get_base_dir());
if (efsd) {
@@ -4818,8 +4939,13 @@ void EditorNode::_load_editor_layout() {
Ref<ConfigFile> config;
config.instantiate();
Error err = config->load(EditorPaths::get_singleton()->get_project_settings_dir().path_join("editor_layout.cfg"));
- if (err != OK) {
- // No config.
+ if (err != OK) { // No config.
+ // If config is not found, expand the res:// folder by default.
+ TreeItem *root = FileSystemDock::get_singleton()->get_tree_control()->get_item_with_metadata("res://", 0);
+ if (root) {
+ root->set_collapsed(false);
+ }
+
if (overridden_default_layout >= 0) {
_layout_menu_option(overridden_default_layout);
}
@@ -5086,8 +5212,14 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String
}
// Restore collapsed state of FileSystemDock.
+ PackedStringArray uncollapsed_tis;
if (p_layout->has_section_key(p_section, "dock_filesystem_uncollapsed_paths")) {
- PackedStringArray uncollapsed_tis = p_layout->get_value(p_section, "dock_filesystem_uncollapsed_paths");
+ uncollapsed_tis = p_layout->get_value(p_section, "dock_filesystem_uncollapsed_paths");
+ } else {
+ uncollapsed_tis = { "res://" };
+ }
+
+ if (!uncollapsed_tis.is_empty()) {
for (int i = 0; i < uncollapsed_tis.size(); i++) {
TreeItem *uncollapsed_ti = FileSystemDock::get_singleton()->get_tree_control()->get_item_with_metadata(uncollapsed_tis[i], 0);
if (uncollapsed_ti) {
@@ -6860,6 +6992,7 @@ EditorNode::EditorNode() {
resource_preview = memnew(EditorResourcePreview);
add_child(resource_preview);
progress_dialog = memnew(ProgressDialog);
+ progress_dialog->set_unparent_when_invisible(true);
// Take up all screen.
gui_base->set_anchor(SIDE_RIGHT, Control::ANCHOR_END);
@@ -7256,14 +7389,8 @@ EditorNode::EditorNode() {
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/project_settings", TTR("Project Settings..."), Key::NONE, TTR("Project Settings")), RUN_SETTINGS);
project_menu->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
- vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
- vcs_actions_menu->set_name("Version Control");
- vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option));
project_menu->add_separator();
- project_menu->add_child(vcs_actions_menu);
- project_menu->add_submenu_item(TTR("Version Control"), "Version Control");
- vcs_actions_menu->add_item(TTR("Create Version Control Metadata"), RUN_VCS_METADATA);
- vcs_actions_menu->add_item(TTR("Version Control Settings"), RUN_VCS_SETTINGS);
+ project_menu->add_item(TTR("Version Control"), VCS_MENU);
project_menu->add_separator();
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTR("Export..."), Key::NONE, TTR("Export")), FILE_EXPORT_PROJECT);
@@ -7383,6 +7510,8 @@ EditorNode::EditorNode() {
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/online_docs", TTR("Online Documentation")), HELP_DOCS);
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/q&a", TTR("Questions & Answers")), HELP_QA);
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG);
+ help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/copy_system_info", TTR("Copy System Info")), HELP_COPY_SYSTEM_INFO);
+ help_menu->set_item_tooltip(-1, TTR("Copies the system info as a single-line text into the clipboard."));
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/suggest_a_feature", TTR("Suggest a Feature")), HELP_SUGGEST_A_FEATURE);
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK);
help_menu->add_icon_shortcut(gui_base->get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_SHORTCUT_AND_COMMAND("editor/community", TTR("Community")), HELP_COMMUNITY);
@@ -7762,12 +7891,27 @@ EditorNode::EditorNode() {
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
+
+ vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
+ vcs_actions_menu->set_name("Version Control");
+ vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option));
+ vcs_actions_menu->add_item(TTR("Create Version Control Metadata"), RUN_VCS_METADATA);
+ vcs_actions_menu->add_item(TTR("Version Control Settings"), RUN_VCS_SETTINGS);
+ project_menu->add_child(vcs_actions_menu);
+ project_menu->set_item_submenu(project_menu->get_item_index(VCS_MENU), "Version Control");
+
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i));
}
+ for (const StringName &extension_class_name : GDExtensionEditorPlugins::get_extension_classes()) {
+ add_extension_editor_plugin(extension_class_name);
+ }
+ GDExtensionEditorPlugins::editor_node_add_plugin = &EditorNode::add_extension_editor_plugin;
+ GDExtensionEditorPlugins::editor_node_remove_plugin = &EditorNode::remove_extension_editor_plugin;
+
for (int i = 0; i < plugin_init_callback_count; i++) {
plugin_init_callbacks[i]();
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 66da019560..edcad7e4d1 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -195,6 +195,7 @@ private:
RUN_USER_DATA_FOLDER,
RELOAD_CURRENT_PROJECT,
RUN_PROJECT_MANAGER,
+ VCS_MENU,
RUN_VCS_METADATA,
RUN_VCS_SETTINGS,
SETTINGS_UPDATE_CONTINUOUSLY,
@@ -225,6 +226,7 @@ private:
HELP_DOCS,
HELP_QA,
HELP_REPORT_A_BUG,
+ HELP_COPY_SYSTEM_INFO,
HELP_SUGGEST_A_FEATURE,
HELP_SEND_DOCS_FEEDBACK,
HELP_COMMUNITY,
@@ -503,6 +505,8 @@ private:
static int plugin_init_callback_count;
static Vector<EditorNodeInitCallback> _init_callbacks;
+ String _get_system_info() const;
+
static void _dependency_error_report(const String &p_path, const String &p_dep, const String &p_type) {
DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id());
if (!singleton->dependency_errors.has(p_path)) {
@@ -739,6 +743,9 @@ public:
static void add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
static void remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
+ static void add_extension_editor_plugin(const StringName &p_class_name);
+ static void remove_extension_editor_plugin(const StringName &p_class_name);
+
static void add_plugin_init_callback(EditorPluginInitializeCallback p_callback);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
static void add_build_callback(EditorBuildCallback p_callback);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index fffdec512c..0484a2efc9 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -95,7 +95,7 @@ void EditorPropertyText::_text_changed(const String &p_string) {
}
void EditorPropertyText::update_property() {
- String s = get_edited_object()->get(get_edited_property());
+ String s = get_edited_property_value();
updating = true;
if (text->get_text() != s) {
int caret = text->get_caret_column();
@@ -108,6 +108,13 @@ void EditorPropertyText::update_property() {
void EditorPropertyText::set_string_name(bool p_enabled) {
string_name = p_enabled;
+ if (p_enabled) {
+ Label *prefix = memnew(Label("&"));
+ prefix->set_tooltip_text("StringName");
+ prefix->set_mouse_filter(MOUSE_FILTER_STOP);
+ text->get_parent()->add_child(prefix);
+ text->get_parent()->move_child(prefix, 0);
+ }
}
void EditorPropertyText::set_secret(bool p_enabled) {
@@ -122,9 +129,13 @@ void EditorPropertyText::_bind_methods() {
}
EditorPropertyText::EditorPropertyText() {
+ HBoxContainer *hb = memnew(HBoxContainer);
+ add_child(hb);
+
text = memnew(LineEdit);
- add_child(text);
+ hb->add_child(text);
add_focusable(text);
+ text->set_h_size_flags(SIZE_EXPAND_FILL);
text->connect("text_changed", callable_mp(this, &EditorPropertyText::_text_changed));
text->connect("text_submitted", callable_mp(this, &EditorPropertyText::_text_submitted));
}
@@ -167,7 +178,7 @@ void EditorPropertyMultilineText::_open_big_text() {
}
void EditorPropertyMultilineText::update_property() {
- String t = get_edited_object()->get(get_edited_property());
+ String t = get_edited_property_value();
if (text->get_text() != t) {
text->set_text(t);
if (big_text && big_text->is_visible_in_tree()) {
@@ -270,14 +281,14 @@ void EditorPropertyTextEnum::_custom_value_accepted() {
}
void EditorPropertyTextEnum::_custom_value_canceled() {
- custom_value_edit->set_text(get_edited_object()->get(get_edited_property()));
+ custom_value_edit->set_text(get_edited_property_value());
edit_custom_layout->hide();
default_layout->show();
}
void EditorPropertyTextEnum::update_property() {
- String current_value = get_edited_object()->get(get_edited_property());
+ String current_value = get_edited_property_value();
int default_option = options.find(current_value);
// The list can change in the loose mode.
@@ -405,13 +416,13 @@ void EditorPropertyLocale::_locale_pressed() {
add_child(dialog);
}
- String locale_code = get_edited_object()->get(get_edited_property());
+ String locale_code = get_edited_property_value();
dialog->set_locale(locale_code);
dialog->popup_locale_dialog();
}
void EditorPropertyLocale::update_property() {
- String locale_code = get_edited_object()->get(get_edited_property());
+ String locale_code = get_edited_property_value();
locale->set_text(locale_code);
locale->set_tooltip_text(locale_code);
}
@@ -472,7 +483,7 @@ void EditorPropertyPath::_path_pressed() {
add_child(dialog);
}
- String full_path = get_edited_object()->get(get_edited_property());
+ String full_path = get_edited_property_value();
dialog->clear_filters();
@@ -500,7 +511,7 @@ void EditorPropertyPath::_path_pressed() {
}
void EditorPropertyPath::update_property() {
- String full_path = get_edited_object()->get(get_edited_property());
+ String full_path = get_edited_property_value();
path->set_text(full_path);
path->set_tooltip_text(full_path);
}
@@ -603,7 +614,7 @@ void EditorPropertyClassName::setup(const String &p_base_type, const String &p_s
}
void EditorPropertyClassName::update_property() {
- String s = get_edited_object()->get(get_edited_property());
+ String s = get_edited_property_value();
property->set_text(s);
selected_type = s;
}
@@ -645,7 +656,7 @@ void EditorPropertyCheck::_checkbox_pressed() {
}
void EditorPropertyCheck::update_property() {
- bool c = get_edited_object()->get(get_edited_property());
+ bool c = get_edited_property_value();
checkbox->set_pressed(c);
checkbox->set_disabled(is_read_only());
}
@@ -673,7 +684,7 @@ void EditorPropertyEnum::_option_selected(int p_which) {
}
void EditorPropertyEnum::update_property() {
- Variant current = get_edited_object()->get(get_edited_property());
+ Variant current = get_edited_property_value();
if (current.get_type() == Variant::NIL) {
options->select(-1);
return;
@@ -728,7 +739,7 @@ void EditorPropertyFlags::_set_read_only(bool p_read_only) {
}
void EditorPropertyFlags::_flag_toggled(int p_index) {
- uint32_t value = get_edited_object()->get(get_edited_property());
+ uint32_t value = get_edited_property_value();
if (flags[p_index]->is_pressed()) {
value |= flag_values[p_index];
} else {
@@ -739,7 +750,7 @@ void EditorPropertyFlags::_flag_toggled(int p_index) {
}
void EditorPropertyFlags::update_property() {
- uint32_t value = get_edited_object()->get(get_edited_property());
+ uint32_t value = get_edited_property_value();
for (int i = 0; i < flags.size(); i++) {
flags[i]->set_pressed((value & flag_values[i]) == flag_values[i]);
@@ -1110,7 +1121,7 @@ void EditorPropertyLayers::_grid_changed(uint32_t p_grid) {
}
void EditorPropertyLayers::update_property() {
- uint32_t value = get_edited_object()->get(get_edited_property());
+ uint32_t value = get_edited_property_value();
grid->set_flag(value);
}
@@ -1292,7 +1303,7 @@ void EditorPropertyInteger::_value_changed(int64_t val) {
}
void EditorPropertyInteger::update_property() {
- int64_t val = get_edited_object()->get(get_edited_property());
+ int64_t val = get_edited_property_value();
setting = true;
spin->set_value(val);
setting = false;
@@ -1332,7 +1343,7 @@ void EditorPropertyObjectID::_set_read_only(bool p_read_only) {
}
void EditorPropertyObjectID::_edit_pressed() {
- emit_signal(SNAME("object_id_selected"), get_edited_property(), get_edited_object()->get(get_edited_property()));
+ emit_signal(SNAME("object_id_selected"), get_edited_property(), get_edited_property_value());
}
void EditorPropertyObjectID::update_property() {
@@ -1341,7 +1352,7 @@ void EditorPropertyObjectID::update_property() {
type = "Object";
}
- ObjectID id = get_edited_object()->get(get_edited_property());
+ ObjectID id = get_edited_property_value();
if (id.is_valid()) {
edit->set_text(type + " ID: " + uitos(id));
edit->set_tooltip_text(type + " ID: " + uitos(id));
@@ -1373,14 +1384,14 @@ EditorPropertyObjectID::EditorPropertyObjectID() {
///////////////////// SIGNAL /////////////////////////
void EditorPropertySignal::_edit_pressed() {
- Signal signal = get_edited_object()->get(get_edited_property());
+ Signal signal = get_edited_property_value();
emit_signal(SNAME("object_id_selected"), get_edited_property(), signal.get_object_id());
}
void EditorPropertySignal::update_property() {
String type = base_type;
- Signal signal = get_edited_object()->get(get_edited_property());
+ Signal signal = get_edited_property_value();
edit->set_text("Signal: " + signal.get_name());
edit->set_disabled(false);
@@ -1402,7 +1413,7 @@ EditorPropertySignal::EditorPropertySignal() {
void EditorPropertyCallable::update_property() {
String type = base_type;
- Callable callable = get_edited_object()->get(get_edited_property());
+ Callable callable = get_edited_property_value();
edit->set_text("Callable");
edit->set_disabled(true);
@@ -1436,7 +1447,7 @@ void EditorPropertyFloat::_value_changed(double val) {
}
void EditorPropertyFloat::update_property() {
- double val = get_edited_object()->get(get_edited_property());
+ double val = get_edited_property_value();
if (angle_in_radians) {
val = Math::rad_to_deg(val);
}
@@ -1513,7 +1524,7 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
rel = -rel;
}
- float val = get_edited_object()->get(get_edited_property());
+ float val = get_edited_property_value();
bool sg = val < 0;
val = Math::absf(val);
@@ -1548,7 +1559,7 @@ void EditorPropertyEasing::_draw_easing() {
const int point_count = 48;
- const float exp = get_edited_object()->get(get_edited_property());
+ const float exp = get_edited_property_value();
const Ref<Font> f = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
@@ -1602,7 +1613,7 @@ void EditorPropertyEasing::_set_preset(int p_preset) {
void EditorPropertyEasing::_setup_spin() {
setting = true;
spin->setup_and_show();
- spin->get_line_edit()->set_text(TS->format_number(rtos(get_edited_object()->get(get_edited_property()))));
+ spin->get_line_edit()->set_text(TS->format_number(rtos(get_edited_property_value())));
setting = false;
spin->show();
}
@@ -1721,7 +1732,7 @@ void EditorPropertyVector2::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector2::update_property() {
- Vector2 val = get_edited_object()->get(get_edited_property());
+ Vector2 val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -1842,7 +1853,7 @@ void EditorPropertyRect2::_value_changed(double val, const String &p_name) {
}
void EditorPropertyRect2::update_property() {
- Rect2 val = get_edited_object()->get(get_edited_property());
+ Rect2 val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.position.x);
spin[1]->set_value(val.position.y);
@@ -1968,7 +1979,7 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector3::update_property() {
- update_using_vector(get_edited_object()->get(get_edited_property()));
+ update_using_vector(get_edited_property_value());
_update_ratio();
}
@@ -2134,7 +2145,7 @@ void EditorPropertyVector2i::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector2i::update_property() {
- Vector2i val = get_edited_object()->get(get_edited_property());
+ Vector2i val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -2254,7 +2265,7 @@ void EditorPropertyRect2i::_value_changed(double val, const String &p_name) {
}
void EditorPropertyRect2i::update_property() {
- Rect2i val = get_edited_object()->get(get_edited_property());
+ Rect2i val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.position.x);
spin[1]->set_value(val.position.y);
@@ -2374,7 +2385,7 @@ void EditorPropertyVector3i::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector3i::update_property() {
- Vector3i val = get_edited_object()->get(get_edited_property());
+ Vector3i val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -2506,7 +2517,7 @@ void EditorPropertyPlane::_value_changed(double val, const String &p_name) {
}
void EditorPropertyPlane::update_property() {
- Plane val = get_edited_object()->get(get_edited_property());
+ Plane val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.normal.x);
spin[1]->set_value(val.normal.y);
@@ -2647,7 +2658,7 @@ bool EditorPropertyQuaternion::is_grabbing_euler() {
}
void EditorPropertyQuaternion::update_property() {
- Quaternion val = get_edited_object()->get(get_edited_property());
+ Quaternion val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -2815,7 +2826,7 @@ void EditorPropertyVector4::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector4::update_property() {
- Vector4 val = get_edited_object()->get(get_edited_property());
+ Vector4 val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -2905,7 +2916,7 @@ void EditorPropertyVector4i::_value_changed(double val, const String &p_name) {
}
void EditorPropertyVector4i::update_property() {
- Vector4i val = get_edited_object()->get(get_edited_property());
+ Vector4i val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.x);
spin[1]->set_value(val.y);
@@ -2997,7 +3008,7 @@ void EditorPropertyAABB::_value_changed(double val, const String &p_name) {
}
void EditorPropertyAABB::update_property() {
- AABB val = get_edited_object()->get(get_edited_property());
+ AABB val = get_edited_property_value();
setting = true;
spin[0]->set_value(val.position.x);
spin[1]->set_value(val.position.y);
@@ -3080,7 +3091,7 @@ void EditorPropertyTransform2D::_value_changed(double val, const String &p_name)
}
void EditorPropertyTransform2D::update_property() {
- Transform2D val = get_edited_object()->get(get_edited_property());
+ Transform2D val = get_edited_property_value();
setting = true;
spin[0]->set_value(val[0][0]);
spin[1]->set_value(val[1][0]);
@@ -3174,7 +3185,7 @@ void EditorPropertyBasis::_value_changed(double val, const String &p_name) {
}
void EditorPropertyBasis::update_property() {
- Basis val = get_edited_object()->get(get_edited_property());
+ Basis val = get_edited_property_value();
setting = true;
spin[0]->set_value(val[0][0]);
spin[1]->set_value(val[0][1]);
@@ -3267,7 +3278,7 @@ void EditorPropertyTransform3D::_value_changed(double val, const String &p_name)
}
void EditorPropertyTransform3D::update_property() {
- update_using_transform(get_edited_object()->get(get_edited_property()));
+ update_using_transform(get_edited_property_value());
}
void EditorPropertyTransform3D::update_using_transform(Transform3D p_transform) {
@@ -3369,7 +3380,7 @@ void EditorPropertyProjection::_value_changed(double val, const String &p_name)
}
void EditorPropertyProjection::update_property() {
- update_using_transform(get_edited_object()->get(get_edited_property()));
+ update_using_transform(get_edited_property_value());
}
void EditorPropertyProjection::update_using_transform(Projection p_transform) {
@@ -3447,7 +3458,7 @@ void EditorPropertyColor::_set_read_only(bool p_read_only) {
void EditorPropertyColor::_color_changed(const Color &p_color) {
// Cancel the color change if the current color is identical to the new one.
- if (get_edited_object()->get(get_edited_property()) == p_color) {
+ if (get_edited_property_value() == p_color) {
return;
}
@@ -3474,7 +3485,7 @@ void EditorPropertyColor::_notification(int p_what) {
}
void EditorPropertyColor::update_property() {
- picker->set_pick_color(get_edited_object()->get(get_edited_property()));
+ picker->set_pick_color(get_edited_property_value());
const Color color = picker->get_pick_color();
// Add a tooltip to display each channel's values without having to click the ColorPickerButton
@@ -3642,7 +3653,7 @@ void EditorPropertyNodePath::update_property() {
if (pointer_mode) {
p = get_edited_object()->get(_get_meta_pointer_property());
} else {
- p = get_edited_object()->get(get_edited_property());
+ p = get_edited_property_value();
}
assign->set_tooltip_text(p);
@@ -3726,7 +3737,7 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
///////////////////// RID /////////////////////////
void EditorPropertyRID::update_property() {
- RID rid = get_edited_object()->get(get_edited_property());
+ RID rid = get_edited_property_value();
if (rid.is_valid()) {
uint64_t id = rid.get_id();
label->set_text("RID: " + uitos(id));
@@ -3927,7 +3938,7 @@ void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) {
}
void EditorPropertyResource::_open_editor_pressed() {
- Ref<Resource> res = get_edited_object()->get(get_edited_property());
+ Ref<Resource> res = get_edited_property_value();
if (res.is_valid()) {
// May clear the editor so do it deferred.
callable_mp(EditorNode::get_singleton(), &EditorNode::edit_item).bind(res.ptr(), this).call_deferred();
@@ -4052,7 +4063,7 @@ void EditorPropertyResource::setup(Object *p_object, const String &p_path, const
}
void EditorPropertyResource::update_property() {
- Ref<Resource> res = get_edited_object()->get(get_edited_property());
+ Ref<Resource> res = get_edited_property_value();
if (use_sub_inspector) {
if (res.is_valid() != resource_picker->is_toggle_mode()) {
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 5acb30b9d6..078ebb34fd 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -250,7 +250,7 @@ void EditorPropertyArray::_object_id_selected(const StringName &p_property, Obje
}
void EditorPropertyArray::update_property() {
- Variant array = get_edited_object()->get(get_edited_property());
+ Variant array = get_edited_property_value();
String array_type_name = Variant::get_type_name(array_type);
if (array_type == Variant::ARRAY && subtype != Variant::NIL) {
@@ -568,7 +568,7 @@ void EditorPropertyArray::_notification(int p_what) {
}
void EditorPropertyArray::_edit_pressed() {
- Variant array = get_edited_object()->get(get_edited_property());
+ Variant array = get_edited_property_value();
if (!array.is_array() && edit->is_pressed()) {
initialize_array(array);
get_edited_object()->set(get_edited_property(), array);
@@ -808,7 +808,7 @@ void EditorPropertyDictionary::setup(PropertyHint p_hint) {
}
void EditorPropertyDictionary::update_property() {
- Variant updated_val = get_edited_object()->get(get_edited_property());
+ Variant updated_val = get_edited_property_value();
if (updated_val.get_type() == Variant::NIL) {
edit->set_text(TTR("Dictionary (Nil)")); // This provides symmetry with the array property.
@@ -1217,7 +1217,7 @@ void EditorPropertyDictionary::_notification(int p_what) {
}
void EditorPropertyDictionary::_edit_pressed() {
- Variant prop_val = get_edited_object()->get(get_edited_property());
+ Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL && edit->is_pressed()) {
VariantInternal::initialize(&prop_val, Variant::DICTIONARY);
get_edited_object()->set(get_edited_property(), prop_val);
@@ -1299,7 +1299,7 @@ void EditorPropertyLocalizableString::_remove_item(Object *p_button, int p_index
}
void EditorPropertyLocalizableString::update_property() {
- Variant updated_val = get_edited_object()->get(get_edited_property());
+ Variant updated_val = get_edited_property_value();
if (updated_val.get_type() == Variant::NIL) {
edit->set_text(TTR("Localizable String (Nil)")); // This provides symmetry with the array property.
@@ -1431,7 +1431,7 @@ void EditorPropertyLocalizableString::_notification(int p_what) {
}
void EditorPropertyLocalizableString::_edit_pressed() {
- Variant prop_val = get_edited_object()->get(get_edited_property());
+ Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL && edit->is_pressed()) {
VariantInternal::initialize(&prop_val, Variant::DICTIONARY);
get_edited_object()->set(get_edited_property(), prop_val);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 0eb76c6011..8574ea409a 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -553,7 +553,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/appearance/gutters/show_line_numbers", true);
_initial_set("text_editor/appearance/gutters/line_numbers_zero_padded", false);
_initial_set("text_editor/appearance/gutters/highlight_type_safe_lines", true);
- _initial_set("text_editor/appearance/gutters/show_bookmark_gutter", true);
_initial_set("text_editor/appearance/gutters/show_info_gutter", true);
// Appearance: Minimap
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 25749a9589..0cd6b6c540 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -63,7 +63,7 @@ void EditorColorMap::create() {
add_conversion_color_pair("#ffffff", "#414141"); // Pure white
add_conversion_color_pair("#000000", "#bfbfbf"); // Pure black
- // Keep pure RGB colors as is, but list them for explicitly.
+ // Keep pure RGB colors as is, but list them for explicitness.
add_conversion_color_pair("#ff0000", "#ff0000"); // Pure red
add_conversion_color_pair("#00ff00", "#00ff00"); // Pure green
add_conversion_color_pair("#0000ff", "#0000ff"); // Pure blue
@@ -107,10 +107,11 @@ void EditorColorMap::create() {
add_conversion_color_pair("#dbee15", "#b7d10a"); // Color track yellow
add_conversion_color_pair("#288027", "#218309"); // Color track green
- // Resource groups
+ // Other objects
add_conversion_color_pair("#ffca5f", "#fea900"); // Mesh resource (orange)
add_conversion_color_pair("#2998ff", "#68b6ff"); // Shape resource (blue)
add_conversion_color_pair("#a2d2ff", "#4998e3"); // Shape resource (light blue)
+ add_conversion_color_pair("#69c4d4", "#29a3cc"); // Input event highlight (light blue)
// Animation editor tracks
// The property track icon color is set by the common icon color.
diff --git a/editor/icons/2D.svg b/editor/icons/2D.svg
index fdd2e473e3..9908006fe3 100644
--- a/editor/icons/2D.svg
+++ b/editor/icons/2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.984375 15a1 1 0 0 1 -.6914062-.291316l-2-2a1 1 0 0 1 0-1.414062 1 1 0 0 1 1.4140624 0l.2929688.292968v-8.5859371h8.585938l-.292969-.292969a1 1 0 0 1 0-1.414062 1 1 0 0 1 1.414062 0l2 2a1 1 0 0 1 0 1.414062l-2 2.0000002a1 1 0 0 1 -.720703.2910157 1 1 0 0 1 -.693359-.2910157 1 1 0 0 1 0-1.4140622l.292969-.292969h-6.585938v6.5859371l.2929688-.292968a1 1 0 0 1 1.4140624 0 1 1 0 0 1 0 1.414062l-2 2a1 1 0 0 1 -.7226562.291316z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.308 15-2-2a1 1 0 0 1 1.414-1.414l.293.293V3.293h8.586L11.308 3a1 1 0 0 1 1.415-1.414l2 2a1 1 0 0 1 0 1.414l-2 2a1 1 0 0 1-1.415-1.414l.293-.293H5.015v6.586l.294-.293A1 1 0 0 1 6.723 13l-2 2a1 1 0 0 1-1.414 0z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/3D.svg b/editor/icons/3D.svg
index 501b47aca1..b9b17b82ee 100644
--- a/editor/icons/3D.svg
+++ b/editor/icons/3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.9902 1.002a1.0001 1.0001 0 0 0 -.69141.29102l-2 2a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l.29297-.29297v8.5859h8.5859l-.29297.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2a1 1 0 0 0 -.72266-.29102 1 1 0 0 0 -.69141.29102 1 1 0 0 0 0 1.4141l.29297.29297h-5.1719l5.5859-5.5859v.41602a1 1 0 0 0 1 1 1 1 0 0 0 1-1v-2.8301a1.0001 1.0001 0 0 0 -1-1h-2.8301a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h.41602l-5.5859 5.5859v-5.1719l.29297.29297a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-2-2a1.0001 1.0001 0 0 0 -.72266-.29102z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.309 1.291-2 2a1 1 0 0 0 1.414 1.414l.293-.293v8.586h8.586l-.293.293a1 1 0 0 0 1.414 1.414l2-2a1 1 0 0 0 0-1.414l-2-2a1 1 0 0 0-1.414 1.414l.293.293H6.43l5.586-5.586v.416a1 1 0 0 0 2 0v-2.83a1 1 0 0 0-1-1h-2.83a1 1 0 0 0 0 2h.416L5.016 9.584V4.412l.293.293a1 1 0 0 0 1.414-1.414l-2-2a1 1 0 0 0-1.414 0z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/AspectRatioContainer.svg b/editor/icons/AspectRatioContainer.svg
index d28bcc7193..b8fa88091d 100644
--- a/editor/icons/AspectRatioContainer.svg
+++ b/editor/icons/AspectRatioContainer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM3 5v2h2V5zm8 0v2h2V5zM3 9v2h2V9zm8 0v2h2V9zm-8 4a2 2 0 0 0 2 2v-2zm4 0v2h2v-2zm4 0v2a2 2 0 0 0 2-2z" fill="#8eef97"/></svg>
diff --git a/editor/icons/AtlasTexture.svg b/editor/icons/AtlasTexture.svg
index e261d372d1..4f4112253d 100644
--- a/editor/icons/AtlasTexture.svg
+++ b/editor/icons/AtlasTexture.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1037.4-5 2v12l5-2 4 2 5-2v-12l-5 2zm0 2 4 2v8l-4-2z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 1 1 3v12l5-2 4 2 5-2V1l-5 2zm0 2 4 2v8l-4-2z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Back.svg b/editor/icons/Back.svg
index e98a583855..1f9d32da2c 100644
--- a/editor/icons/Back.svg
+++ b/editor/icons/Back.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 8 16" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m6 1038.4-4 6 4 6" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 8 16" width="8" xmlns="http://www.w3.org/2000/svg"><path d="M6 2 2 8l4 6" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/BoxContainer.svg b/editor/icons/BoxContainer.svg
index 03b918d9cf..39de70c15d 100644
--- a/editor/icons/BoxContainer.svg
+++ b/editor/icons/BoxContainer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.4520481 6.9086748c-.60273897.602739-.60272261 1.5799281 0 2.1826507l5.4566267 5.4566265c.602739.602739 1.5799281.602723 2.1826507 0l5.4566265-5.4566265c.602739-.602739.602723-1.5799281 0-2.1826507l-5.4566265-5.4566265c-.602739-.60273904-1.5799281-.60272304-2.1826507 0zm1.0913253 1.0913253 1.0913254-1.0913253 5.4566267 5.4566262-1.0913253 1.091326zm2.1826507-2.1826498 1.0913254-1.091326 5.4566265 5.4566267-1.091326 1.091325zm2.1826507-2.182651 1.0913254-1.091325 5.4566258 5.4566258-1.091325 1.0913254z" fill="#8eef97" stroke-width=".771684"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1.452 6.909a1.543 1.543 0 0 0 0 2.182l5.457 5.457a1.543 1.543 0 0 0 2.182 0l5.457-5.457a1.543 1.543 0 0 0 0-2.182L9.091 1.452a1.543 1.543 0 0 0-2.182 0zM2.543 8l1.092-1.091 5.456 5.456L8 13.457zm2.183-2.183 1.091-1.091 5.457 5.457-1.091 1.091zm2.183-2.182L8 2.543 13.457 8l-1.092 1.091z" fill="#8eef97"/></svg>
diff --git a/editor/icons/BoxMesh.svg b/editor/icons/BoxMesh.svg
index ef2f77a255..734f239279 100644
--- a/editor/icons/BoxMesh.svg
+++ b/editor/icons/BoxMesh.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .889-7 3.5v7.222l7 3.5 7-3.5v-7.222zm0 2.115 3.94 1.971-3.94 1.968-3.939-1.968zm-5 3.553 4 2v3.941l-4-2.002zm10 0v3.939l-4 2.002v-3.941z" fill="#ffca5f" fill-rule="nonzero"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/Bucket.svg b/editor/icons/Bucket.svg
index a30fce3112..b2c694632d 100644
--- a/editor/icons/Bucket.svg
+++ b/editor/icons/Bucket.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke-width="1.325447" transform="matrix(.53348552 .53348552 -.53348552 .53348552 561.06065 -551.99594)"><path d="m2 1c-.5522355.0001-.9999477.4477-1 1v1.5h2.8847656a1.4999877 1.5 0 0 1 1.1152344-.5 1.4999877 1.5 0 0 1 1.5 1.5 1.4999877 1.5 0 0 1 -1.5 1.5 1.4999877 1.5 0 0 1 -1.1152344-.5h-2.8847656v1.5h-1.26953125-1.73046875c-.5522769 0-.999989-.4477-1-1 .000011-.5523.4477231-1 1-1h3 2.5878906.546875a1 1 0 0 0 .8652344.5 1 1 0 0 0 1-1 1 1 0 0 0 -1-1 1 1 0 0 0 -.8632812.5h-.5488282-2.5878906-3c-1.1045647 0-1.9999933.8954285-2 2 .0000067 1.1045715.8954353 2 2 2h3v6c.0000735.5523.4477232.9999 1 1h8c.552235-.0001.999947-.4477 1-1v-13z" stroke-width="1.325447" transform="translate(0 1036.4)"/><path d="m12 1038.4c.707107 3.5356.707107 3.5356 1.414213 4.2427.707107.7071 2.121321.7071 2.828428 0 .707106-.7071.707106-2.1213 0-2.8284-.707107-.7072-.707107-.7072-4.242641-1.4143z" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8.693 2.51a.754.754 0 0 0-1.067 0l-.8.8 1.538 1.54a1.132 1.132 0 1 1-1.066 1.066l-1.54-1.54-.8.8-1.6-1.6A.754.754 0 0 1 4.425 2.51l3.273 3.273a.754.754 0 1 0 .533-.533L4.958 1.977A1.509 1.509 0 0 0 2.824 4.11l1.6 1.6-3.2 3.201a.754.754 0 0 0 0 1.067l4.268 4.268a.754.754 0 0 0 1.067 0l6.935-6.935zm4.801 5.869c-1.51 2.263-1.51 2.263-1.51 3.018 0 .754.756 1.509 1.51 1.509s1.51-.755 1.51-1.51c0-.754 0-.754-1.51-3.017z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Camera2D.svg b/editor/icons/Camera2D.svg
index 6b0f8e603f..81e5cc2c8e 100644
--- a/editor/icons/Camera2D.svg
+++ b/editor/icons/Camera2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#8da5f3" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9 2a3 3 0 0 0-3 2.777 3 3 0 1 0-3 5.047V12a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-1l3 2V7l-3 2V7.23A3 3 0 0 0 9 2z" fill="#8da5f3"/></svg>
diff --git a/editor/icons/Camera3D.svg b/editor/icons/Camera3D.svg
index a8dee93de2..bf61aa48fc 100644
--- a/editor/icons/Camera3D.svg
+++ b/editor/icons/Camera3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#fc7f7f" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9 2a3 3 0 0 0-3 2.777 3 3 0 1 0-3 5.047V12a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-1l3 2V7l-3 2V7.23A3 3 0 0 0 9 2z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/CameraAttributes.svg b/editor/icons/CameraAttributes.svg
index 1ee7e15c87..459c64e11c 100644
--- a/editor/icons/CameraAttributes.svg
+++ b/editor/icons/CameraAttributes.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.9492188 2a3 3 0 0 0 -2.9492188 3 3 3 0 0 0 1 2.2304688v1.7695312l-3-2v6l3-2v1c0 .554.44599 1 1 1h3c.0076117-.045309.0115938-.096059.0214844-.134766.0773621-.302758.1860981-.478282.2832031-.625.1397097-.211089.2814954-.338835.4257813-.480468-.1445165-.141692-.2879205-.269839-.4277344-.480469-.0971224-.146315-.2052562-.321748-.2832032-.623047-.0777157-.300405-.1044198-.8152648.1640626-1.2910156.2700589-.4775976.7340166-.7239536 1.0371093-.8105469.3037241-.0867737.5108695-.0808838.6875-.0703125.2608449.0156115.4500479.0763383.6503909.1328125.049596-.1859081.086921-.3641449.195312-.5800781.078477-.1563394.174637-.3364783.396485-.5527344.221847-.2162561.652628-.4930277 1.195312-.4980469a1.6124973 1.6124973 0 0 1 .033203 0c.542861.0056205.97185.2837448 1.19336.5.146452.1429781.230167.265896.298828.3808594a3 3 0 0 0 .128906-.8671875 3 3 0 0 0 -3-3 3 3 0 0 0 -2.0117188.7773438 3 3 0 0 0 -2.9882812-2.7773438 3 3 0 0 0 -.0507812 0z" fill="#e0e0e0"/><path d="m12.36062 8.59795a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#c38ef1" stroke-width="1.0667"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 2a3 3 0 0 0-2 5.23V9L1 7v6l3-2v1a1 1 0 0 0 1 1h3a2 2 0 0 1 .73-1.24 1.83 1.83 0 0 1 1.828-3.143 1.8 1.8 0 0 1 3.313-.75 3 3 0 0 0-4.883-3.09A3 3 0 0 0 6 2z" fill="#e0e0e0"/><path d="M12.36 8.598a.533 3.2 0 0 0-.51 2.275 3.2.533 30 0 0-.515.887.533 3.2 60 0 0 .515.887.533 3.2 0 0 0 1.02 0 3.2.533 30 0 0 .515-.887.533 3.2 60 0 0-.515-.887.533 3.2 0 0 0-.51-2.275z" fill="#c38ef1"/></svg>
diff --git a/editor/icons/CameraTexture.svg b/editor/icons/CameraTexture.svg
index 91e3fe9b41..145a817b7e 100644
--- a/editor/icons/CameraTexture.svg
+++ b/editor/icons/CameraTexture.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v12c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-12c0-.55228-.44772-1-1-1zm1 2h10v8h-10zm5.8184 1.0039c-.85534.0009758-1.5654.66069-1.6289 1.5137-.30036-.27229-.69029-.4234-1.0957-.42383-.90315 0-1.6367.73162-1.6367 1.6348.0009732.69217.43922 1.3103 1.0918 1.541v1.1855c0 .30198.24293.54492.54492.54492h3.2695c.30199 0 .54492-.24294.54492-.54492v-.54492l1.6367 1.0898v-3.2715l-1.6367 1.0918v-.96484c.34606-.30952.54406-.75251.54492-1.2168 0-.90315-.73162-1.6348-1.6348-1.6348z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm1 2h10v8H3zm5.818 1A1.65 1.65 0 0 0 7.19 5.514a1.65 1.65 0 1 0-1.641 2.752v1.19a.55.55 0 0 0 .545.544h3.27a.55.55 0 0 0 .544-.545V8.91L11.545 10V6.728L9.908 7.82v-.965a1.65 1.65 0 0 0-1.09-2.851z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/CapsuleMesh.svg b/editor/icons/CapsuleMesh.svg
index 0bc7814bea..ad8eea2f01 100644
--- a/editor/icons/CapsuleMesh.svg
+++ b/editor/icons/CapsuleMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-.66556-.1047-1.2973-.372-1.9941-.6618v-1.3222c0-1.3474.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-.68406.3054-1.3142.5732-1.9941.6663zm-4.0059 6.334c.67836.2231 1.3126.447 1.9941.5264v2.8848c-1.1957-.4092-1.9941-1.5242-1.9941-2.8716zm6 .03v.5094c0 1.3474-.79838 2.4619-1.9941 2.8711v-2.8711c.68606-.068 1.3207-.2828 1.9941-.5094z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/CapsuleShape2D.svg b/editor/icons/CapsuleShape2D.svg
index 5b3c411f9b..dc1d5b06fc 100644
--- a/editor/icons/CapsuleShape2D.svg
+++ b/editor/icons/CapsuleShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.77 0-5 2.23-5 5v4c0 2.77 2.23 5 5 5s5-2.23 5-5v-4c0-2.77-2.23-5-5-5zm0 2c1.662 0 3 1.338 3 3v4c0 1.662-1.338 3-3 3s-3-1.338-3-3v-4c0-1.662 1.338-3 3-3z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 6v4a4 4 0 0 0 8 0V6a4 4 0 0 0-8 0" stroke-width="2" stroke="#5fb2ff" fill="none"/></svg>
diff --git a/editor/icons/CapsuleShape3D.svg b/editor/icons/CapsuleShape3D.svg
index c566d68f19..9b1527883c 100644
--- a/editor/icons/CapsuleShape3D.svg
+++ b/editor/icons/CapsuleShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903z" fill="#5fb2ff"/><circle cx="6.5" cy="1040.9" fill="#a2d2ff" r="1.5"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M 3 6 v 4 a 5 5 0 0 0 10 0 v -4 a 5 5 0 0 0 -10 0 z" fill="#5fb2ff"/><circle cx="6.5" cy="4.5" fill="#a2d2ff" r="1.5"/></svg>
diff --git a/editor/icons/Checkerboard.svg b/editor/icons/Checkerboard.svg
index 38b537e872..4d0447400c 100644
--- a/editor/icons/Checkerboard.svg
+++ b/editor/icons/Checkerboard.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" stroke-linecap="round" stroke-linejoin="round" transform="translate(0 -988.36)"><path d="m0 988.36h64v64h-64z" fill-opacity=".19608" stroke-width="2"/><path d="m0 0v16h16v-16zm16 16v16h16v-16zm16 0h16v-16h-16zm16 0v16h16v-16zm0 16h-16v16h16zm0 16v16h16v-16zm-16 0h-16v16h16zm-16 0v-16h-16v16z" fill-opacity=".39216" stroke-width="8" transform="translate(0 988.36)"/></g></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="M0 0h64v64H0z" fill-opacity=".196"/><path d="M0 0v16h16V0zm16 16v16h16V16zm16 0h16V0H32zm16 0v16h16V16zm0 16H32v16h16zm0 16v16h16V48zm-16 0H16v16h16zm-16 0V32H0v16z" fill-opacity=".392"/></g></svg>
diff --git a/editor/icons/ClippedCamera3D.svg b/editor/icons/ClippedCamera3D.svg
index 44d656e8ba..b1651aca6a 100644
--- a/editor/icons/ClippedCamera3D.svg
+++ b/editor/icons/ClippedCamera3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6.5 12v4h3v-1h-2v-3zm-1 0h-2c-.5 0-1 .5-1 1v2c-.01829.53653.5 1 1 1h2v-1h-2v-2h2zm4-12c-1.5691.0017903-2.8718 1.2125-2.9883 2.7773-.55103-.49952-1.268-.77655-2.0117-.77734-1.6569 0-3 1.3431-3 3 .00179 1.2698.80282 2.4009 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695c.63486-.56783.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm1 12v4h1v-1h1c.55228 0 1-.44772 1-1v-1c0-.55228-.44775-.99374-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 0a3 3 0 0 0-3 2.777 3 3 0 1 0-3 5.047V10a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V9l3 2V5l-3 2V5.23A3 3 0 0 0 9.5 0zm-3 12v4h3v-1h-2v-3zm-1 0h-2c-.5 0-1 .5-1 1v2c-.018.536.5 1 1 1h2v-1h-2v-2h2zm5 0v4h1v-1h1a1 1 0 0 0 1-1v-1c0-.552-.448-.994-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/Collapse.svg b/editor/icons/Collapse.svg
index 5e5611adb2..fb594a636b 100644
--- a/editor/icons/Collapse.svg
+++ b/editor/icons/Collapse.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1044.4 5 4 5-4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 8 5 4 5-4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CollisionPolygon3D.svg b/editor/icons/CollisionPolygon3D.svg
index 121bd82685..469a7ed732 100644
--- a/editor/icons/CollisionPolygon3D.svg
+++ b/editor/icons/CollisionPolygon3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f"/></svg>
diff --git a/editor/icons/CollisionShape3D.svg b/editor/icons/CollisionShape3D.svg
index d7f8a308e6..7299eacdf7 100644
--- a/editor/icons/CollisionShape3D.svg
+++ b/editor/icons/CollisionShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.399988)"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f"/></svg>
diff --git a/editor/icons/Container.svg b/editor/icons/Container.svg
index efe1966ad4..bfe78cbc67 100644
--- a/editor/icons/Container.svg
+++ b/editor/icons/Container.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM1 5v2h2V5zm12 0v2h2V5zM1 9v2h2V9zm12 0v2h2V9zM1 13a2 2 0 0 0 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2a2 2 0 0 0 2-2z" fill="#8eef97"/></svg>
diff --git a/editor/icons/ContainerLayout.svg b/editor/icons/ContainerLayout.svg
index feabc2c350..1eac17532f 100644
--- a/editor/icons/ContainerLayout.svg
+++ b/editor/icons/ContainerLayout.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m3 1c-1.105 0-2 .895-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.105-.895-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4c0 1.105.895 2 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2c1.105 0 2-.895 2-2z" fill="#8eef97"/><path d="m7 7h4v4h-4z" fill="#d6d6d6"/></g></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM1 5v2h2V5zm12 0v2h2V5zM1 9v2h2V9zm12 0v2h2V9zM1 13a2 2 0 0 0 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2a2 2 0 0 0 2-2z" fill="#8eef97"/><path d="M7 7h4v4H7z" fill="#d6d6d6"/></svg>
diff --git a/editor/icons/ControlAlignFullRect.svg b/editor/icons/ControlAlignFullRect.svg
index 0099e04896..6dfde73e08 100644
--- a/editor/icons/ControlAlignFullRect.svg
+++ b/editor/icons/ControlAlignFullRect.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h16v16h-16z" fill="#919191"/><path d="m2 2h12v12h-12z" fill="#474747"/><path d="m2 2h12v12h-12z" fill="#d6d6d6"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h16v16h-16z" fill="#919191"/><path d="m2 2h12v12h-12z" fill="#d6d6d6"/></svg>
diff --git a/editor/icons/ConvexPolygonShape2D.svg b/editor/icons/ConvexPolygonShape2D.svg
index fa5369aace..23249190dd 100644
--- a/editor/icons/ConvexPolygonShape2D.svg
+++ b/editor/icons/ConvexPolygonShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-6l6-6 6 6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M14 14H2V8l6-6 6 6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/ConvexPolygonShape3D.svg b/editor/icons/ConvexPolygonShape3D.svg
index f0c9101c72..48eec6e998 100644
--- a/editor/icons/ConvexPolygonShape3D.svg
+++ b/editor/icons/ConvexPolygonShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#5fb2ff"/><path d="m8 1-7 3 7 11 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1 1 4v8l7 3 7-3z" fill="#2998ff"/><path d="m8 15-7-3V4l7 3z" fill="#5fb2ff"/><path d="M8 1 1 4l7 11 7-3z" fill="#2998ff"/></svg>
diff --git a/editor/icons/Curve2D.svg b/editor/icons/Curve2D.svg
index 4470e660b3..e4cf1dcb9d 100644
--- a/editor/icons/Curve2D.svg
+++ b/editor/icons/Curve2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1037.4c-3.1667 0-5.1045.854-6.082 2.3203-.97757 1.4664-.91797 3.1797-.91797 4.6797s-.059601 2.7867-.58203 3.5703c-.52243.7837-1.5846 1.4297-4.418 1.4297a1.0001 1.0001 0 1 0 0 2c3.1667 0 5.1045-.8539 6.082-2.3203.97757-1.4663.91797-3.1797.91797-4.6797s.059601-2.7866.58203-3.5703c.52243-.7836 1.5846-1.4297 4.418-1.4297a1.0001 1.0001 0 1 0 0-2z" fill="#e0e0e0" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M 2 14 C 14 14 2 2 14 2" fill="none" stroke-linecap="round" stroke-width="2" stroke="#e0e0e0"/></svg>
diff --git a/editor/icons/Curve3D.svg b/editor/icons/Curve3D.svg
index f61b344966..a5cd20433e 100644
--- a/editor/icons/Curve3D.svg
+++ b/editor/icons/Curve3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0039 1037.4a1.0001 1.0001 0 0 0 -.45117.1113l-6 3a1.0001 1.0001 0 0 0 0 1.7891l6 3a1.0001 1.0001 0 0 0 .89453 0l4.5527-2.2754v3.7636l-5 2.5-5.5527-2.7773a1.0001 1.0001 0 0 0 -.89453 1.7891l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1.0001 1.0001 0 0 0 .55273-.8946v-6a1.0001 1.0001 0 0 0 -1.4473-.8945l-5.5527 2.7773-3.7637-1.8828 4.2109-2.1054a1.0001 1.0001 0 0 0 -.44336-1.9004z" fill="#e0e0e0" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2 2 5l6 3 6-3v6l-6 3-6-3" fill="none" stroke-width="2" stroke-linejoin="round" stroke-linecap="round" stroke="#e0e0e0"/></svg>
diff --git a/editor/icons/CurveClose.svg b/editor/icons/CurveClose.svg
index 032f1c6c55..f92187249f 100644
--- a/editor/icons/CurveClose.svg
+++ b/editor/icons/CurveClose.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/><path d="m10 6v2h2v-2zm0 2h-2v2h2zm-2 2h-2v2h2z" fill="#5fb2ff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 13C3 4 4 3 13 5" fill="none" stroke="#e0e0e0" stroke-opacity=".392" stroke-width="2"/><path d="M5 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm-8 8a2 2 0 0 0 0 4 2 2 0 0 0 0-4z" fill="#fff"/><path d="M10 6v2h2V6zm0 2H8v2h2zm-2 2H6v2h2z" fill="#5fb2ff"/></svg>
diff --git a/editor/icons/CurveConstant.svg b/editor/icons/CurveConstant.svg
index 656bdd7580..a09831c237 100644
--- a/editor/icons/CurveConstant.svg
+++ b/editor/icons/CurveConstant.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1046.4h8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="M2 6h8" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CurveCreate.svg b/editor/icons/CurveCreate.svg
index 4e406b35f6..aac51e6a2a 100644
--- a/editor/icons/CurveCreate.svg
+++ b/editor/icons/CurveCreate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 13C3 4 4 3 13 5" fill="none" stroke="#e0e0e0" stroke-opacity=".392" stroke-width="2"/><path d="M5 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm6 5v3H8v2h3v3h2v-3h3v-2h-3V8z" fill="#5fff97"/><path d="M13 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm-8 8a2 2 0 0 0 0 4 2 2 0 0 0 0-4z" fill="#fff"/></svg>
diff --git a/editor/icons/CurveCurve.svg b/editor/icons/CurveCurve.svg
index b5312aea24..5b4bd7e81a 100644
--- a/editor/icons/CurveCurve.svg
+++ b/editor/icons/CurveCurve.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m8.4688.4707-2.6875 2.6875h-.0019531a2 2 0 0 0 -.7793-.1582 2 2 0 0 0 -2 2 2 2 0 0 0 .16016.7793l-2.6914 2.6914 1.0625 1.0605 2.6895-2.6895a2 2 0 0 0 .7793.1582 2 2 0 0 0 2-2 2 2 0 0 0 -.16016-.77734l2.6914-2.6914-1.0625-1.0605z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 13C3 4 4 3 13 5" fill="none" stroke="#e0e0e0" stroke-opacity=".392" stroke-width="2"/><path d="M8.469.47 5.78 3.159a2 2 0 0 0-2.62 2.62L.47 8.47l1.06 1.062 2.69-2.69a2 2 0 0 0 2.62-2.62L9.53 1.53 8.47.471z" fill="#5fb2ff"/><path d="M13 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm-8 8a2 2 0 0 0 0 4 2 2 0 0 0 0-4z" fill="#fff"/></svg>
diff --git a/editor/icons/CurveEdit.svg b/editor/icons/CurveEdit.svg
index d8318a6bc3..da92d19447 100644
--- a/editor/icons/CurveEdit.svg
+++ b/editor/icons/CurveEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm3 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 13C3 4 4 3 13 5" fill="none" stroke="#e0e0e0" stroke-opacity=".392" stroke-width="2"/><path d="M5 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm3 5 3.291 8 .947-2.82 1.883 1.883.943-.942-1.884-1.883 2.82-.947L8 8z" fill="#5fb2ff"/><path d="M13 3a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm-8 8a2 2 0 0 0 0 4 2 2 0 0 0 0-4z" fill="#fff"/></svg>
diff --git a/editor/icons/CurveIn.svg b/editor/icons/CurveIn.svg
index fefad9ce6c..d1028a491d 100644
--- a/editor/icons/CurveIn.svg
+++ b/editor/icons/CurveIn.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 8-3 8-8" fill="none" stroke="#80ff45" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="M2 10c5 0 8-3 8-8" fill="none" stroke="#80ff45" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CurveInOut.svg b/editor/icons/CurveInOut.svg
index f099cb83f1..13a9ceee2c 100644
--- a/editor/icons/CurveInOut.svg
+++ b/editor/icons/CurveInOut.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 3-8 8-8" fill="none" stroke="#45d7ff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="M2 10c5 0 3-8 8-8" fill="none" stroke="#45d7ff" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CurveLinear.svg b/editor/icons/CurveLinear.svg
index 41d37c9329..c4fc83ae02 100644
--- a/editor/icons/CurveLinear.svg
+++ b/editor/icons/CurveLinear.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 8-8" fill="none" stroke="#ffe345" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 10 8-8" fill="none" stroke="#ffe345" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CurveOutIn.svg b/editor/icons/CurveOutIn.svg
index 7f200432bf..9d90c01dd6 100644
--- a/editor/icons/CurveOutIn.svg
+++ b/editor/icons/CurveOutIn.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c0-5 8-3 8-8" fill="none" stroke="#ff4596" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="M2 10c0-5 8-3 8-8" fill="none" stroke="#ff4596" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/CylinderMesh.svg b/editor/icons/CylinderMesh.svg
index 2059e77aeb..9d0045a341 100644
--- a/editor/icons/CylinderMesh.svg
+++ b/editor/icons/CylinderMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="2" fill="none" stroke="#ffca5f"><ellipse cx="8" cy="4" rx="6" ry="2"/><path d="M2 4v8a6 2 0 0 0 12 0V4"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/DebugSkipBreakpointsOff.svg b/editor/icons/DebugSkipBreakpointsOff.svg
index c0b6e8d188..7b9a222534 100644
--- a/editor/icons/DebugSkipBreakpointsOff.svg
+++ b/editor/icons/DebugSkipBreakpointsOff.svg
@@ -1,2 +1,2 @@
-<svg height="17" width="17" xmlns="http://www.w3.org/2000/svg"><circle cx="8.5" cy="8.5" r="6" fill="#fc7f7f" stroke-width="1"/></svg>
+<svg height="17" width="17" xmlns="http://www.w3.org/2000/svg"><circle cx="8.5" cy="8.5" r="6" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/EditInternal.svg b/editor/icons/EditInternal.svg
index 7daf7ec29a..14e8518797 100644
--- a/editor/icons/EditInternal.svg
+++ b/editor/icons/EditInternal.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m7 1c-.554 0-1 .446-1 1v2h4v-2c0-.554-.446-1-1-1zm-1 4v7l2 3 2-3v-7zm1 1h1v5h-1z" transform="translate(-3.322034)"/><circle cx="10.508475" cy="12.677966" r="2.372881"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M3.678 1c-.554 0-1 .446-1 1v2h4V2c0-.554-.446-1-1-1zm-1 4v7l2 3 2-3V5zm1 1h1v5h-1z"/><circle cx="10.508" cy="12.678" r="2.373"/></g></svg>
diff --git a/editor/icons/EditorFileDialog.svg b/editor/icons/EditorFileDialog.svg
index c1e5479525..6b16dbb3e9 100644
--- a/editor/icons/EditorFileDialog.svg
+++ b/editor/icons/EditorFileDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v1h14V3a2 2 0 0 0-2-2zm9 1h1v1h-1zM1 5v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V5zm3 2h3c1 0 1 2 2 2h3v4H4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Environment.svg b/editor/icons/Environment.svg
index f42ae39bc0..b356459829 100644
--- a/editor/icons/Environment.svg
+++ b/editor/icons/Environment.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0"><circle cx="8" cy="8" r="6" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><g stroke-width="1.5" transform="translate(0 -1036.4)"><path d="m2 1044.4c4.5932 1.582 8.3985 1.0627 12 0"/><path d="m8 1038.4c-3 4-3 8 0 12"/><path d="m8 1038.4c3 4 3 8 0 12"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0"><circle cx="8" cy="8" r="6" stroke-width="2"/><path d="M2 8a6.5 2 0 0 0 12 0M8 2c-3 4-3 8 0 12M8 2c3 4 3 8 0 12" stroke-width="1.5"/></g></svg>
diff --git a/editor/icons/Error.svg b/editor/icons/Error.svg
index 8478decb41..198df53a92 100644
--- a/editor/icons/Error.svg
+++ b/editor/icons/Error.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff5f5f" height="8" ry="4" width="8"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle fill="#ff5f5f" cx="4" cy="4" r="4"/></svg>
diff --git a/editor/icons/ErrorWarning.svg b/editor/icons/ErrorWarning.svg
index e034bf194f..6ca6f4c8b8 100644
--- a/editor/icons/ErrorWarning.svg
+++ b/editor/icons/ErrorWarning.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 0c-2.216 0-4 1.784-4 4s1.784 4 4 4z" fill="#ff5f5f"/><path d="m4 .00000003c2.216 0 4 1.78399997 4 3.99999997s-1.784 4-4 4z" fill="#ffdd65"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="M4 8a1 1 0 0 1 0-8z" fill="#ff5f5f"/><path d="M4 0a1 1 0 0 1 0 8z" fill="#ffdd65"/></svg>
diff --git a/editor/icons/Favorites.svg b/editor/icons/Favorites.svg
index 67f62f26d5..a57c3da139 100644
--- a/editor/icons/Favorites.svg
+++ b/editor/icons/Favorites.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.1-2.3741 4.0973-4.6259 1.0978 3.2361 3.4074-.35866 4.6735 4.1389-1.9766 4.1572 1.9421-.39534-4.6532 3.2218-3.3932-4.6259-1.0978z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1.7 5.626 5.797 1 6.895l3.236 3.408-.359 4.673 4.14-1.977 4.157 1.942-.396-4.653L15 6.895l-4.626-1.098z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/File.svg b/editor/icons/File.svg
index d3c01ca45e..86c6e09114 100644
--- a/editor/icons/File.svg
+++ b/editor/icons/File.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v14h12v-9h-5v-5zm8 0v4h4z" fill="#e0e0e0" transform="translate(0 -.000017)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v14h12v-9h-5v-5zm8 0v4h4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/FileBigThumb.svg b/editor/icons/FileBigThumb.svg
index 214bd1d56b..2608ef89af 100644
--- a/editor/icons/FileBigThumb.svg
+++ b/editor/icons/FileBigThumb.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 5c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-.007812c.00212-.24832-.079273-.50098-.28516-.70703l-16-16c-.18786-.18693-.44246-.28939-.70703-.28906v-.0039062h-23zm0 2h22v2 10c0 2.1987 1.8013 4 4 4h10 2v32c0 1.1253-.87472 2-2 2h-36c-1.1253 0-2-.8747-2-2v-46c0-1.1253.87472-2 2-2z" fill="#fff" fill-opacity=".58824" transform="translate(0 -.000017)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M14 5a4 4 0 0 0-4 4v46a4 4 0 0 0 4 4h36a4 4 0 0 0 4-4V22a1 1 0 0 0-.29-.707l-16-16a1 1 0 0 0-.707-.29V5H14zm0 2h22v12a4 4 0 0 0 4 4h12v32a2 2 0 0 1-2 2H14a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2z" fill="#fff" fill-opacity=".588"/></svg>
diff --git a/editor/icons/FileBroken.svg b/editor/icons/FileBroken.svg
index d68c89e240..4c8b7cdb74 100644
--- a/editor/icons/FileBroken.svg
+++ b/editor/icons/FileBroken.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 .69141-.29102 1.0001 1.0001 0 0 1 .72266.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4zm-6 9.4141-2 2v2.5859h12v-2.5859l-.29297.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1v8.586l1.293-1.293a1 1 0 0 1 1.414 0L7 10.587l2.293-2.293a1 1 0 0 1 1.414 0L13 10.586l1-1V6H9V1H2zm8 0v4h4zm-6 9.414-2 2V15h12v-2.586l-.293.293a1 1 0 0 1-1.414 0L10 10.414l-2.293 2.293a1 1 0 0 1-1.414 0L4 10.414z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FileBrokenBigThumb.svg b/editor/icons/FileBrokenBigThumb.svg
index 7dc5a14452..c7edaa638b 100644
--- a/editor/icons/FileBrokenBigThumb.svg
+++ b/editor/icons/FileBrokenBigThumb.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 .29297-.70703v-11.172a1.0001 1.0001 0 0 0 -.29297-.70703l-16-16a1.0001 1.0001 0 0 0 -.70703-.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253.87473-2 2-2zm.98438 28.83a1.0001 1.0001 0 0 0 -.69141.29297l-4 4a1.0001 1.0001 0 0 0 -.29297.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707-.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -.72266-.29297zm.015625 2.4141 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-.87473 2-2 2h-36c-1.1253 0-2-.87473-2-2v-13.756l3-3z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M14 5c-2.199 0-4 1.801-4 4v26.172a1 1 0 0 0 1.707.707L15 32.586l9.293 9.293a1 1 0 0 0 1.414 0L35 32.586l9.293 9.293a1 1 0 0 0 1.414 0l8-8a1 1 0 0 0 .293-.707V22a1 1 0 0 0-.293-.707l-16-16A1 1 0 0 0 37 5H14zm0 2h22v12c0 2.199 1.801 4 4 4h12v9.758l-7 7-9.293-9.293a1 1 0 0 0-1.414 0L25 39.758l-9.293-9.293a1 1 0 0 0-1.414 0L12 32.758V9c0-1.126.875-2 2-2zm.984 28.83a1 1 0 0 0-.691.293l-4 4a1 1 0 0 0-.293.707V55c0 2.199 1.801 4 4 4h36c2.199 0 4-1.801 4-4V38.83a1 1 0 0 0-1.707-.707L45 45.416l-9.293-9.293a1 1 0 0 0-1.414 0L25 45.416l-9.293-9.293a1 1 0 0 0-.723-.293zM15 38.244l9.293 9.293a1 1 0 0 0 1.414 0L35 38.244l9.293 9.293a1 1 0 0 0 1.414 0L52 41.244V55c0 1.125-.875 2-2 2H14c-1.125 0-2-.875-2-2V41.244l3-3z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FileDead.svg b/editor/icons/FileDead.svg
index b5c18f3780..af88bd83ff 100644
--- a/editor/icons/FileDead.svg
+++ b/editor/icons/FileDead.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c.1353-.0020779.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091882.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm6 0c.1353-.00208.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091883.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm-6.4922 4h9c.277 0 .5.223.5.5s-.223.5-.5.5h-4.5c0 1.1046-.89543 2-2 2s-2-.8954-2-2h-.5c-.277 0-.5-.223-.5-.5s.223-.5.5-.5zm1.5 1c-.000019.5523.44771 1 1 1s1-.4477 1-1z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1v14h12V6H9V1zm8 0v4h4zM5 7.793l.646-.646a.353.353 0 0 1 .707.707l-.646.646.646.646a.353.353 0 0 1-.707.707L5 9.207l-.646.646a.353.353 0 0 1-.707-.706l.646-.647-.646-.646a.353.353 0 0 1 .707-.707zm6 0 .646-.646a.353.353 0 0 1 .707.707l-.646.646.646.646a.353.353 0 0 1-.706.707L11 9.207l-.646.646a.353.353 0 0 1-.707-.706l.646-.647-.646-.646a.353.353 0 0 1 .706-.707zM3.5 11h9a.5.5 0 0 1 0 1H8a2 2 0 0 1-4 0h-.5a.5.5 0 0 1 0-1zM5 12a1 1 0 0 0 2 0z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FileDeadBigThumb.svg b/editor/icons/FileDeadBigThumb.svg
index 0c1e3e03c6..ac420bef6f 100644
--- a/editor/icons/FileDeadBigThumb.svg
+++ b/editor/icons/FileDeadBigThumb.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-.0078c.002-.2483-.0793-.501-.28516-.707l-16-16c-.18788-.18693-.44247-.28939-.70704-.28907v-.004zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-.87472 2-2 2h-36c-1.1253 0-2-.8747-2-2v-46c0-1.1253.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm23 0a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" fill="#ff5f5f" transform="translate(0 -988.360017)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M14 5c-2.199 0-4 1.801-4 4v46c0 2.199 1.801 4 4 4h36c2.199 0 4-1.801 4-4V22h-.008a.967.967 0 0 0-.285-.707l-16-16a1 1 0 0 0-.707-.29V5zm0 2h22v12c0 2.199 1.801 4 4 4h12v32c0 1.125-.875 2-2 2H14c-1.125 0-2-.875-2-2V9c0-1.125.875-2 2-2zm2.951 22.002a1 1 0 0 0-.61.246 1 1 0 0 0-.093 1.412L19.172 34l-2.924 3.342a1 1 0 0 0 .094 1.412 1 1 0 0 0 1.41-.094l2.748-3.14 2.748 3.14a1 1 0 0 0 1.41.094 1 1 0 0 0 .094-1.412L21.828 34l2.924-3.34a1 1 0 0 0-.094-1.412 1 1 0 0 0-.638-.246 1 1 0 0 0-.772.34l-2.748 3.14-2.748-3.14a1 1 0 0 0-.8-.34zm23 0a1 1 0 0 0-.61.246 1 1 0 0 0-.093 1.412L42.172 34l-2.924 3.342a1 1 0 0 0 .094 1.412 1 1 0 0 0 1.41-.094l2.748-3.14 2.748 3.14a1 1 0 0 0 1.41.094 1 1 0 0 0 .094-1.412L44.828 34l2.924-3.34a1 1 0 0 0-.094-1.412 1 1 0 0 0-.638-.246 1 1 0 0 0-.772.34l-2.748 3.14-2.748-3.14a1 1 0 0 0-.8-.34zM21.001 43a1 1 0 0 0-1 1 1 1 0 0 0 1 1h3v3c0 2.753 2.246 5 5 5s5-2.247 5-5v-3h9a1 1 0 0 0 1-1 1 1 0 0 0-1-1zm5 2h6v3c0 1.68-1.321 3-3 3s-3-1.32-3-3z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FileDeadMediumThumb.svg b/editor/icons/FileDeadMediumThumb.svg
index 6ca43c8903..7addc26ef0 100644
--- a/editor/icons/FileDeadMediumThumb.svg
+++ b/editor/icons/FileDeadMediumThumb.svg
@@ -1 +1 @@
-<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-.000051-.2652-.10543-.51952-.29297-.70703l-9.1816-9.1895c-.18719-.18825-.44155-.29435-.70703-.29492h-14.818zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 .5713-.42868 1-1 1h-22c-.57133 0-1-.4287-1-1v-24c0-.5713.42867-1 1-1zm1.9863 11.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm14 0a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm-13.986 7.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h1a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3 2h4a2 2 0 0 1 -2 2 2 2 0 0 1 -2-2z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
+<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M5 1C3.355 1 2 2.355 2 4v24c0 1.645 1.355 3 3 3h22c1.645 0 3-1.355 3-3V11.191a1 1 0 0 0-.293-.707l-9.182-9.19A1 1 0 0 0 19.818 1H5zm0 2h14v6c0 1.645 1.355 3 3 3h6v16c0 .571-.429 1-1 1H5c-.571 0-1-.429-1-1V4c0-.571.429-1 1-1zm1.986 11.002a1 1 0 0 0-.693.291 1 1 0 0 0 0 1.414L7.586 17l-1.293 1.293a1 1 0 0 0 0 1.414 1 1 0 0 0 1.414 0L9 18.414l1.293 1.293a1 1 0 0 0 1.414 0 1 1 0 0 0 0-1.414L10.414 17l1.293-1.293a1 1 0 0 0 0-1.414 1 1 0 0 0-.72-.291 1 1 0 0 0-.694.291L9 15.586l-1.293-1.293a1 1 0 0 0-.72-.291zm14 0a1 1 0 0 0-.693.291 1 1 0 0 0 0 1.414L21.586 17l-1.293 1.293a1 1 0 0 0 0 1.414 1 1 0 0 0 1.414 0L23 18.414l1.293 1.293a1 1 0 0 0 1.414 0 1 1 0 0 0 0-1.414L24.414 17l1.293-1.293a1 1 0 0 0 0-1.414 1 1 0 0 0-.72-.291 1 1 0 0 0-.694.291L23 15.586l-1.293-1.293a1 1 0 0 0-.72-.291zM7 22a1 1 0 0 0-1 1 1 1 0 0 0 1 1h1a4 4 0 0 0 2 3.465 4 4 0 0 0 4 0A4 4 0 0 0 16 24h9a1 1 0 0 0 1-1 1 1 0 0 0-1-1zm3 2h4a2 2 0 0 1-2 2 2 2 0 0 1-2-2z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FileDialog.svg b/editor/icons/FileDialog.svg
index c1e5479525..6b16dbb3e9 100644
--- a/editor/icons/FileDialog.svg
+++ b/editor/icons/FileDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v1h14V3a2 2 0 0 0-2-2zm9 1h1v1h-1zM1 5v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V5zm3 2h3c1 0 1 2 2 2h3v4H4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/FileMediumThumb.svg b/editor/icons/FileMediumThumb.svg
index 0c2b467bf9..446255ed65 100644
--- a/editor/icons/FileMediumThumb.svg
+++ b/editor/icons/FileMediumThumb.svg
@@ -1 +1 @@
-<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-.000051-.2652-.10543-.51952-.29297-.70703l-9.1816-9.1895c-.18719-.18825-.44155-.29435-.70703-.29492zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 .5713-.42868 1-1 1h-22c-.57133 0-1-.4287-1-1v-24c0-.5713.42867-1 1-1z" fill="#fff" fill-opacity=".58824" transform="translate(0 -.000017)"/></svg>
+<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M5 1a3 3 0 0 0-3 3v24a3 3 0 0 0 3 3h22a3 3 0 0 0 3-3V11.191a1 1 0 0 0-.293-.707l-9.182-9.182A1 1 0 0 0 19.818 1zm0 2h14v6a3 3 0 0 0 3 3h6v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" fill="#fff" fill-opacity=".588"/></svg>
diff --git a/editor/icons/GPUParticlesCollisionSphere3D.svg b/editor/icons/GPUParticlesCollisionSphere3D.svg
index 4aa3f7c5bf..4eeec807f6 100644
--- a/editor/icons/GPUParticlesCollisionSphere3D.svg
+++ b/editor/icons/GPUParticlesCollisionSphere3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M 8 4 a 5 5 0 0 0 0 10 a 5 5 0 0 0 0 -10 v 10 m -4.95 -5.6 a 5 2 0 0 0 9.9 0" fill="none" stroke-width="1.667" stroke="#fc7f7f"/><g fill="#fc7f7f"><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg>
diff --git a/editor/icons/Gizmo3DSamplePlayer.svg b/editor/icons/Gizmo3DSamplePlayer.svg
index d174bcfe07..dc379b6076 100644
--- a/editor/icons/Gizmo3DSamplePlayer.svg
+++ b/editor/icons/Gizmo3DSamplePlayer.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -924.36)"><path d="m63.766 932.37c-2.0369.0594-3.9779.89602-5.4199 2.3359l-.002.002-29.656 29.658h-12.688c-4.3705.00044-7.9996 3.6295-8 8v32c.0004372 4.3705 3.6295 7.9995 8 8h12.688l29.656 29.656c2.4 2.3983 5.9795 2.8662 8.7168 1.7324 2.7373-1.1337 4.9381-3.9958 4.9395-7.3886v-96.004c-.003-4.4555-3.779-8.1211-8.2324-7.9922zm48.234 3.9941c-4.3709 0-8 3.6291-8 8v88c0 4.3709 3.6291 8 8 8s8-3.6291 8-8v-88c0-4.3709-3.6291-8-8-8zm-24 24c-4.3709 0-8 3.6291-8 8v40c0 4.3709 3.6291 8 8 8s8-3.6291 8-8v-40c0-4.3709-3.6291-8-8-8z" fill-opacity=".29412"/><path d="m63.883 12.004c-1.0195.0295-1.9892.4473-2.7109 1.168l-30.828 30.83h-14.344c-2.209.000221-3.9998 1.791-4 4v32c.000221 2.209 1.791 3.9998 4 4h14.344l30.828 30.828c2.52 2.5182 6.8267.73442 6.8281-2.8281v-96.002c-.0015-2.2541-1.8641-4.0619-4.1172-3.9961zm48.117 3.9961a4 4 0 0 0 -4 4v88a4 4 0 0 0 4 4 4 4 0 0 0 4-4v-88a4 4 0 0 0 -4-4zm-24 24a4 4 0 0 0 -4 4v40a4 4 0 0 0 4 4 4 4 0 0 0 4-4v-40a4 4 0 0 0 -4-4z" fill="#f7f5cf" transform="translate(0 924.36)"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M63.766 8.01a8.006 8.006 0 0 0-5.42 2.336l-.002.002-29.656 29.658H16c-4.37 0-8 3.63-8 8v32c0 4.37 3.63 8 8 8h12.688l29.656 29.656c2.4 2.398 5.98 2.866 8.717 1.732 2.737-1.133 4.938-3.996 4.94-7.388V16.002c-.004-4.456-3.78-8.121-8.233-7.992zM112 12.004c-4.37 0-8 3.63-8 8v88c0 4.371 3.63 8 8 8s8-3.629 8-8v-88c0-4.37-3.63-8-8-8zm-24 24c-4.37 0-8 3.63-8 8v40c0 4.371 3.63 8 8 8s8-3.629 8-8v-40c0-4.37-3.63-8-8-8z" fill-opacity=".294"/><path d="M63.883 12.004a4 4 0 0 0-2.71 1.168l-30.829 30.83H16a4 4 0 0 0-4 4v32a4 4 0 0 0 4 4h14.344l30.828 30.828c2.52 2.518 6.827.734 6.828-2.828V16a4 4 0 0 0-4.117-3.996zM112 16a4 4 0 0 0-4 4v88a4 4 0 0 0 4 4 4 4 0 0 0 4-4V20a4 4 0 0 0-4-4zM88 40a4 4 0 0 0-4 4v40a4 4 0 0 0 4 4 4 4 0 0 0 4-4V44a4 4 0 0 0-4-4z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/GizmoAudioListener3D.svg b/editor/icons/GizmoAudioListener3D.svg
index 9d3ddf8b85..66a1f8fd5d 100644
--- a/editor/icons/GizmoAudioListener3D.svg
+++ b/editor/icons/GizmoAudioListener3D.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(2 0 0 2 -16 -1964.76)"><path d="m32 984.36c-12.126.00002-22 9.8729-22 21.999.00011 1.1045.89548 1.9999 2 2h8c1.1045-.0001 1.9999-.8955 2-2 .000223-5.546 4.4536-9.999 10-9.999 5.5464.00001 9.9998 4.453 10 9.999 0 6.5873-1.6032 8.0251-3.8408 9.8897-1.0295.8579-2.3133 1.6111-3.7969 2.6826-.72285.522-1.6649 1.2341-2.5488 2.3496-.98288 1.2402-1.8135 2.99-1.8135 5.0781 0 2.3898-.31658 3.686-.61035 4.3194-.29378.6333-.4706.73-.97754 1.0341-.54947.3297-2.5162.6446-4.4121.6446-.0065.0003-.01302.0006-.01953.001h-3.9805c-1.1045.0001-1.9999.8954-2 2v8c.00011 1.1045.89548 1.9999 2 2h4c.0072-.0003.01432-.0005.02148-.001 1.9052.001 6.3098.1982 10.566-2.3555 4.0103-2.4061 6.6628-7.2724 7.1738-13.592.81224-.548 2.3445-1.497 4.0791-2.9424 4.0025-3.3353 8.1592-9.5405 8.1592-19.108-.000095-12.126-9.8735-21.999-22-21.999zm31.807 4.002c-.38259-.0177-.76221.0749-1.0938.2666l-6.9531 4.0156c-.95754.55332-1.2843 1.7787-.72949 2.7354 1.9364 3.3365 2.9609 7.1229 2.9717 10.98-.0072 3.8597-1.0296 7.6487-2.9648 10.988-.55452.9572-.22681 2.1827.73144 2.7353l6.9453 4.0069c.95656.5517 2.1792.2238 2.7314-.7325 6.0717-10.516 6.0717-23.482 0-33.998-.3406-.59005-.95812-.96615-1.6387-.99805z" fill-opacity=".29412"/><path d="m48 8a40 39.998 0 0 0 -40 39.998h16a24 23.999 0 0 1 24-23.998 24 23.999 0 0 1 24 23.998c0 13.999-4.33 18.859-9.1211 22.852-2.3955 1.9962-5.0363 3.5302-7.8125 5.5352-1.3881 1.0024-2.8661 2.126-4.3047 3.9414-1.4385 1.8152-2.7617 4.6719-2.7617 7.6719 0 10.221-2.5383 12.59-5.1172 14.137-2.5789 1.5472-6.8828 1.8594-10.883 1.8594v.00195h-8v16h8v-.00195c4 0 11.696.31158 19.117-4.1406 7.0602-4.236 12.198-13.279 12.695-26 .1835-.1636.14883-.15489.62109-.49609 1.7238-1.245 5.083-3.2112 8.6875-6.2148 7.209-6.0072 14.879-17.145 14.879-35.145a40 39.998 0 0 0 -40-39.998zm63.426 8-13.906 8.0312a48 47.998 0 0 1 6.4844 23.967 48 47.998 0 0 1 -6.4688 23.984l13.891 8.0137a64 63.997 0 0 0 0-63.996z" fill="#f7f5cf" transform="matrix(.5 0 0 .5 8 982.36)"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M48 3.96c-24.252 0-44 19.746-44 43.998a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4A19.94 19.94 0 0 1 48 27.96a19.94 19.94 0 0 1 20 19.998c0 13.174-3.206 16.05-7.68 19.78-2.06 1.716-4.628 3.22-7.596 5.364-1.446 1.044-3.33 2.468-5.098 4.7C45.662 80.282 44 83.782 44 87.958c0 4.78-.634 7.372-1.22 8.64-.588 1.266-.942 1.46-1.956 2.066-1.1.66-5.032 1.29-8.824 1.29l-.04.002H24a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h8.042c3.812 0 12.62.394 21.132-4.712 8.02-4.812 13.326-14.546 14.348-27.184 1.624-1.096 4.69-2.994 8.16-5.886C83.686 79.504 92 67.094 92 47.958 92 23.706 72.252 3.96 48 3.96zm63.614 8.004a4 4 0 0 0-2.188.534l-13.906 8.03A4 4 0 0 0 94.06 26a43.992 43.992 0 0 1 5.944 21.96 43.99 43.99 0 0 1-5.928 21.976 4 4 0 0 0 1.462 5.47l13.89 8.014a4 4 0 0 0 5.464-1.466 68.01 68.01 0 0 0 0-67.996 4 4 0 0 0-3.278-1.996z" fill-opacity=".294"/><path d="M48 7.96A40 39.998 0 0 0 8 47.958h16A24 24 0 0 1 48 23.96a24 24 0 0 1 24 23.998c0 14-4.33 18.86-9.12 22.852-2.396 1.996-5.038 3.53-7.814 5.536-1.388 1-2.866 2.126-4.304 3.94C49.322 82.102 48 84.958 48 87.958c0 10.22-2.54 12.59-5.118 14.138-2.578 1.546-6.882 1.86-10.882 1.86h-8v16h8c4 0 11.696.31 19.116-4.14 7.06-4.238 12.2-13.28 12.696-26 .184-.166.148-.156.62-.498 1.724-1.244 5.084-3.21 8.688-6.214C80.33 77.096 88 65.958 88 47.958A40 39.998 0 0 0 48 7.96zm63.426 8L97.52 23.992a48 47.998 0 0 1 6.484 23.966 48 47.998 0 0 1-6.468 23.984l13.89 8.014a64 63.996 0 0 0 0-63.996z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/GizmoCPUParticles3D.svg b/editor/icons/GizmoCPUParticles3D.svg
index e62dd530c4..391c126c28 100644
--- a/editor/icons/GizmoCPUParticles3D.svg
+++ b/editor/icons/GizmoCPUParticles3D.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m35.503779 1.2819066c-3.570424 0-6.435164 2.9483368-6.435164 6.6019028v4.3900146c0 .889114.169457 1.726301.478513 2.49893h-10.081759c-3.570424 0-6.435167 2.931453-6.435167 6.585021v7.969562c-.341543-.0568-.648813-.202614-1.006525-.202614h-4.2901096c-3.5704232 0-6.451665 2.948338-6.451665 6.601904v3.224972c0 3.653568 2.8812418 6.585016 6.451665 6.585016h4.2901096c.358169 0 .664563-.14568 1.006525-.202618v38.497043c-.341543-.05706-.648814-.202616-1.006525-.202616h-4.2901096c-3.5704232 0-6.451665 2.948332-6.451665 6.601908v3.224971c0 3.653575 2.8812418 6.585017 6.451665 6.585017h4.2901096c.358169 0 .664563-.145692 1.006525-.202612v9.725542c0 3.6536 2.864743 6.60193 6.435167 6.60193h9.603246v3.951c0 3.65357 2.86474 6.60192 6.435164 6.60192h3.15158c3.57042 0 6.451663-2.94836 6.451663-6.60192v-3.95104h37.224955v3.951c0 3.65358 2.86474 6.60193 6.435166 6.60193h3.151583c3.570418 0 6.451653-2.94836 6.451653-6.60193v-3.951h10.725281c3.57043 0 6.45166-2.94833 6.45166-6.60191v-9.607372c.14985.0105.27643.0846.42899.0846h4.29014c3.5704 0 6.45165-2.931432 6.45165-6.585011v-3.224992c0-3.653565-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07348-.42899.08472v-38.261071c.14985.01042.27643.08445.42899.08445h4.29014c3.5704 0 6.45165-2.931451 6.45165-6.585023v-3.224986c0-3.653566-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07392-.42899.08446v-7.851429c0-3.653567-2.88123-6.585019-6.45166-6.585021h-11.220281c.309043-.772641.494982-1.609791.494982-2.498929v-4.3900086c0-3.6535651-2.881246-6.601903-6.451662-6.601903h-3.15158c-3.570428 0-6.435167 2.9483379-6.435167 6.601903v4.3900146c0 .889115.16948 1.726301.478507 2.49893h-38.198448c.309083-.772642.495011-1.609792.495011-2.49893v-4.3900146c0-3.6535651-2.881243-6.601903-6.451663-6.601903z" fill="#f7f5cf" stroke="#b3b3b3" stroke-width="2.563805"/><g fill="#b3b3b3" stroke-width="8.546018"><path d="m62.861474 21.661698a27.707285 31.502779 0 0 1 27.143197 25.411422 18.471523 18.901669 0 0 1 15.955909 18.691329 18.471523 18.901669 0 0 1 -18.480472 18.893947h-49.25376a18.471523 18.901669 0 0 1 -18.463973-18.893947 18.471523 18.901669 0 0 1 15.922908-18.708215 27.707285 31.502779 0 0 1 27.176191-25.394536z"/><path d="m38.226348 90.956369a6.1571744 6.3005562 0 0 1 6.154657 6.297979 6.1571744 6.3005562 0 0 1 -6.154657 6.314882 6.1571744 6.3005562 0 0 1 -6.154657-6.314882 6.1571744 6.3005562 0 0 1 6.154657-6.297979z"/><path d="m87.480108 90.956369a6.1571744 6.3005562 0 0 1 6.171159 6.297979 6.1571744 6.3005562 0 0 1 -6.171159 6.314882 6.1571744 6.3005562 0 0 1 -6.154656-6.314882 6.1571744 6.3005562 0 0 1 6.154656-6.297979z"/><path d="m62.861474 97.254348a6.1571744 6.3005562 0 0 1 6.154662 6.314882 6.1571744 6.3005562 0 0 1 -6.154662 6.29797 6.1571744 6.3005562 0 0 1 -6.154651-6.29797 6.1571744 6.3005562 0 0 1 6.154651-6.314882z"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M35.504 1.282c-3.57 0-6.435 2.948-6.435 6.602v4.39c0 .889.17 1.726.478 2.499H19.465c-3.57 0-6.435 2.931-6.435 6.585v7.97c-.341-.057-.649-.203-1.006-.203h-4.29c-3.57 0-6.452 2.948-6.452 6.602v3.225c0 3.653 2.881 6.585 6.452 6.585h4.29c.358 0 .664-.146 1.006-.203v38.497c-.341-.057-.649-.203-1.006-.203h-4.29c-3.57 0-6.452 2.949-6.452 6.602v3.225c0 3.654 2.881 6.585 6.452 6.585h4.29c.358 0 .664-.145 1.006-.202v9.725c0 3.654 2.865 6.602 6.435 6.602h9.604v3.951c0 3.654 2.864 6.602 6.435 6.602h3.151c3.57 0 6.452-2.948 6.452-6.602v-3.95h37.225v3.95c0 3.654 2.865 6.602 6.435 6.602h3.152c3.57 0 6.451-2.948 6.451-6.602v-3.95h10.726c3.57 0 6.451-2.95 6.451-6.603v-9.607c.15.01.277.084.43.084h4.29c3.57 0 6.451-2.931 6.451-6.585V90.23c0-3.653-2.881-6.601-6.452-6.601h-4.29c-.152 0-.28.073-.429.084v-38.26c.15.01.277.084.43.084h4.29c3.57 0 6.451-2.932 6.451-6.585v-3.225c0-3.654-2.881-6.602-6.452-6.602h-4.29c-.152 0-.28.074-.429.084v-7.851c0-3.654-2.88-6.585-6.451-6.585h-11.22a6.7 6.7 0 0 0 .494-2.5v-4.39c0-3.653-2.88-6.601-6.451-6.601h-3.152c-3.57 0-6.435 2.948-6.435 6.602v4.39c0 .889.17 1.726.478 2.499H44.612c.31-.773.495-1.61.495-2.5v-4.39c0-3.653-2.881-6.601-6.452-6.601z" fill="#f7f5cf" stroke="#b3b3b3" stroke-width="2.564"/><path d="M62.861 21.662a27.707 31.503 0 0 1 27.144 25.411 18.472 18.902 0 0 1 15.956 18.691 18.472 18.902 0 0 1-18.48 18.894H38.225a18.472 18.902 0 0 1-18.464-18.894 18.472 18.902 0 0 1 15.923-18.708A27.707 31.503 0 0 1 62.86 21.662zM38.226 90.956a6.157 6.3 0 0 1 6.155 6.298 6.157 6.3 0 0 1-6.155 6.315 6.157 6.3 0 0 1-6.154-6.315 6.157 6.3 0 0 1 6.154-6.298zm49.254 0a6.157 6.3 0 0 1 6.171 6.298 6.157 6.3 0 0 1-6.17 6.315 6.157 6.3 0 0 1-6.156-6.315 6.157 6.3 0 0 1 6.155-6.298zm-24.619 6.298a6.157 6.3 0 0 1 6.155 6.315 6.157 6.3 0 0 1-6.155 6.298 6.157 6.3 0 0 1-6.154-6.298 6.157 6.3 0 0 1 6.154-6.315z" fill="#b3b3b3"/></svg>
diff --git a/editor/icons/GizmoDirectionalLight.svg b/editor/icons/GizmoDirectionalLight.svg
index cb80b31f91..c736e86dee 100644
--- a/editor/icons/GizmoDirectionalLight.svg
+++ b/editor/icons/GizmoDirectionalLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 4c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8zm-36.77 15.223c-2.045 0-4.0893.78461-5.6562 2.3516-3.1339 3.1339-3.1339 8.1786 0 11.312l11.312 11.314c3.1339 3.1339 8.1806 3.1339 11.314 0s3.1339-8.1806 0-11.314l-11.314-11.312c-1.5669-1.5669-3.6113-2.3516-5.6562-2.3516zm73.539 0c-2.045 0-4.0893.78461-5.6562 2.3516l-11.314 11.312c-3.1339 3.1339-3.1339 8.1806 0 11.314s8.1806 3.1339 11.314 0l11.312-11.314c3.1339-3.1339 3.1339-8.1786 0-11.312-1.567-1.5669-3.6113-2.3516-5.6562-2.3516zm-36.77 20.777a24 24 0 0 0 -24 24 24 24 0 0 0 24 24 24 24 0 0 0 24-24 24 24 0 0 0 -24-24zm-52 16c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm88 0c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm-61.455 25.449c-2.045 0-4.0913.78266-5.6582 2.3496l-11.312 11.314c-3.1339 3.1339-3.1339 8.1786 0 11.312 3.1339 3.1339 8.1786 3.1339 11.312 0l11.314-11.312c3.1339-3.1339 3.1339-8.1806 0-11.314-1.5669-1.5669-3.6113-2.3496-5.6562-2.3496zm50.91 0c-2.045 0-4.0893.78266-5.6562 2.3496-3.1339 3.1339-3.1339 8.1806 0 11.314l11.314 11.312c3.1339 3.1339 8.1786 3.1339 11.312 0s3.1339-8.1786 0-11.312l-11.312-11.314c-1.5669-1.5669-3.6132-2.3496-5.6582-2.3496zm-25.455 10.551c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><path d="m64 8c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4zm-36.77 15.227c-1.0225 0-2.0447.39231-2.8281 1.1758-1.5669 1.5669-1.5669 4.0893 0 5.6562l11.312 11.314c1.5669 1.5669 4.0913 1.5669 5.6582 0s1.5669-4.0913 0-5.6582l-11.314-11.312c-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm73.539 0c-1.0225 0-2.0446.39231-2.8281 1.1758l-11.314 11.312c-1.5669 1.5669-1.5669 4.0913 0 5.6582s4.0913 1.5669 5.6582 0l11.313-11.314c1.5669-1.5669 1.5669-4.0893 0-5.6562-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm-36.77 20.773c-11.046.00001-20 8.9543-20 20 .000007 11.046 8.9543 20 20 20s20-8.9543 20-20c-.000008-11.046-8.9543-20-20-20zm-52 16c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm88 0c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm-61.455 25.453c-1.0225 0-2.0466.39035-2.8301 1.1738l-11.312 11.314c-1.5669 1.5669-1.5669 4.0893 0 5.6563 1.5669 1.5669 4.0893 1.5669 5.6562 0l11.314-11.313c1.5669-1.5669 1.5669-4.0913 0-5.6582-.78347-.78347-1.8056-1.1738-2.8281-1.1738zm50.91 0c-1.0225 0-2.0447.39035-2.8281 1.1738-1.5669 1.5669-1.5669 4.0913 0 5.6582l11.314 11.313c1.5669 1.5669 4.0893 1.5669 5.6563 0 1.5669-1.567 1.5669-4.0893 0-5.6563l-11.313-11.314c-.78347-.78347-1.8076-1.1738-2.8301-1.1738zm-25.455 10.547c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4z" fill="#ffffff"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M64 4c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8V12c0-4.432-3.568-8-8-8zM27.23 19.223c-2.045 0-4.09.785-5.656 2.352a7.98 7.98 0 0 0 0 11.312L32.886 44.2c3.134 3.134 8.18 3.134 11.314 0s3.134-8.181 0-11.314L32.886 21.575a7.975 7.975 0 0 0-5.656-2.352zm73.539 0c-2.045 0-4.09.785-5.656 2.352L83.799 32.887c-3.134 3.134-3.134 8.18 0 11.314s8.18 3.134 11.314 0l11.312-11.314a7.98 7.98 0 0 0 0-11.312 7.975 7.975 0 0 0-5.656-2.352zM63.999 40a24 24 0 0 0-24 24 24 24 0 0 0 24 24 24 24 0 0 0 24-24 24 24 0 0 0-24-24zm-52 16c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm88 0c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zM38.544 81.449a7.977 7.977 0 0 0-5.658 2.35L21.574 95.113a7.98 7.98 0 0 0 0 11.312 7.98 7.98 0 0 0 11.312 0L44.2 95.113a7.983 7.983 0 0 0 0-11.314 7.973 7.973 0 0 0-5.656-2.35zm50.91 0a7.97 7.97 0 0 0-5.656 2.35 7.983 7.983 0 0 0 0 11.314l11.314 11.312c3.134 3.133 8.178 3.133 11.312 0s3.134-8.179 0-11.312L95.112 83.799a7.977 7.977 0 0 0-5.658-2.35zM63.999 92c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8z" fill-opacity=".294"/><path d="M64 8c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4V12c0-2.216-1.784-4-4-4zM27.23 23.227a3.987 3.987 0 0 0-2.828 1.176 3.99 3.99 0 0 0 0 5.656l11.312 11.314c1.567 1.567 4.091 1.567 5.658 0s1.567-4.091 0-5.658L30.058 24.403a3.987 3.987 0 0 0-2.828-1.176zm73.539 0a3.987 3.987 0 0 0-2.828 1.176L86.627 35.715c-1.567 1.567-1.567 4.091 0 5.658s4.091 1.567 5.658 0l11.313-11.314a3.99 3.99 0 0 0 0-5.656 3.987 3.987 0 0 0-2.828-1.176zM63.999 44c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20zm-52 16c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm88 0c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zM38.544 85.453a3.99 3.99 0 0 0-2.83 1.174L24.402 97.94a3.99 3.99 0 0 0 0 5.656 3.99 3.99 0 0 0 5.656 0l11.314-11.313a3.993 3.993 0 0 0 0-5.658 3.985 3.985 0 0 0-2.828-1.174zm50.91 0c-1.022 0-2.045.39-2.828 1.174a3.993 3.993 0 0 0 0 5.658l11.314 11.313a3.99 3.99 0 0 0 5.656 0 3.99 3.99 0 0 0 0-5.656L92.283 86.628a3.99 3.99 0 0 0-2.83-1.174zM63.999 96c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4z" fill="#fff"/></svg>
diff --git a/editor/icons/GizmoGPUParticles3D.svg b/editor/icons/GizmoGPUParticles3D.svg
index 126ece6d4d..3e96123d00 100644
--- a/editor/icons/GizmoGPUParticles3D.svg
+++ b/editor/icons/GizmoGPUParticles3D.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -924.36)"><path d="m63.998 928.36c-18.429.005-34.029 13.88-38.557 32.926-12.4 3.0077-21.427 14.08-21.441 27.07v.004c0 15.417 12.583 28 28 28h64c15.417 0 28-12.583 28-28v-.004c-.0152-13-9.0549-24.076-21.467-27.074-4.5265-19.033-20.112-32.903-38.529-32.922zm32.002 88c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12zm-64 0c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12zm32 8c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12z" fill-opacity=".29412"/><path d="m64 8a36 40 0 0 0 -35.311 32.256 24 24 0 0 0 -20.689 23.744 24 24 0 0 0 24 24h64a24 24 0 0 0 24-24 24 24 0 0 0 -20.715-23.746 36 40 0 0 0 -35.285-32.254zm-32 88a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0 -8-8zm64 0a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0 -8-8zm-32 8a8 8 0 0 0 -8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0 -8-8z" fill="#f7f5cf" transform="translate(0 924.36)"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M63.998 4c-18.429.005-34.029 13.88-38.557 32.926C13.041 39.934 4.014 51.006 4 63.996V64c0 15.417 12.583 28 28 28h64c15.417 0 28-12.583 28-28v-.004c-.015-13-9.055-24.076-21.467-27.074C98.006 17.889 82.421 4.019 64.004 4zM96 92c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12zm-64 0c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12zm32 8c-6.58 0-12 5.42-12 12s5.42 12 12 12 12-5.42 12-12-5.42-12-12-12z" fill-opacity=".294"/><path d="M64 8a36 40 0 0 0-35.311 32.256A24 24 0 0 0 8 64a24 24 0 0 0 24 24h64a24 24 0 0 0 24-24 24 24 0 0 0-20.715-23.746A36 40 0 0 0 64 8zM32 96a8 8 0 0 0-8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0-8-8zm64 0a8 8 0 0 0-8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0-8-8zm-32 8a8 8 0 0 0-8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0-8-8z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/GizmoLight.svg b/editor/icons/GizmoLight.svg
index ff224f32c9..8009af81a5 100644
--- a/editor/icons/GizmoLight.svg
+++ b/editor/icons/GizmoLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 2a44 44 0 0 0 -44 44 44 44 0 0 0 24 39.189v5.8105 5 3c0 5.0515 3.3756 9.2769 8 10.578v16.422h24v-16.422c4.6244-1.3012 8-5.5266 8-10.578v-3-5-5.8574a44 44 0 0 0 24-39.143 44 44 0 0 0 -44-44zm0 20a24 24 0 0 1 24 24 24 24 0 0 1 -24 24 24 24 0 0 1 -24-24 24 24 0 0 1 24-24z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.2"/><path d="m64 6a40 40 0 0 0 -40 40 40 40 0 0 0 24 36.607v15.393a8 8 0 0 0 8 8h16a8 8 0 0 0 8-8v-15.363a40 40 0 0 0 24-36.637 40 40 0 0 0 -40-40zm0 12a28 28 0 0 1 28 28 28 28 0 0 1 -28 28 28 28 0 0 1 -28-28 28 28 0 0 1 28-28zm-8 96v8h16v-8z" fill="#ffffff"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M64 2a44 44 0 0 0-44 44 44 44 0 0 0 24 39.189v13.81a10.97 10.97 0 0 0 8 10.579v16.421h24v-16.421a10.97 10.97 0 0 0 8-10.579V85.142A44 44 0 0 0 108 46 44 44 0 0 0 64 2zm0 20a24 24 0 0 1 24 24 24 24 0 0 1-24 24 24 24 0 0 1-24-24 24 24 0 0 1 24-24z" fill-opacity=".294"/><path d="M64 6a40 40 0 0 0-40 40 40 40 0 0 0 24 36.607V98a8 8 0 0 0 8 8h16a8 8 0 0 0 8-8V82.637A40 40 0 0 0 104 46 40 40 0 0 0 64 6zm0 12a28 28 0 0 1 28 28 28 28 0 0 1-28 28 28 28 0 0 1-28-28 28 28 0 0 1 28-28zm-8 96v8h16v-8z" fill="#fff"/></svg>
diff --git a/editor/icons/GizmoLightmapGI.svg b/editor/icons/GizmoLightmapGI.svg
index a7828615fd..64fc17a127 100644
--- a/editor/icons/GizmoLightmapGI.svg
+++ b/editor/icons/GizmoLightmapGI.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m18 8c-2.209.00022-3.9998 1.791-4 4l.01563 20h-6.0156c-2.209.00022-3.9998 1.791-4 4v71.076c0 9.3065 7.6174 16.924 16.924 16.924h61.076c2.209-.0002 3.9998-1.791 4-4v-12c-.000221-2.209-1.791-3.9998-4-4h-58v-40h20v12c.000221 2.209 1.791 3.9998 4 4h32c2.209-.0002 3.9998-1.791 4-4v-12h20v4c.002.72576.20093 1.4374.57617 2.0586-.19584-.006-.37901-.058594-.57617-.058594-10.998 0-20 9.0016-20 20-.000004 0-.000004.0098 0 .0098.0088 6.2734 3.0833 12.01 8 15.756v2.2383c0 2.8834 1.66 5.3456 4 6.75v5.2461c.000221 2.209 1.791 3.9998 4 4h8c2.209-.0002 3.9998-1.791 4-4v-5.248c2.3405-1.4043 4-3.8682 4-6.752v-2.2344c4.9179-3.7475 7.9931-9.4866 8-15.762 0-7.935-4.7186-14.774-11.459-18h7.459c2.209-.00022 3.9998-1.791 4-4v-32c-.00022-2.209-1.791-3.9998-4-4l-6-.003906v-19.996c-.00022-2.209-1.791-3.9998-4-4zm8 38c1.1519 0 2 .84806 2 2 .000003 1.1519-.84806 2-2 2s-2-.84806-2-2c-.000003-1.1519.84806-2 2-2zm25 0c1.1519 0 2 .84806 2 2 .000003 1.1519-.84806 2-2 2s-2-.84806-2-2c-.000003-1.1519.84806-2 2-2zm26 0c1.1519 0 2 .84806 2 2 .000003 1.1519-.84806 2-2 2s-2-.84806-2-2c-.000003-1.1519.84806-2 2-2zm25 0c1.1519 0 2 .84806 2 2s-.84806 2-2 2-2-.84806-2-2c-.000003-1.1519.84806-2 2-2zm2 38c3.3611 0 6 2.6388 6 6 0 3.361-2.639 6-6 6s-6-2.639-6-6c0-3.3612 2.6389-6 6-6z" fill-opacity=".29412"/><path d="m18 12v16h92v-16zm-10 24v71.076c0 7.1594 5.7644 12.924 12.924 12.924h61.076v-12h-62v-48h88v8h12v-32zm18 6c3.3137-.00001 6 2.6863 6 6 .000009 3.3137-2.6863 6-6 6-3.3137.00001-6-2.6863-6-6-.000009-3.3137 2.6863-6 6-6zm25 0c3.3137-.00001 6 2.6863 6 6 .000009 3.3137-2.6863 6-6 6-3.3137.00001-6-2.6863-6-6-.000009-3.3137 2.6863-6 6-6zm26 0c3.3137-.00001 6 2.6863 6 6 .000009 3.3137-2.6863 6-6 6-3.3137.00001-6-2.6863-6-6-.000009-3.3137 2.6863-6 6-6zm25 0c3.3137-.00001 6 2.6863 6 6 .00001 3.3137-2.6863 6-6 6-3.3137.00001-6-2.6863-6-6-.000009-3.3137 2.6863-6 6-6zm-54 26v8h32v-8zm56 6c-8.8365 0-16 7.1634-16 16 .008 5.7082 3.0565 10.98 8 13.834v4.166c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-4.1602c4.945-2.855 7.9937-8.1299 8-13.84 0-8.8366-7.1635-16-16-16zm0 6c5.5228 0 10 4.4771 10 10 0 5.5228-4.4772 10-10 10s-10-4.4772-10-10c0-5.5229 4.4772-10 10-10zm-4 36v4h8v-4z" fill="#f7f5cf"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M18 8a4 4 0 0 0-4 4l.016 20H8a4 4 0 0 0-4 4v71.076C4 116.382 11.617 124 20.924 124H82a4 4 0 0 0 4-4v-12a4 4 0 0 0-4-4H24V64h20v12a4 4 0 0 0 4 4h32a4 4 0 0 0 4-4V64h20v4c.002.726.201 1.437.576 2.059-.196-.006-.379-.059-.576-.059-10.998 0-20 9.002-20 20v.01c.009 6.273 3.083 12.01 8 15.756v2.238c0 2.884 1.66 5.346 4 6.75V120a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4v-5.248c2.34-1.404 4-3.868 4-6.752v-2.234c4.918-3.748 7.993-9.487 8-15.762 0-7.935-4.719-14.774-11.459-18H120a4 4 0 0 0 4-4v-32a4 4 0 0 0-4-4L114 32V12.004a4 4 0 0 0-4-4zm8 38c1.152 0 2 .848 2 2 0 1.152-.848 2-2 2s-2-.848-2-2c0-1.152.848-2 2-2zm25 0c1.152 0 2 .848 2 2 0 1.152-.848 2-2 2s-2-.848-2-2c0-1.152.848-2 2-2zm26 0c1.152 0 2 .848 2 2 0 1.152-.848 2-2 2s-2-.848-2-2c0-1.152.848-2 2-2zm25 0c1.152 0 2 .848 2 2s-.848 2-2 2-2-.848-2-2c0-1.152.848-2 2-2zm2 38c3.361 0 6 2.639 6 6s-2.639 6-6 6-6-2.639-6-6 2.639-6 6-6z" fill-opacity=".294"/><path d="M18 12v16h92V12zM8 36v71.076C8 114.236 13.764 120 20.924 120H82v-12H20V60h88v8h12V36zm18 6a6 6 0 1 1 0 12 6 6 0 0 1 0-12zm25 0a6 6 0 1 1 0 12 6 6 0 0 1 0-12zm26 0a6 6 0 1 1 0 12 6 6 0 0 1 0-12zm25 0a6 6 0 1 1 0 12 6 6 0 0 1 0-12zM48 68v8h32v-8zm56 6c-8.836 0-16 7.163-16 16a16 16 0 0 0 8 13.834V108c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-4.16A16.002 16.002 0 0 0 120 90c0-8.837-7.163-16-16-16zm0 6c5.523 0 10 4.477 10 10s-4.477 10-10 10-10-4.477-10-10 4.477-10 10-10zm-4 36v4h8v-4z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/GizmoReflectionProbe.svg b/editor/icons/GizmoReflectionProbe.svg
index 60895a18af..ee8138295c 100644
--- a/editor/icons/GizmoReflectionProbe.svg
+++ b/editor/icons/GizmoReflectionProbe.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -924.36)"><path d="m12 928.36c-4.3705.00044-7.9996 3.6295-8 8v28h16v-20h88v8h16v-16c-.00044-4.3705-3.6295-7.9996-8-8zm76 28c-4.3709 0-8 3.6291-8 8s3.6291 8 8 8h10.035l-34.486 40.236-44.721-44.723-11.312 11.316 50.828 50.828c3.2536 3.2513 8.7374 3.0394 11.73-.4531l37.926-44.244v7.0391c0 4.3709 3.6291 8 8 8s8-3.6291 8-8v-28c-.00044-4.3705-3.6295-7.9996-8-8zm-84 52v32c.000437 4.3705 3.6295 7.9996 8 8h104c4.3705-.0004 7.9996-3.6295 8-8v-32h-16v24h-88v-24z" fill-opacity=".29412"/><path d="m12 932.36c-2.209.00022-3.9998 1.791-4 4v24h8v-20h96v8h8v-12c-.00022-2.209-1.791-3.9998-4-4zm76 28c-2.2091 0-4 1.7909-4 4s1.7909 4 4 4h18.732l-42.957 50.119-44.947-44.947-5.6562 5.6582 48 48c1.648 1.6468 4.3491 1.5425 5.8652-.2266l44.963-52.457v17.854c0 2.2091 1.7909 4 4 4s4-1.7909 4-4v-28c-.00022-2.209-1.791-3.9998-4-4zm-80 52v28c.0002209 2.2091 1.791 3.9998 4 4h104c2.209-.0002 3.9998-1.7909 4-4v-28h-8v24h-96v-24z" fill="#f7f5cf"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M12 4c-4.37 0-8 3.63-8 8v28h16V20h88v8h16V12c0-4.37-3.63-8-8-8zm76 28c-4.37 0-8 3.63-8 8s3.63 8 8 8h10.035L63.549 88.236 18.828 43.513 7.516 54.829l50.828 50.828c3.254 3.251 8.737 3.04 11.73-.453L108 60.96v7.039c0 4.37 3.63 8 8 8s8-3.63 8-8v-28c0-4.37-3.63-8-8-8zM4 84v32c0 4.37 3.63 8 8 8h104c4.37 0 8-3.63 8-8V84h-16v24H20V84z" fill-opacity=".294"/><path d="M12 8a4 4 0 0 0-4 4v24h8V16h96v8h8V12a4 4 0 0 0-4-4zm76 28a4 4 0 0 0 0 8h18.732L63.775 94.119 18.828 49.172l-5.656 5.658 48 48a4 4 0 0 0 5.865-.226L112 50.147v17.854a4 4 0 0 0 8 0v-28a4 4 0 0 0-4-4zM8 88v28a4 4 0 0 0 4 4h104a4 4 0 0 0 4-4V88h-8v24H16V88z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/GizmoSpotLight.svg b/editor/icons/GizmoSpotLight.svg
index d1a576ce22..c943ed7a7b 100644
--- a/editor/icons/GizmoSpotLight.svg
+++ b/editor/icons/GizmoSpotLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m52 4c-6.5788 0-12 5.4212-12 12v26.625c-12.263 7.2822-19.978 19.75-20 33.369l-.005859 4.0059h28.578c1.7994 6.8632 8.0265 12 15.428 12s13.628-5.1368 15.428-12h28.576l-.00391-4.0039c-.01526-13.625-7.7323-26.099-20-33.385v-26.611c0-6.5788-5.4212-12-12-12zm-11.689 78.016c-1.536-.10738-3.1419.23676-4.5586 1.0547l-10.393 6c-3.7786 2.1816-5.1117 7.1503-2.9297 10.93 2.1816 3.7786 7.1503 5.1117 10.93 2.9297l10.393-6c3.7796-2.1822 5.1087-7.1521 2.9277-10.93-1.3629-2.3605-3.8057-3.8052-6.3691-3.9844zm47.379 0c-2.5634.1792-5.0063 1.6238-6.3691 3.9844-2.181 3.7776-.85187 8.7475 2.9277 10.93l10.393 6c3.7794 2.182 8.7481.8489 10.93-2.9297 2.182-3.7794.84891-8.7481-2.9297-10.93l-10.393-6c-1.4167-.81792-3.0225-1.1621-4.5586-1.0547zm-23.689 13.984c-4.3628 0-8 3.6372-8 8v12c0 4.3628 3.6372 8 8 8s8-3.6372 8-8v-12c0-4.3628-3.6372-8-8-8z" fill-opacity=".29412"/><path d="m52 8c-4.432 0-8 3.568-8 8v12 16.875a40 36 0 0 0 -20 31.125h28a12 12 0 0 0 12 12 12 12 0 0 0 12-12h28a40 36 0 0 0 -20-31.141v-20.859-8c0-4.432-3.568-8-8-8zm-11.969 78.006c-.76793-.053681-1.5596.1138-2.2793.5293l-10.393 6c-1.9191 1.108-2.5728 3.5457-1.4648 5.4648s3.5457 2.5728 5.4648 1.4648l10.393-6c1.9191-1.108 2.5709-3.5457 1.4629-5.4648-.6925-1.1994-1.9037-1.9047-3.1836-1.9941zm47.938 0c-1.2799.08947-2.4911.7947-3.1836 1.9941-1.108 1.9191-.45622 4.3568 1.4629 5.4648l10.393 6c1.9191 1.108 4.3568.45427 5.4648-1.4648s.45427-4.3568-1.4648-5.4648l-10.393-6c-.71967-.4155-1.5114-.58298-2.2793-.5293zm-23.969 13.994c-2.216 0-4 1.784-4 4v12c0 2.216 1.784 4 4 4s4-1.784 4-4v-12c0-2.216-1.784-4-4-4z" fill="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.1082"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M52 4c-6.579 0-12 5.421-12 12v26.625c-12.263 7.282-19.978 19.75-20 33.369L19.994 80h28.578C50.372 86.863 56.6 92 64 92s13.628-5.137 15.428-12h28.576L108 75.996c-.015-13.625-7.732-26.099-20-33.385V16c0-6.579-5.42-12-12-12zM40.311 82.016a8.033 8.033 0 0 0-4.559 1.055l-10.393 6c-3.778 2.181-5.111 7.15-2.93 10.93 2.182 3.778 7.151 5.111 10.93 2.93l10.394-6c3.78-2.183 5.108-7.153 2.927-10.93a8.033 8.033 0 0 0-6.369-3.985zm47.379 0A8.032 8.032 0 0 0 81.32 86c-2.18 3.778-.851 8.748 2.929 10.93l10.393 6c3.779 2.182 8.748.85 10.93-2.93 2.182-3.779.849-8.747-2.93-10.93l-10.393-6a8.033 8.033 0 0 0-4.559-1.054zM64.001 96c-4.363 0-8 3.637-8 8v12c0 4.363 3.637 8 8 8s8-3.637 8-8v-12c0-4.363-3.637-8-8-8z" fill-opacity=".294"/><path d="M52 8c-4.432 0-8 3.568-8 8v28.875A40 36 0 0 0 24 76h28a12 12 0 0 0 12 12 12 12 0 0 0 12-12h28a40 36 0 0 0-20-31.141V16c0-4.432-3.568-8-8-8zM40.031 86.006a3.987 3.987 0 0 0-2.28.53l-10.392 6c-1.92 1.107-2.573 3.545-1.465 5.464s3.546 2.573 5.465 1.465l10.393-6A3.992 3.992 0 0 0 43.215 88a3.99 3.99 0 0 0-3.184-1.994zm47.938 0A3.99 3.99 0 0 0 84.785 88a3.992 3.992 0 0 0 1.463 5.465l10.393 6c1.92 1.108 4.357.454 5.465-1.465s.454-4.357-1.465-5.465l-10.393-6a3.987 3.987 0 0 0-2.279-.529zM64 100c-2.216 0-4 1.784-4 4v12c0 2.216 1.784 4 4 4s4-1.784 4-4v-12c0-2.216-1.784-4-4-4z" fill="#fff"/></svg>
diff --git a/editor/icons/GizmoVoxelGI.svg b/editor/icons/GizmoVoxelGI.svg
index ff3cafa1f5..92e84bc67e 100644
--- a/editor/icons/GizmoVoxelGI.svg
+++ b/editor/icons/GizmoVoxelGI.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m12 4c-4.4183.0000095-8 3.5817-8 8v104c.0000095 4.4183 3.5817 8 8 8h64v-16h-56v-88h88v7.7676a36 36 0 0 0 -16-3.7676 36 36 0 0 0 -36 36 36 36 0 0 0 16 29.9v8.0996c0 4.8544 3.4253 8.8788 8 9.8008v16.199h24v-16.199c4.5747-.92197 8-4.9464 8-9.8008v-8.0879a36 36 0 0 0 16-29.912 36 36 0 0 0 -19.523-32h15.523v-16c-.00001-4.4183-3.5817-8-8-8h-104zm28.25 17.996c-2.8358-.076599-5.6171 1.3651-7.1406 4.0039-2.216 3.8382-.90854 8.7117 2.9297 10.928l10.393 6c3.8382 2.216 8.7117.91049 10.928-2.9277s.91049-8.7117-2.9277-10.928l-10.393-6c-1.1994-.6925-2.5-1.0414-3.7891-1.0762zm51.75 22.004a16 16 0 0 1 16 16 16 16 0 0 1 -16 16 16 16 0 0 1 -16-16 16 16 0 0 1 16-16zm-60 8c-4.432 0-8 3.568-8 8s3.568 8 8 8h12c4.432 0 8-3.568 8-8s-3.568-8-8-8zm18.221 23.996c-1.289.034818-2.5896.38367-3.7891 1.0762l-10.393 6c-3.8382 2.216-5.1457 7.0895-2.9297 10.928s7.0915 5.1437 10.93 2.9277l10.393-6c3.8382-2.216 5.1437-7.0895 2.9277-10.928-1.5235-2.6388-4.3028-4.0805-7.1387-4.0039z" fill-opacity=".29412"/><path d="m12 8a4.0004 4.0004 0 0 0 -4 4v104a4.0004 4.0004 0 0 0 4 4h60v-8h-56v-96h96v8h8v-12a4.0004 4.0004 0 0 0 -4-4zm27.715 17.951c-1.2324.08615-2.3996.76492-3.0664 1.9199l-.14844.25781c-1.0669 1.848-.43784 4.1948 1.4102 5.2617l10.648 6.1484c1.848 1.0669 4.1948.43784 5.2617-1.4102l.14844-.25781c1.0669-1.848.43784-4.1948-1.4102-5.2617l-10.648-6.1484c-.693-.4001-1.4558-.56146-2.1953-.50977zm52.285 2.0488a32 32 0 0 0 -32 32 32 32 0 0 0 16 27.668v8.332c0 4.432 3.568 8 8 8h16c4.432 0 8-3.568 8-8v-8.3223a32 32 0 0 0 16-27.678 32 32 0 0 0 -32-32zm0 12a20 20 0 0 1 20 20 20 20 0 0 1 -20 20 20 20 0 0 1 -20-20 20 20 0 0 1 20-20zm-60.148 16c-2.1339 0-3.8516 1.7177-3.8516 3.8516v.29688c0 2.1339 1.7177 3.8516 3.8516 3.8516h12.297c2.1339 0 3.8516-1.7177 3.8516-3.8516v-.29688c0-2.1339-1.7177-3.8516-3.8516-3.8516zm18.902 23.951c-.73947-.05169-1.5023.10966-2.1953.50977l-10.648 6.1484c-1.848 1.0669-2.4771 3.4137-1.4102 5.2617l.14844.25781c1.0669 1.848 3.4137 2.4771 5.2617 1.4102l10.648-6.1484c1.848-1.0669 2.4771-3.4137 1.4102-5.2617l-.14844-.25781c-.66684-1.155-1.834-1.8338-3.0664-1.9199zm33.246 32.049v8h16v-8z" fill="#f7f5cf"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M12 4a8 8 0 0 0-8 8v104a8 8 0 0 0 8 8h64v-16H20V20h88v7.768A36 36 0 0 0 92 24a36 36 0 0 0-36 36 36 36 0 0 0 16 29.9V98a9.977 9.977 0 0 0 8 9.8V124h24v-16.2a9.977 9.977 0 0 0 8-9.8v-8.088A36 36 0 0 0 128 60a36 36 0 0 0-19.523-32H124V12a8 8 0 0 0-8-8H12zm28.25 17.996A7.984 7.984 0 0 0 33.11 26a7.983 7.983 0 0 0 2.93 10.928l10.392 6c3.838 2.216 8.712.91 10.928-2.928s.91-8.712-2.928-10.928l-10.393-6a7.99 7.99 0 0 0-3.789-1.076zM92 44a16 16 0 0 1 16 16 16 16 0 0 1-16 16 16 16 0 0 1-16-16 16 16 0 0 1 16-16zm-60 8c-4.432 0-8 3.568-8 8s3.568 8 8 8h12c4.432 0 8-3.568 8-8s-3.568-8-8-8zm18.221 23.996a7.991 7.991 0 0 0-3.79 1.076l-10.392 6c-3.838 2.216-5.146 7.09-2.93 10.928s7.092 5.144 10.93 2.928l10.393-6A7.982 7.982 0 0 0 57.36 80a7.98 7.98 0 0 0-7.139-4.004z" fill-opacity=".294"/><path d="M12 8a4 4 0 0 0-4 4v104a4 4 0 0 0 4 4h60v-8H16V16h96v8h8V12a4 4 0 0 0-4-4zm27.715 17.951a3.843 3.843 0 0 0-3.066 1.92l-.149.258a3.844 3.844 0 0 0 1.41 5.261l10.648 6.149a3.844 3.844 0 0 0 5.262-1.41l.149-.258a3.844 3.844 0 0 0-1.41-5.262L41.91 26.461a3.84 3.84 0 0 0-2.195-.51zM92 28a32 32 0 0 0-32 32 32 32 0 0 0 16 27.668V96c0 4.432 3.568 8 8 8h16c4.432 0 8-3.568 8-8v-8.323A32 32 0 0 0 124 60a32 32 0 0 0-32-32zm0 12a20 20 0 0 1 20 20 20 20 0 0 1-20 20 20 20 0 0 1-20-20 20 20 0 0 1 20-20zM31.852 56A3.843 3.843 0 0 0 28 59.85v.297A3.843 3.843 0 0 0 31.852 64h12.297a3.843 3.843 0 0 0 3.852-3.852v-.297A3.843 3.843 0 0 0 44.149 56zm18.902 23.95a3.84 3.84 0 0 0-2.195.51L37.91 86.61a3.844 3.844 0 0 0-1.41 5.262l.148.257a3.844 3.844 0 0 0 5.262 1.41l10.648-6.148a3.844 3.844 0 0 0 1.41-5.261l-.149-.258a3.842 3.842 0 0 0-3.066-1.92zM84 112v8h16v-8z" fill="#f7f5cf"/></svg>
diff --git a/editor/icons/Gradient.svg b/editor/icons/Gradient.svg
index 99d3a871a6..0dff9daa72 100644
--- a/editor/icons/Gradient.svg
+++ b/editor/icons/Gradient.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3 1c-1.1046 0-2 .8954299-2 1.9999999v10.0000001c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10.0000001c0-1.1046-.89543-1.9999999-2-1.9999999zm0 1.9999999h10v10.0000001h-10z"/><path d="m7.5 5.500001h1v1h-1z" stroke-width=".787342"/><path d="m3.5 3.5v9h3v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1z" stroke-width="4.09116"/><g stroke-width=".787342"><path d="m7.5 3.5h1v1h-1z"/><path d="m7.5 9.500001h1v1h-1z"/><path d="m7.5 7.500001h1v1h-1z"/><path d="m7.5 11.5h1v1h-1z"/><path d="m8.5 4.500001h1v1h-1z"/><path d="m8.5 6.500001h1v1h-1z"/><path d="m8.5 8.500002h1v1h-1z"/><path d="m8.5 10.500002h1v1h-1z"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h10v10H3zm4.5 2.5h1v1h-1zm-4-2v9h3v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1zm4 0h1v1h-1zm0 6h1v1h-1zm0-2h1v1h-1zm0 4h1v1h-1zm1-7h1v1h-1zm0 2h1v1h-1zm0 2h1v1h-1zm0 2h1v1h-1z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/GraphNode.svg b/editor/icons/GraphNode.svg
index b56fe6b609..31316ea32c 100644
--- a/editor/icons/GraphNode.svg
+++ b/editor/icons/GraphNode.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0 -2.5-2.5z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-1 3.73v6.541a2 2 0 1 0 2 0V5.414L8.086 9.5 9.5 8.086 5.414 4h5.857a2 2 0 1 0 0-2H4.729A2 2 0 0 0 3 1zm9.5 9a2.5 2.5 0 0 0 0 5 2.5 2.5 0 0 0 0-5z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GuiHsplitter.svg b/editor/icons/GuiHsplitter.svg
index 6d4505685e..c4ee70fa2f 100644
--- a/editor/icons/GuiHsplitter.svg
+++ b/editor/icons/GuiHsplitter.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 8 64" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 990.36v60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2" transform="translate(0 -988.36)"/></svg>
+<svg height="64" viewBox="0 0 8 64" width="8" xmlns="http://www.w3.org/2000/svg"><path d="M4 2v60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".392" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiProgressBar.svg b/editor/icons/GuiProgressBar.svg
index b1ce44c645..68af5d2e09 100644
--- a/editor/icons/GuiProgressBar.svg
+++ b/editor/icons/GuiProgressBar.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1036.4c-1.0907-.0002-2 .9073-2 1.998v12.002c0 1.0907.9093 2 2 2h12c1.0907 0 2-.9093 2-2v-12c0-1.0907-.9093-1.9978-2-1.998zm0 2h12v11.998h-12z" fill="#e0e0e0" fill-opacity=".39216" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 2h12v12H2z" fill="#e0e0e0" fill-opacity=".392"/></svg>
diff --git a/editor/icons/GuiProgressFill.svg b/editor/icons/GuiProgressFill.svg
index f8070cadc4..8e1d2dbf0d 100644
--- a/editor/icons/GuiProgressFill.svg
+++ b/editor/icons/GuiProgressFill.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" fill-opacity=".39216" height="8" ry=".99999" width="8" x="4" y="4"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" fill-opacity=".392" height="8" ry="1" width="8" x="4" y="4"/></svg>
diff --git a/editor/icons/GuiScrollGrabber.svg b/editor/icons/GuiScrollGrabber.svg
index a8a0cf08c2..54888dcee5 100644
--- a/editor/icons/GuiScrollGrabber.svg
+++ b/editor/icons/GuiScrollGrabber.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".29" r="3"/></svg>
+<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".29" r="3"/></svg>
diff --git a/editor/icons/GuiScrollGrabberHl.svg b/editor/icons/GuiScrollGrabberHl.svg
index 0388063d25..8ec0790ed1 100644
--- a/editor/icons/GuiScrollGrabberHl.svg
+++ b/editor/icons/GuiScrollGrabberHl.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#f9f9f9" fill-opacity=".73" r="3"/></svg>
+<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#f9f9f9" fill-opacity=".73" r="3"/></svg>
diff --git a/editor/icons/GuiScrollGrabberPressed.svg b/editor/icons/GuiScrollGrabberPressed.svg
index 202b9c9412..babc8c30c1 100644
--- a/editor/icons/GuiScrollGrabberPressed.svg
+++ b/editor/icons/GuiScrollGrabberPressed.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#b3b3b3" fill-opacity=".72941" r="3"/></svg>
+<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#b3b3b3" fill-opacity=".72941" r="3"/></svg>
diff --git a/editor/icons/GuiSpace.svg b/editor/icons/GuiSpace.svg
index db4b1745e2..73c9aa00e3 100644
--- a/editor/icons/GuiSpace.svg
+++ b/editor/icons/GuiSpace.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 7.9999993" width="8" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="1046.4" fill="#fff" fill-opacity=".196078" r="3" transform="matrix(.5 0 0 -.5 1 527.20001)"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="4" fill="#fff" fill-opacity=".196078" r="1.5"/></svg>
diff --git a/editor/icons/GuiTab.svg b/editor/icons/GuiTab.svg
index b6ba1bb3dd..6ab1c95740 100644
--- a/editor/icons/GuiTab.svg
+++ b/editor/icons/GuiTab.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v8h2v-8zm-5.0137.0019531a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l3-3a1.0001 1.0001 0 0 0 0-1.4141l-3-3a1 1 0 0 0 -.7207-.29102z" fill="#fff" fill-opacity=".19608"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="M6 0v8h2V0zM1 0a1 1 0 0 0-.693 1.705L2.6 3.998.307 6.291A1 1 0 0 0 1.72 7.705l3-3a1 1 0 0 0 0-1.414l-3-3A1 1 0 0 0 1 0z" fill="#fff" fill-opacity=".19608"/></svg>
diff --git a/editor/icons/GuiViewportHdiagsplitter.svg b/editor/icons/GuiViewportHdiagsplitter.svg
index ceba2c9cfb..c7fc99070d 100644
--- a/editor/icons/GuiViewportHdiagsplitter.svg
+++ b/editor/icons/GuiViewportHdiagsplitter.svg
@@ -1 +1 @@
-<svg height="34" viewBox="0 0 64 34" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m4.0307 1048.4h29.969m-30 30v-60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2" transform="matrix(0 1 -1 0 1080.4 -2)"/></svg>
+<svg height="34" viewBox="0 0 64 34" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M32 2V32M2 2h60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".392" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiViewportVdiagsplitter.svg b/editor/icons/GuiViewportVdiagsplitter.svg
index af52e1ec62..03b9ecc8f4 100644
--- a/editor/icons/GuiViewportVdiagsplitter.svg
+++ b/editor/icons/GuiViewportVdiagsplitter.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 34 64" width="34" xmlns="http://www.w3.org/2000/svg"><path d="m4.0307 1048.4h29.969m-30 30v-60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2" transform="matrix(-1 0 0 -1 36.008 1080.4)"/></svg>
+<svg height="64" viewBox="0 0 34 64" width="34" xmlns="http://www.w3.org/2000/svg"><path d="M32 32H2m30-30v60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".392" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiViewportVhsplitter.svg b/editor/icons/GuiViewportVhsplitter.svg
index b53a23f62a..e1bd123c18 100644
--- a/editor/icons/GuiViewportVhsplitter.svg
+++ b/editor/icons/GuiViewportVhsplitter.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m-26 1048.4h60m-30 30v-60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2" transform="matrix(0 1 -1 0 1080.4 28)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M32 2v60M2 32h60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".392" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiVsplitter.svg b/editor/icons/GuiVsplitter.svg
index add4301a4b..bd0a53a456 100644
--- a/editor/icons/GuiVsplitter.svg
+++ b/editor/icons/GuiVsplitter.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 64 8" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m2 1048.4h60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".39216" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 64 8" width="64" xmlns="http://www.w3.org/2000/svg"><path d="M2 4h60" fill="none" stroke="#fff" stroke-linecap="round" stroke-opacity=".392" stroke-width="2"/></svg>
diff --git a/editor/icons/HBoxContainer.svg b/editor/icons/HBoxContainer.svg
index 8fbeef525c..30e06d8849 100644
--- a/editor/icons/HBoxContainer.svg
+++ b/editor/icons/HBoxContainer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h2v10h-2zm4 0h2v10h-2zm4 0h2v10h-2z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h2v10H3zm4 0h2v10H7zm4 0h2v10h-2z" fill="#8eef97"/></svg>
diff --git a/editor/icons/HeightMapShape3D.svg b/editor/icons/HeightMapShape3D.svg
index e1b3af88e5..205443b52b 100644
--- a/editor/icons/HeightMapShape3D.svg
+++ b/editor/icons/HeightMapShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="8" y2="11"><stop offset="0" stop-color="#5fb2ff"/><stop offset="1" stop-color="#a2d2ff"/></linearGradient><g transform="translate(0 -1)"><path d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd" transform="translate(0 -1033.4)"/><path d="m3 11c1-1 2-2 2-4s1-3 3-3 3 1 3 3 1 3 2 4z" fill="url(#a)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="7" y2="10"><stop offset="0" stop-color="#5fb2ff"/><stop offset="1" stop-color="#a2d2ff"/></linearGradient><path d="m1 10 7 3 7-3-7-3z" fill="#a2d2ff"/><path d="M3 10c1-1 2-2 2-4s1-3 3-3 3 1 3 3 1 3 2 4z" fill="url(#a)"/></svg>
diff --git a/editor/icons/History.svg b/editor/icons/History.svg
index cb1bb4178f..0d2ec493b1 100644
--- a/editor/icons/History.svg
+++ b/editor/icons/History.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/><path d="m8 1041.4h2v4h-2z"/><path d="m8 1043.4h4v2h-4z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 8a4 4 0 1 1 4 4v2a6 6 0 1 0-6-6H1l3 4 3-4zm3-3h2v2h2v2H8z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/ImmediateMesh.svg b/editor/icons/ImmediateMesh.svg
index f94ef8c323..ceedc008ec 100644
--- a/editor/icons/ImmediateMesh.svg
+++ b/editor/icons/ImmediateMesh.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v2h5v-2zm5 2v3h2v-3zm2-2v2h5v-2zm-2 7v3h2v-3zm-5 3v2h5v-2zm7 0v2h5v-2z" fill="#ffca5f" fill-rule="nonzero"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 2v2h5V2zm5 2v3h2V4zm2-2v2h5V2zM7 9v3h2V9zm-5 3v2h5v-2zm7 0v2h5v-2z" fill="#ffca5f"/></svg>
diff --git a/editor/icons/ImportFail.svg b/editor/icons/ImportFail.svg
index 582b244614..ed73096f6e 100644
--- a/editor/icons/ImportFail.svg
+++ b/editor/icons/ImportFail.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141-1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -.72656-1.7148 1.0001 1.0001 0 0 0 -.6875.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -.7168-.30273z" fill="#ff5f5f" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.99 1.99a1 1 0 0 0-.697 1.717L6.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414L8 9.414l4.293 4.293a1 1 0 1 0 1.414-1.414L9.414 8l4.293-4.293a1 1 0 0 0-1.414-1.414L8 6.586 3.707 2.293a1 1 0 0 0-.717-.303z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/InputEventAction.svg b/editor/icons/InputEventAction.svg
new file mode 100644
index 0000000000..9c8c2f0487
--- /dev/null
+++ b/editor/icons/InputEventAction.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.55 5a.85.85 0 0 0-.85.85v7.65a.85.85 0 0 0 .85.85h6.8a.85.85 0 0 0 .85-.85V5.85a.85.85 0 0 0-.85-.85zM8.5 6.2l.282 1.129a2.5 2.5 90 0 0 .345.14l.994-.597.707.707-.598.997a2.5 2.5 90 0 0 .143.342L11.5 9.2v1l-1.129.282a2.5 2.5 90 0 0-.14.344l.597.995-.707.707-.997-.598a2.5 2.5 90 0 0-.343.143l-.28 1.127h-1l-.283-1.13a2.5 2.5 90 0 0-.344-.139l-.995.597-.707-.707.598-.997a2.5 2.5 90 0 0-.143-.343L4.5 10.2v-1l1.13-.282a2.5 2.5 90 0 0 .139-.344l-.597-.995.707-.707.997.598a2.5 2.5 90 0 0 .343-.143L7.5 6.2z" fill="#69c4d4"/><circle cx="8" cy="9.675" r="1" fill="#69c4d4"/><path d="M2 6.36v7.65a1.7 1.7 0 0 0 1.7 1.7h8.5a1.7 1.7 0 0 0 1.7-1.7V6.36h-.85v7.65a.85.85 0 0 1-.85.85H3.7a.85.85 0 0 1-.85-.85V6.36z" fill="#e0e0e0"/><path d="m10.5 3.6.75-1.5M5.5 3.6l-.75-1.5M8 3.2V1.5" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4" fill="none"/></svg>
diff --git a/editor/icons/InputEventJoypadButton.svg b/editor/icons/InputEventJoypadButton.svg
new file mode 100644
index 0000000000..4540d4462f
--- /dev/null
+++ b/editor/icons/InputEventJoypadButton.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5.25 3h2.3A1.15 1.15 90 0 1 8.7 4.15v9.2a1.15 1.15 90 0 1-1.15 1.15h-2.3a1.15 1.15 90 0 1-1.15-1.15v-2.3H1.8A1.15 1.15 90 0 1 .65 9.9V7.6A1.15 1.15 90 0 1 1.8 6.45h2.3v-2.3A1.15 1.15 90 0 1 5.25 3zM6.4 7.025a1.15 1.15 90 0 0 0 3.45 1.15 1.15 90 0 0 0-3.45Z" fill="#e0e0e0"/><path d="M8.7 6.3H11a1.15 1.15 90 0 1 1.15 1.15v2.3A1.15 1.15 90 0 1 11 10.9H8.7" fill="#69c4d4"/><path d="m13.25 7.25 1.7-.4m-2.2-1.35 1.3-1.3M11 5l.4-1.7" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventJoypadMotion.svg b/editor/icons/InputEventJoypadMotion.svg
new file mode 100644
index 0000000000..d1e4544335
--- /dev/null
+++ b/editor/icons/InputEventJoypadMotion.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="2" x2="9"><stop offset="0" stop-color="#69c4d4" stop-opacity="0"/><stop offset=".6" stop-color="#69c4d4"/></linearGradient><path d="M11.5 16v-1.5a1 1 0 0 0-1-1H10l1.6-4a4 4 0 1 0-3.5-1.4l-2.2 5.4h-.7a1 1 0 0 0-1 1V16z" fill="#e0e0e0"/><path d="M5.25 12.2 2 4a8 8 0 0 1 7-3 5 5 0 0 0-2.1 7.2z" fill="url(#a)"/></svg>
diff --git a/editor/icons/InputEventKey.svg b/editor/icons/InputEventKey.svg
new file mode 100644
index 0000000000..4c5b0c01c9
--- /dev/null
+++ b/editor/icons/InputEventKey.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.55 5a.85.85 0 0 0-.85.85v7.65a.85.85 0 0 0 .85.85h6.8a.85.85 0 0 0 .85-.85V5.85a.85.85 0 0 0-.85-.85zm.65 1.503h1.75v2.2l2-2.2h2.1L8.166 9.675l2.884 3.172h-2.1l-2-2.2v2.2H5.2z" fill="#69c4d4"/><path d="M2 6.36v7.65a1.7 1.7 0 0 0 1.7 1.7h8.5a1.7 1.7 0 0 0 1.7-1.7V6.36h-.85v7.65a.85.85 0 0 1-.85.85H3.7a.85.85 0 0 1-.85-.85V6.36z" fill="#e0e0e0"/><path d="m10.5 3.6.75-1.5M5.5 3.6l-.75-1.5M8 3.2V1.5" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4" fill="none"/></svg>
diff --git a/editor/icons/InputEventMIDI.svg b/editor/icons/InputEventMIDI.svg
new file mode 100644
index 0000000000..269ce60bc6
--- /dev/null
+++ b/editor/icons/InputEventMIDI.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M.5 15.5h15v-9a2 2 0 0 0-2-2h-11a2 2 0 0 0-2 2zm1-1v-8h2v4H4v4zm3.5 0v-4h.5v-4H7v4h.5v4zm7 0v-4h.5v-4h2v8z" fill="#e0e0e0"/><path d="M4.5 4.127a2 2 0 0 0-2-2 2 2 0 0 1-2-2" stroke-linecap="square" stroke="#e0e0e0" fill="none"/><path d="M8.5 14.5v-4H9v-4h1.5v4h.5v4z" fill="#69c4d4"/><path d="m11.75 3.3.75-1.5M7.75 3.3 7 1.8m2.75 1.1V1.2" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventMagnifyGesture.svg b/editor/icons/InputEventMagnifyGesture.svg
new file mode 100644
index 0000000000..dbf434c2a6
--- /dev/null
+++ b/editor/icons/InputEventMagnifyGesture.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M1 3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1zm1 0v8h12V3zm0 9v1h5.5v-1zm6.5 0v1H14v-1z" fill="#e0e0e0"/><path d="M6.4 3.8a1.7 1.7 0 1 1 3.2 0C8.1 7 8.1 7 9.6 10.2a1.7 1.7 0 1 1-3.2 0C7.9 7 7.9 7 6.4 3.8z" transform="rotate(66 8 7)" fill="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventMouseButton.svg b/editor/icons/InputEventMouseButton.svg
new file mode 100644
index 0000000000..1981749489
--- /dev/null
+++ b/editor/icons/InputEventMouseButton.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 8.5v2.75a4 4 0 0 0 8 0V8.5zm3-1V4a4 4 0 0 0-3 3.5Z" fill="#e0e0e0"/><path d="M7.5 4.127a2 2 0 0 0-2-2H4a2 2 0 0 1-2-2" stroke-linecap="round" stroke="#e0e0e0" fill="none"/><path d="M11.5 7.5a4 4 0 0 0-3-3.5v3.5z" fill="#69c4d4"/><path d="m12.2 5.5 1.6-.8m-2.5-.75 1.3-1.3m-2.85.4.8-1.6" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventMouseMotion.svg b/editor/icons/InputEventMouseMotion.svg
new file mode 100644
index 0000000000..9a8a17fb89
--- /dev/null
+++ b/editor/icons/InputEventMouseMotion.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0.5" x2="6"><stop offset="0" stop-color="#69c4d4" stop-opacity="0"/><stop offset=".6" stop-color="#69c4d4"/></linearGradient><path d="M6 8v3a4 4 0 0 0 8 0V8a4 4 0 0 0-3-3.873V7.5a1 1 0 0 1-2 0V4.127A4 4 0 0 0 6 8" fill="#e0e0e0"/><path d="M10 4.127a2 2 0 0 0-2-2H7a2 2 0 0 1-2-2" stroke-linecap="round" stroke="#e0e0e0" fill="none"/><path d="M5 6a4 4 0 0 0-.4 1.5v4a4 4 0 0 0 1.2 2.8l-4 .8q-1.3.26-1.3-2V8q0-1.1 1.3-1.36Z" fill="url(#a)"/></svg>
diff --git a/editor/icons/InputEventPanGesture.svg b/editor/icons/InputEventPanGesture.svg
new file mode 100644
index 0000000000..b093b3ed83
--- /dev/null
+++ b/editor/icons/InputEventPanGesture.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M1 3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1zm1 0v8h12V3zm0 9v1h5.5v-1zm6.5 0v1H14v-1z" fill="#e0e0e0"/><path d="M11.25 4a1.3 1.3 0 1 1 0 2.5 31 31 0 0 0-7.75-.85.4.4 0 1 1 0-.8A31 31 0 0 0 11.25 4zm0 3.5a1.3 1.3 0 1 1 0 2.5 31 31 0 0 0-7.75-.85.4.4 0 1 1 0-.8 31 31 0 0 0 7.75-.85z" fill="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventScreenDrag.svg b/editor/icons/InputEventScreenDrag.svg
new file mode 100644
index 0000000000..949eb3b67b
--- /dev/null
+++ b/editor/icons/InputEventScreenDrag.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zm1 0v10.75h8V2M8 13.125a.625.625 0 0 0 0 1.5.625.625 0 0 0 0-1.5z" fill="#e0e0e0"/><path d="M6 4.1a1.8 1.8 0 1 1 3.3.9 6 6 0 0 0 .3 6.4.6.6 0 1 1-1.2.6A15 15 0 0 1 6 4.1z" transform="rotate(40 8 6.76)" fill="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventScreenTouch.svg b/editor/icons/InputEventScreenTouch.svg
new file mode 100644
index 0000000000..9226818f7c
--- /dev/null
+++ b/editor/icons/InputEventScreenTouch.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zm1 0v10.75h8V2M8 13.125a.625.625 0 0 0 0 1.5.625.625 0 0 0 0-1.5z" fill="#e0e0e0"/><circle cx="8" cy="6.5" r="1.25" fill="#69c4d4"/><circle cx="8" cy="6.5" r="2.25" fill="none" stroke-width=".75" stroke="#69c4d4"/></svg>
diff --git a/editor/icons/InputEventShortcut.svg b/editor/icons/InputEventShortcut.svg
new file mode 100644
index 0000000000..363e4b180a
--- /dev/null
+++ b/editor/icons/InputEventShortcut.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.55 5a.85.85 0 0 0-.85.85v7.65a.85.85 0 0 0 .85.85h6.8a.85.85 0 0 0 .85-.85V5.85a.85.85 0 0 0-.85-.85zM7 7h2.55L8.7 9.55h1.7L7 12.95l.85-2.55h-1.7z" fill="#69c4d4"/><path d="M2 6.36v7.65a1.7 1.7 0 0 0 1.7 1.7h8.5a1.7 1.7 0 0 0 1.7-1.7V6.36h-.85v7.65a.85.85 0 0 1-.85.85H3.7a.85.85 0 0 1-.85-.85V6.36z" fill="#e0e0e0"/><path d="m10.5 3.6.75-1.5M5.5 3.6l-.75-1.5M8 3.2V1.5" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4" fill="none"/></svg>
diff --git a/editor/icons/InstanceOptions.svg b/editor/icons/InstanceOptions.svg
index c9ff474fee..6ea0536443 100644
--- a/editor/icons/InstanceOptions.svg
+++ b/editor/icons/InstanceOptions.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m1 7v6c0 1.1046.89543 2 2 2h12v-8zm4 2h6l-3 4z" transform="translate(0 1036.4)"/><path d="m.71129 1040.4.28871 1.9791 2.2438-.3273-.81826-1.9018-1.7143.25zm3.6933-.5387.81826 1.9018 1.9791-.2887-.81826-1.9018zm3.9581-.5775.81826 1.9018 1.9791-.2887-.81826-1.9018zm3.9581-.5774.81826 1.9018 1.7143-.25-.28871-1.9791-2.2438.3273z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 7v6a2 2 0 0 0 2 2h12V7zm4 2h6l-3 4zM.711 4 1 5.98l2.244-.328-.818-1.902L.711 4zm3.694-.539.818 1.902 1.979-.289-.818-1.901zm3.958-.577.818 1.902 1.98-.29-.82-1.9zm3.958-.578.818 1.902 1.714-.25-.288-1.979-2.244.327z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/InterpCubic.svg b/editor/icons/InterpCubic.svg
index b542986ea6..f2e43bd941 100644
--- a/editor/icons/InterpCubic.svg
+++ b/editor/icons/InterpCubic.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c5 0 3-4 6-4s1 4 6 4" fill="none" stroke="#5fb2ff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 6c5 0 3-4 6-4s1 4 6 4" fill="none" stroke="#5fb2ff" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/InterpCubicAngle.svg b/editor/icons/InterpCubicAngle.svg
index e302d556dc..428230f315 100644
--- a/editor/icons/InterpCubicAngle.svg
+++ b/editor/icons/InterpCubicAngle.svg
@@ -1 +1 @@
-<svg enable-background="new 0 0 16 8" height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#5fff95" stroke-linecap="round"><path d="m2 6c5 0 3-4 6-4s1 4 6 4" stroke-width="2"/><circle cx="14" cy="2" r="1.5" stroke-linejoin="round"/></g></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#5fff95" stroke-linecap="round"><path d="m2 6c5 0 3-4 6-4s1 4 6 4" stroke-width="2"/><circle cx="14" cy="2" r="1.5"/></g></svg>
diff --git a/editor/icons/InterpLinear.svg b/editor/icons/InterpLinear.svg
index 966ddfdc31..8974f545d4 100644
--- a/editor/icons/InterpLinear.svg
+++ b/editor/icons/InterpLinear.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 6-4 6 4" fill="none" stroke="#ffca5f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 6 6-4 6 4" fill="none" stroke="#ffca5f" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/InterpLinearAngle.svg b/editor/icons/InterpLinearAngle.svg
index af4e87a6cb..09609ef5f9 100644
--- a/editor/icons/InterpLinearAngle.svg
+++ b/editor/icons/InterpLinearAngle.svg
@@ -1 +1 @@
-<svg enable-background="new 0 0 16 8" height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#fd995f" stroke-linecap="round" stroke-linejoin="round"><path d="m2 6 6-4 6 4" stroke-width="2"/><circle cx="14" cy="2" r="1.5"/></g></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#fd995f" stroke-linecap="round" stroke-linejoin="round"><path d="m2 6 6-4 6 4" stroke-width="2"/><circle cx="14" cy="2" r="1.5"/></g></svg>
diff --git a/editor/icons/InterpRaw.svg b/editor/icons/InterpRaw.svg
index 6344155c4b..1ec57d0aa9 100644
--- a/editor/icons/InterpRaw.svg
+++ b/editor/icons/InterpRaw.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4h3v-4h6v4h3" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 6h3V2h6v4h3" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/InterpWrapClamp.svg b/editor/icons/InterpWrapClamp.svg
index b589542019..9fab4fc249 100644
--- a/editor/icons/InterpWrapClamp.svg
+++ b/editor/icons/InterpWrapClamp.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v6h2v-2.9863-3.0137zm2 3.0137a1.0001 1.0001 0 0 0 .29297.69336l2 2a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-.29297-.29297h3.1719l-.29297.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 .29297-.72266 1.0001 1.0001 0 0 0 -.29297-.69141l-2-2a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l.29297.29297h-3.1719l.29297-.29297a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-2 2a1.0001 1.0001 0 0 0 -.29297.7207zm10-.029297v3.0156h2v-6h-2z" fill="#fc7f7f"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 1v6h2V1zm2 3.014a1 1 0 0 0 .293.693l2 2a1 1 0 0 0 1.414-1.414L6.414 5h3.172l-.293.293a1 1 0 0 0 1.414 1.414l2-2a1 1 0 0 0 0-1.414l-2-2a1 1 0 0 0-1.414 1.414L9.586 3H6.414l.293-.293a1 1 0 0 0-1.414-1.414l-2 2a1 1 0 0 0-.293.72zm10-3v6h2v-6h-2z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/InterpWrapLoop.svg b/editor/icons/InterpWrapLoop.svg
index 4faf7805f8..672a3cd39b 100644
--- a/editor/icons/InterpWrapLoop.svg
+++ b/editor/icons/InterpWrapLoop.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 0-3 2 3 2v-1h3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1v2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3h-3zm-5 1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h3v1l3-2-3-2v1h-3a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#c38ef1"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9 0 6 2l3 2V3h3a1 1 0 0 1 0 2v2a3 3 0 0 0 0-6H9zM4 1a3 3 0 0 0 0 6h3v1l3-2-3-2v1H4a1 1 0 0 1 0-2z" fill="#c38ef1"/></svg>
diff --git a/editor/icons/JoyAxis.svg b/editor/icons/JoyAxis.svg
index 11c694aede..c36aacb869 100644
--- a/editor/icons/JoyAxis.svg
+++ b/editor/icons/JoyAxis.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff"/><g fill="#e0e0e0"><path d="m3 1a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h12v-14zm4 2h2a1 1 0 0 1 1 1v2h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1-1v-2h-2a1 1 0 0 1 -1-1v-2a1 1 0 0 1 1-1h2v-2a1 1 0 0 1 1-1z" transform="translate(0 1036.4)"/><circle cx="8" cy="1044.4" r="1"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12V1zm4 2h2a1 1 0 0 1 1 1v2h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2v2a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1v-2H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h2V4a1 1 0 0 1 1-1z"/><circle cx="8" cy="8" r="1.5"/></g></svg>
diff --git a/editor/icons/JoyButton.svg b/editor/icons/JoyButton.svg
index d3d6e22929..d7eafadee4 100644
--- a/editor/icons/JoyButton.svg
+++ b/editor/icons/JoyButton.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff"/><path d="m1 1v14h12c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm7 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 1v14h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm7 1a2 2 0 0 1 0 4 2 2 0 0 1 0-4zM4 6a2 2 0 0 1 0 4 2 2 0 0 1 0-4zm8 0a2 2 0 0 1 0 4 2 2 0 0 1 0-4zm-4 4a2 2 0 0 1 0 4 2 2 0 0 1 0-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Joypad.svg b/editor/icons/Joypad.svg
index ead745379b..1ac10605b5 100644
--- a/editor/icons/Joypad.svg
+++ b/editor/icons/Joypad.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 3c-.55226.0000552-.99994.44774-1 1v8c.0000552.55226.44774.99994 1 1h14c.55226-.000055.99994-.44774 1-1v-8c-.000055-.55226-.44774-.99994-1-1zm2 2h2v2h2v2h-2v2h-2v-2h-2v-2h2zm10.5 0a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5zm-3 3a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5z" fill="#e0e0e0" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm2 2h2v2h2v2H5v2H3V9H1V7h2zm10.5 0a1.5 1.5 0 0 1 0 3 1.5 1.5 0 0 1 0-3zm-3 3a1.5 1.5 0 0 1 0 3 1.5 1.5 0 0 1 0-3z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/KeyAnimation.svg b/editor/icons/KeyAnimation.svg
index 24a1e84da2..ac59a5215a 100644
--- a/editor/icons/KeyAnimation.svg
+++ b/editor/icons/KeyAnimation.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#a448f0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#a448f0" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyAudio.svg b/editor/icons/KeyAudio.svg
index 18caa7afe2..cf69940904 100644
--- a/editor/icons/KeyAudio.svg
+++ b/editor/icons/KeyAudio.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae440" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae440" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyBezierHandle.svg b/editor/icons/KeyBezierHandle.svg
index a2b58118e3..e2c95d720f 100644
--- a/editor/icons/KeyBezierHandle.svg
+++ b/editor/icons/KeyBezierHandle.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m3.9960938-.03710938c-.1950007 0-.3896403.07518711-.5390626.22460938l-3.23632808 3.2363281c-.29883746.2988375-.29884453.7812336 0 1.0800781l3.23632808 3.2363282c.2988375.2988374.7812407.2988374 1.0800782 0l3.2363281-3.2363282c.2988445-.2988445.2988375-.7812406 0-1.0800781l-3.2363281-3.2363281c-.1494223-.14942227-.346015-.22460938-.5410156-.22460938zm.0292968.8515625c.1516192 0 .3037416.05796444.4199219.17382813l2.515625 2.50781255c.2323605.2317273.2323605.6061632 0 .8378906l-2.515625 2.5097656c-.2323605.2317274-.6074832.2317274-.8398437 0l-2.515625-2.5097656c-.23236057-.2317274-.23236057-.6061633 0-.8378906l2.515625-2.50781255c.1161802-.11586369.2683026-.17382813.4199218-.17382813z" fill="#e0e0e0"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="M7.762 3.434a.8.8 45 0 1 0 1.132L4.566 7.762a.8.8 45 0 1-1.132 0L.238 4.566a.8.8 45 0 1 0-1.132L3.434.238a.8.8 45 0 1 1.132 0zM4.354.974a.5.5 45 0 0-.708 0L.974 3.646a.5.5 45 0 0 0 .708l2.672 2.672a.5.5 45 0 0 .708 0l2.672-2.672a.5.5 45 0 0 0-.708z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/KeyBezierPoint.svg b/editor/icons/KeyBezierPoint.svg
index 266da4c200..fa926c26fa 100644
--- a/editor/icons/KeyBezierPoint.svg
+++ b/editor/icons/KeyBezierPoint.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1044.4)" width="6.1027" x="-741.53" y="741.08"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="4.96" width="4.96" x="1.52" y="1.52" rx=".6" transform="rotate(45 4 4)"/></svg>
diff --git a/editor/icons/KeyBezierSelected.svg b/editor/icons/KeyBezierSelected.svg
index 741f9bea60..e26888d1d3 100644
--- a/editor/icons/KeyBezierSelected.svg
+++ b/editor/icons/KeyBezierSelected.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1044.4)" width="6.1027" x="-741.53" y="741.08"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="4.96" width="4.96" x="1.52" y="1.52" ry=".6" transform="rotate(45 4 4)"/></svg>
diff --git a/editor/icons/KeyBlendShape.svg b/editor/icons/KeyBlendShape.svg
index 11932bd847..e8d39e4fa0 100644
--- a/editor/icons/KeyBlendShape.svg
+++ b/editor/icons/KeyBlendShape.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5ad5c4" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5ad5c4" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyCall.svg b/editor/icons/KeyCall.svg
index 5ffbceeb09..8101b01201 100644
--- a/editor/icons/KeyCall.svg
+++ b/editor/icons/KeyCall.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#3cf34e" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#3cf34e" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyEasedSelected.svg b/editor/icons/KeyEasedSelected.svg
index c06d94c553..55ce51fdd0 100644
--- a/editor/icons/KeyEasedSelected.svg
+++ b/editor/icons/KeyEasedSelected.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="9.999999" rx=".948002" stroke-width="1.2427" width="9.999999" x=".000001" y=".000035"/><rect fill="#003e7a" height="5.628136" rx=".533549" stroke-width=".699406" transform="matrix(.99989481 .01450427 .01450427 .99989481 0 0)" width="5.628136" x="2.115027" y="2.114924"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="10" rx="1" width="10"/><rect fill="#003e7a" height="5.6" rx=".5" width="5.6" x="2.1" y="2.1"/></svg>
diff --git a/editor/icons/KeySelected.svg b/editor/icons/KeySelected.svg
index aff66b9a27..9315dc67b1 100644
--- a/editor/icons/KeySelected.svg
+++ b/editor/icons/KeySelected.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="6.1027" ry=".76286" transform="matrix(.87871827 -.87871827 .87871827 .87871827 .03288 -1297.7965)" width="6.1027" x="-741.53003" y="741.08002"/><rect fill="#003e7a" height="3.434683" ry=".429348" stroke-width=".562814" transform="matrix(.89137101 -.86588067 .89137101 .86588067 -.038545 -1297.8361)" width="3.434683" x="-751.20953" y="753.42743"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="7.5" width="7.5" x="1.25" y="1.25" ry="1" transform="rotate(45 5 5)"/><rect fill="#003e7a" height="4.2" width="4.2" x="2.9" y="2.9" ry=".5" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyValue.svg b/editor/icons/KeyValue.svg
index 2a112e210a..23bfe93130 100644
--- a/editor/icons/KeyValue.svg
+++ b/editor/icons/KeyValue.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 1.002946 -1043.3636)" width="6.1027" x="-741.53003" y="741.08002"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyValueEased.svg b/editor/icons/KeyValueEased.svg
index 4e4a33c006..725d7ffda0 100644
--- a/editor/icons/KeyValueEased.svg
+++ b/editor/icons/KeyValueEased.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="8.000001" rx="1.000032" ry="1.00003" stroke-width="1.3109" transform="rotate(-90)" width="8.000016" x="-9.000016" y=".999999"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="8" rx="1" ry="1" width="8" x="1" y="1"/></svg>
diff --git a/editor/icons/KeyXPosition.svg b/editor/icons/KeyXPosition.svg
index 59c14cd820..0d186d3dde 100644
--- a/editor/icons/KeyXPosition.svg
+++ b/editor/icons/KeyXPosition.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea7940" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea7940" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyXRotation.svg b/editor/icons/KeyXRotation.svg
index 4494c301bb..97c610901a 100644
--- a/editor/icons/KeyXRotation.svg
+++ b/editor/icons/KeyXRotation.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff2b88" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 .000003 -1042.399994)" width="6.103" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff2b88" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyXScale.svg b/editor/icons/KeyXScale.svg
index cb6011cd83..a0e3b4529a 100644
--- a/editor/icons/KeyXScale.svg
+++ b/editor/icons/KeyXScale.svg
@@ -1 +1 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eac840" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 .000003 -1042.399994)" width="6.103" x="-740.13947" y="741.10779"/></svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eac840" height="6.2" width="6.2" x="1.9" y="1.9" ry=".75" transform="rotate(45 5 5)"/></svg>
diff --git a/editor/icons/KeyXform.svg b/editor/icons/KeyXform.svg
deleted file mode 100644
index 59c14cd820..0000000000
--- a/editor/icons/KeyXform.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea7940" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
diff --git a/editor/icons/KeyboardPhysical.svg b/editor/icons/KeyboardPhysical.svg
index 877b9b89b9..1a8bcf93c4 100644
--- a/editor/icons/KeyboardPhysical.svg
+++ b/editor/icons/KeyboardPhysical.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M4 2a1 1 0 0 0-1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916V3a1 1 0 0 0-1-1Zm2.762 1.768h2.476l3.264 7.464H9.898l-.502-1.3H6.561l-.502 1.3H3.498Zm1.217 2.474L7.254 8.12h1.45z"/><path fill="#e0e0e0" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path fill="#e0e0e0" d="M4 2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1ZM1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Zm5.762-.232h2.476l3.264 7.464H9.898l-.502-1.3H6.561l-.502 1.3H3.498Zm1.217 2.474L7.254 8.12h1.45z"/></svg>
diff --git a/editor/icons/Line.svg b/editor/icons/Line.svg
index c7b1f8a701..0b440b8db7 100644
--- a/editor/icons/Line.svg
+++ b/editor/icons/Line.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 8-8" fill="none" stroke="#ffffff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg>
+<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 10 8-8" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2"/></svg>
diff --git a/editor/icons/MainPlay.svg b/editor/icons/MainPlay.svg
index 5a1d195530..340d44fda8 100644
--- a/editor/icons/MainPlay.svg
+++ b/editor/icons/MainPlay.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1048.4v-8l7 4z" fill="#e0e0e0" fill-rule="evenodd" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 12V4l7 4z" fill="#e0e0e0" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/MaterialPreviewCube.svg b/editor/icons/MaterialPreviewCube.svg
index c4af05ffb0..e7e56d02aa 100644
--- a/editor/icons/MaterialPreviewCube.svg
+++ b/editor/icons/MaterialPreviewCube.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d6d6d6" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d6d6d6"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1 1 4v8l7 3 7-3V4z" fill="#d6d6d6"/><path d="m1 4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 15-7-3V4l7 3z" fill="#e0e0e0"/><path d="m8 15 7-3V4L8 7z" fill="#d6d6d6"/></svg>
diff --git a/editor/icons/MaterialPreviewCubeOff.svg b/editor/icons/MaterialPreviewCubeOff.svg
index e573e170ad..ccf8a1e8f6 100644
--- a/editor/icons/MaterialPreviewCubeOff.svg
+++ b/editor/icons/MaterialPreviewCubeOff.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d6d6d6" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d6d6d6"/><path d="m8 1037.4-7 3v8l7 3 7-3v-8z" fill-opacity=".23529"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1 1 4v8l7 3 7-3V4z" fill="#d6d6d6"/><path d="m1 4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 15-7-3V4l7 3z" fill="#e0e0e0"/><path d="m8 15 7-3V4L8 7z" fill="#d6d6d6"/><path d="M8 1 1 4v8l7 3 7-3V4z" fill-opacity=".235"/></svg>
diff --git a/editor/icons/MaterialPreviewSphere.svg b/editor/icons/MaterialPreviewSphere.svg
index 22c9eef0fb..949d1ef3a7 100644
--- a/editor/icons/MaterialPreviewSphere.svg
+++ b/editor/icons/MaterialPreviewSphere.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM6 3a2 2 0 0 1 0 4 2 2 0 0 1 0-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/MaterialPreviewSphereOff.svg b/editor/icons/MaterialPreviewSphereOff.svg
index e958e3f0a8..5ebd36f85f 100644
--- a/editor/icons/MaterialPreviewSphereOff.svg
+++ b/editor/icons/MaterialPreviewSphereOff.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill-opacity=".23529"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM6 3a2 2 0 0 1 0 4 2 2 0 0 1 0-4z" fill="#e0e0e0"/><path d="M8 1a7 7 0 0 0 0 14A7 7 0 0 0 8 1zM6 3a2 2 0 0 1 0 4 2 2 0 0 1 0-4z" fill-opacity=".23529"/></svg>
diff --git a/editor/icons/Mesh.svg b/editor/icons/Mesh.svg
index a1743e4c58..90d6fe895c 100644
--- a/editor/icons/Mesh.svg
+++ b/editor/icons/Mesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.73 14h6.541A2 2 0 1 0 14 11.27V4.729A2 2 0 1 0 11.27 2Zm.683 2h5.857a2 2 0 0 0 .729.73v5.856L5.412 4zM3.999 5.414 10.584 12H4.727a2 2 0 0 0-.729-.73V5.414z" fill="#ffca5f"/></svg>
diff --git a/editor/icons/MeshInstance2D.svg b/editor/icons/MeshInstance2D.svg
index 8f6de06252..a0d94e2344 100644
--- a/editor/icons/MeshInstance2D.svg
+++ b/editor/icons/MeshInstance2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#8da5f3"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.73 14h6.541A2 2 0 1 0 14 11.27V4.729A2 2 0 1 0 11.27 2Zm.683 2h5.857a2 2 0 0 0 .729.73v5.856L5.412 4zM3.999 5.414 10.584 12H4.727a2 2 0 0 0-.729-.73V5.414z" fill="#8da5f3"/></svg>
diff --git a/editor/icons/MeshInstance3D.svg b/editor/icons/MeshInstance3D.svg
index 67757dafd2..7edb7fcd06 100644
--- a/editor/icons/MeshInstance3D.svg
+++ b/editor/icons/MeshInstance3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#fc7f7f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.73 14h6.541A2 2 0 1 0 14 11.27V4.729A2 2 0 1 0 11.27 2Zm.683 2h5.857a2 2 0 0 0 .729.73v5.856L5.412 4zM3.999 5.414 10.584 12H4.727a2 2 0 0 0-.729-.73V5.414z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/MissingNode.svg b/editor/icons/MissingNode.svg
index 582b244614..ed73096f6e 100644
--- a/editor/icons/MissingNode.svg
+++ b/editor/icons/MissingNode.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141-1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -.72656-1.7148 1.0001 1.0001 0 0 0 -.6875.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -.7168-.30273z" fill="#ff5f5f" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.99 1.99a1 1 0 0 0-.697 1.717L6.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414L8 9.414l4.293 4.293a1 1 0 1 0 1.414-1.414L9.414 8l4.293-4.293a1 1 0 0 0-1.414-1.414L8 6.586 3.707 2.293a1 1 0 0 0-.717-.303z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/MissingResource.svg b/editor/icons/MissingResource.svg
index 582b244614..ed73096f6e 100644
--- a/editor/icons/MissingResource.svg
+++ b/editor/icons/MissingResource.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141-1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -.72656-1.7148 1.0001 1.0001 0 0 0 -.6875.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -.7168-.30273z" fill="#ff5f5f" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.99 1.99a1 1 0 0 0-.697 1.717L6.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414L8 9.414l4.293 4.293a1 1 0 1 0 1.414-1.414L9.414 8l4.293-4.293a1 1 0 0 0-1.414-1.414L8 6.586 3.707 2.293a1 1 0 0 0-.717-.303z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/Navigation2D.svg b/editor/icons/Navigation2D.svg
deleted file mode 100644
index 286fcb8d4c..0000000000
--- a/editor/icons/Navigation2D.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#8da5f3" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/Navigation3D.svg b/editor/icons/Navigation3D.svg
deleted file mode 100644
index 79cca958f8..0000000000
--- a/editor/icons/Navigation3D.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#fc7f7f" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/NavigationPolygon.svg b/editor/icons/NavigationPolygon.svg
index d0fc822f42..c120b4ba5e 100644
--- a/editor/icons/NavigationPolygon.svg
+++ b/editor/icons/NavigationPolygon.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4.9023a2.1002 2.1002 0 0 1 .13086-.73633l.47461-1.2637h-4.5078v-10h8.5859l-4.293 4.293a1.0001 1.0001 0 0 0 0 1.4141l1.3262 1.3262 1.4141-3.7695a2.1002 2.1002 0 0 1 1.9922-1.3613 2.1002 2.1002 0 0 1 .43555.050781l2.2461-2.2461a1.0001 1.0001 0 0 0 -.70703-1.707h-12z" transform="translate(0 1036.4)"/><path d="m15 1051.4-3-8-3 8 3-2z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h4.902a2.1 2.1 0 0 1 .131-.736L7.508 13H3V3h8.586L7.293 7.293a1 1 0 0 0 0 1.414l1.326 1.326 1.414-3.77a2.1 2.1 0 0 1 1.992-1.36 2.1 2.1 0 0 1 .436.05l2.246-2.246A1 1 0 0 0 14 1H2zm13 14-3-8-3 8 3-2z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/New.svg b/editor/icons/New.svg
index 1667f46075..99d74ab05b 100644
--- a/editor/icons/New.svg
+++ b/editor/icons/New.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.400017)"><path d="m2 1v14h8v-1h-2v-4h2v-2h4v-2h-5v-5zm8 0v4h4z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m11 1045.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1v14h8v-1H8v-4h2V8h4V6H9V1zm8 0v4h4z" fill="#e0e0e0"/><path d="M11 9v2H9v2h2v2h2v-2h2v-2h-2V9z" fill="#5fff97"/></svg>
diff --git a/editor/icons/PlaneMesh.svg b/editor/icons/PlaneMesh.svg
index 54b33616ba..857583d278 100644
--- a/editor/icons/PlaneMesh.svg
+++ b/editor/icons/PlaneMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 4-7 4 7 4 7-4zm0 2 3.5 2-3.5 2-3.5-2z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 5 5 3-5 3-5-3z" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/PlayStart.svg b/editor/icons/PlayStart.svg
index afd1251560..ef2408464b 100644
--- a/editor/icons/PlayStart.svg
+++ b/editor/icons/PlayStart.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h1c.55226-.0001.99994-.4477 1-1v-8c-.000055-.5523-.44774-.9999-1-1zm4.9746 0c-.54154.014-.97365.45635-.97461.99805v8c-.000392.8389.97003 1.3054 1.625.78125l5-4c.49938-.4004.49938-1.1601 0-1.5605l-5-4c-.18422-.1473-.41459-.22485-.65039-.21875z" fill="#e0e0e0" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm4.975 0A1 1 0 0 0 7 3.998v8a1 1 0 0 0 1.625.781l5-4a1 1 0 0 0 0-1.56l-5-4A1 1 0 0 0 7.975 3z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/PlayStartBackwards.svg b/editor/icons/PlayStartBackwards.svg
index 7d1624a397..eaf4327558 100644
--- a/editor/icons/PlayStartBackwards.svg
+++ b/editor/icons/PlayStartBackwards.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1039.4a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-1c-.55226-.0001-.99994-.4477-1-1v-8c.000055-.5523.44774-.9999 1-1zm-4.9746 0c.54154.014.97365.4563.97461.998v8c.000392.8389-.97003 1.3055-1.625.7813l-5-4c-.49938-.4004-.49938-1.1601 0-1.5605l5-4c.18422-.1473.41459-.2249.65039-.2188z" fill="#e0e0e0" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M13 3a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM8.025 3A1 1 0 0 1 9 3.998v8a1 1 0 0 1-1.625.781l-5-4a1 1 0 0 1 0-1.56l5-4A1 1 0 0 1 8.025 3z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/PluginScript.svg b/editor/icons/PluginScript.svg
index 3fb34879fe..afcedb4763 100644
--- a/editor/icons/PluginScript.svg
+++ b/editor/icons/PluginScript.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1-.56445 2.2578c-.23643.075851-.46689.16921-.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941c-.11191.22113-.20723.45028-.28516.68555l-2.2539.5625v2l2.2578.56445c.048141.14946.11579.29137.17773.43555h.58789c.51595-.6841 1.1988-1.2456 2.0195-1.5957-.028019-.13296-.042416-.26842-.042969-.4043.0000096-1.1046.89543-2 2-2 1.1046.0000096 2 .89543 2 2-.0001737.1345-.013915.26865-.041016.40039.82295.35108 1.509.91301 2.0254 1.5996h.58008c.063668-.14463.13192-.2874.18164-.4375l2.2539-.5625v-2l-2.2578-.56445c-.075942-.23577-.1693-.46557-.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953c-.22113-.11191-.45028-.20723-.68555-.28516l-.5625-2.2539h-2zm1 6a1 1 0 0 0 -.99805.92969 1 1 0 0 0 -.0019531.070312v2.1738a3 3 0 0 0 -2 2.8262h1v2h1v-2h2v2h1v-2h1a3 3 0 0 0 -.015625-.29883 3 3 0 0 0 -1.9844-2.5254v-2.1758a1 1 0 0 0 -1-1z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1-.565 2.258a4.947 4.947 0 0 0-.689.28L3.758 2.343 2.344 3.758l1.195 1.994c-.112.221-.207.45-.285.685L1 7v2l2.258.564c.048.15.115.292.177.436H4c.54-.684 1.222-1.246 2-1.596a2.037 2.037 0 1 1 4 0A4.766 4.766 0 0 1 12 10h.58c.064-.145.132-.287.182-.438L15.014 9V7l-2.257-.565a4.992 4.992 0 0 0-.28-.687l1.194-1.99-1.414-1.414-1.994 1.195a5.012 5.012 0 0 0-.686-.285L9.016 1h-2zm1 6a1 1 0 0 0-1 1v2.174A3 3 0 0 0 5 13h1v2h1v-2h2v2h1v-2h1a3 3 0 0 0-2-2.826V7.998a1 1 0 0 0-1-1z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/PreviewEnvironment.svg b/editor/icons/PreviewEnvironment.svg
index e0b0257daf..b356459829 100644
--- a/editor/icons/PreviewEnvironment.svg
+++ b/editor/icons/PreviewEnvironment.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.00391a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.0084-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078088c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.00662.10803-.00781.16211-.96392.096801-1.9566.1103-2.9844.027344-.00163-.063192-.00781-.12632-.00781-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055002c.57106-1.0564.95277-2.1268 1.1367-3.2051002.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551002.56647 2.1026002 1.125 3.1367002a5 5 0 0 1 -3.1348-3.5684002zm6.168.55469c-.22615.9886602-.65424 1.9884002-1.3008 3.0059002-.63811-1.0042-1.0645-1.9908-1.293-2.9668002.89027.054126 1.7517.029377 2.5938-.039062z"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.00662.10803-.00781.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0076.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7.000001-7 7 7 0 0 0 -7.000001-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0"><circle cx="8" cy="8" r="6" stroke-width="2"/><path d="M2 8a6.5 2 0 0 0 12 0M8 2c-3 4-3 8 0 12M8 2c3 4 3 8 0 12" stroke-width="1.5"/></g></svg>
diff --git a/editor/icons/PrismMesh.svg b/editor/icons/PrismMesh.svg
index 0fd169cc8c..6481b26a70 100644
--- a/editor/icons/PrismMesh.svg
+++ b/editor/icons/PrismMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.9168678 1.8860265c-.3598509 1.0771598-1.9743383 5.9072035-2.95075512 8.8641335-.15505871.56144.26297692 1.081021.77506042 1.256186 1.9729807.978051 3.9341568 1.98391 5.9144721 2.944682.5872542.201411 1.0933197-.27019 1.6046594-.478049 1.7521944-.878995 3.5092364-1.748814 5.2583944-2.633556.53543-.305954.598247-1.041459.264856-1.51829-.991782-1.9723689-1.966021-3.9544106-2.968743-5.9207481-.320568-.4259931-.882722-.5397422-1.322158-.8066387-1.7413894-.8632626-4.7187151-2.3492561-5.2199521-2.59935915-.501237-.2501031-.9959833-.18552039-1.3558341.89163945zm1.6236276 1.4766588 4.2114703 2.1046892-2.3703904 7.1132625-4.2114703-2.104688zm5.6257546 4.2135626 1.479141 2.9582811-2.9603737 1.481232z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2 6 3-3 9-6-3zm6 3 3 6-6 3" fill="none" stroke-width="2" stroke-linejoin="round" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/Progress1.svg b/editor/icons/Progress1.svg
index d9a58d837e..8707e8ed8c 100644
--- a/editor/icons/Progress1.svg
+++ b/editor/icons/Progress1.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273.4258l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223z"/><path d="m7 1.0801a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1v3.055a4 4 0 0 1 1.027.426l2.159-2.159A7 7 0 0 0 9 1z"/><path d="M7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.08zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.815zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.186l2.158-2.159A4 4 0 0 1 4.13 9H1.08zm10.786 0a4 4 0 0 1-.425 1.027l2.158 2.159A7 7 0 0 0 14.921 9h-3.055zm-5.894 2.441L3.814 13.6a7 7 0 0 0 3.185 1.322v-3.055a4 4 0 0 1-1.027-.426zm4.055 0a4 4 0 0 1-1.028.428v3.05a7 7 0 0 0 3.186-1.32l-2.158-2.158z" fill-opacity=".196"/></g></svg>
diff --git a/editor/icons/Progress2.svg b/editor/icons/Progress2.svg
index d98de2e78b..e238e98c52 100644
--- a/editor/icons/Progress2.svg
+++ b/editor/icons/Progress2.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm-1.3203 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zM1.08 9a7 7 0 0 0 1.32 3.185l2.159-2.158A4 4 0 0 1 4.131 9H1.08zm10.787 0a4 4 0 0 1-.426 1.027l2.159 2.158A7 7 0 0 0 14.922 9h-3.055zm-5.894 2.441L3.814 13.6A7 7 0 0 0 7 14.922v-3.055a4 4 0 0 1-1.027-.426zm4.054 0A4 4 0 0 1 9 11.869v3.05a7 7 0 0 0 3.186-1.32l-2.159-2.158z" fill-opacity=".196"/><path d="m13.6 3.8-2.158 2.158a4 4 0 0 1 .428 1.028h3.05A7 7 0 0 0 13.6 3.8z"/></g></svg>
diff --git a/editor/icons/Progress3.svg b/editor/icons/Progress3.svg
index a1e84fa7cf..ca14c11471 100644
--- a/editor/icons/Progress3.svg
+++ b/editor/icons/Progress3.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm4.8926 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m11.867 1045.4a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.185l2.158-2.158A4 4 0 0 1 4.13 9H1.08zm4.892 2.441L3.814 13.6a7 7 0 0 0 3.185 1.322v-3.055a4 4 0 0 1-1.027-.426zm4.055 0a4 4 0 0 1-1.028.428v3.05a7 7 0 0 0 3.186-1.32l-2.158-2.158z" fill-opacity=".196"/><path d="M11.867 9a4 4 0 0 1-.426 1.027l2.158 2.159A7 7 0 0 0 14.922 9h-3.055z"/></g></svg>
diff --git a/editor/icons/Progress4.svg b/editor/icons/Progress4.svg
index 04a556fd93..c8f6757037 100644
--- a/editor/icons/Progress4.svg
+++ b/editor/icons/Progress4.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m10.027 1047.8a4 4 0 0 1 -1.0273.4277v3.0508a7 7 0 0 0 3.1855-1.3203z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.185l2.158-2.158A4 4 0 0 1 4.13 9H1.08zm10.786 0a4 4 0 0 1-.425 1.027l2.158 2.158A7 7 0 0 0 14.921 9h-3.055zm-5.894 2.441L3.814 13.6a7 7 0 0 0 3.185 1.322v-3.055a4 4 0 0 1-1.027-.426z" fill-opacity=".196"/><path d="M10.027 11.4A4 4 0 0 1 9 11.828v3.05a7 7 0 0 0 3.185-1.32z"/></g></svg>
diff --git a/editor/icons/Progress5.svg b/editor/icons/Progress5.svg
index d5a5432781..62c77b5fdc 100644
--- a/editor/icons/Progress5.svg
+++ b/editor/icons/Progress5.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-1.8398 2.4414a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.4258z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.185l2.158-2.158A4 4 0 0 1 4.13 9H1.08zm10.786 0a4 4 0 0 1-.425 1.027l2.158 2.158A7 7 0 0 0 14.921 9h-3.055zm-1.84 2.441a4 4 0 0 1-1.027.428v3.05a7 7 0 0 0 3.186-1.32l-2.158-2.158z" fill-opacity=".196"/><path d="m5.973 11.4-2.159 2.158A7 7 0 0 0 7 14.88v-3.054a4 4 0 0 1-1.027-.426z"/></g></svg>
diff --git a/editor/icons/Progress6.svg b/editor/icons/Progress6.svg
index 95aebb3cf5..836712c492 100644
--- a/editor/icons/Progress6.svg
+++ b/editor/icons/Progress6.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-1.7324 5.1855a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM11.867 9a4 4 0 0 1-.426 1.027l2.158 2.158A7 7 0 0 0 14.922 9h-3.055zm-5.895 2.441L3.814 13.6A7 7 0 0 0 7 14.922v-3.055a4 4 0 0 1-1.028-.426zm4.055 0A4 4 0 0 1 9 11.869v3.05a7 7 0 0 0 3.185-1.32l-2.158-2.158z" fill-opacity=".196"/><path d="M1.08 9a7 7 0 0 0 1.32 3.186l2.159-2.159A4 4 0 0 1 4.131 9H1.08z"/></g></svg>
diff --git a/editor/icons/Progress7.svg b/editor/icons/Progress7.svg
index cbcd7df35f..c144ae12ab 100644
--- a/editor/icons/Progress7.svg
+++ b/editor/icons/Progress7.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm6.5996 2.7344-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM7 1.08A7 7 0 0 0 3.814 2.4l2.159 2.159A4 4 0 0 1 7 4.13V1.079zm6.6 2.734-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.185l2.158-2.158A4 4 0 0 1 4.13 9H1.08zm10.787 0a4 4 0 0 1-.426 1.027l2.158 2.158A7 7 0 0 0 14.921 9h-3.054zm-5.895 2.441L3.814 13.6a7 7 0 0 0 3.185 1.322v-3.055a4 4 0 0 1-1.027-.426zm4.055 0A4 4 0 0 1 9 11.869v3.05a7 7 0 0 0 3.185-1.32l-2.158-2.158z" fill-opacity=".196"/><path d="M2.4 3.8a7 7 0 0 0-1.322 3.186h3.055a4 4 0 0 1 .426-1.028L2.4 3.8z"/></g></svg>
diff --git a/editor/icons/Progress8.svg b/editor/icons/Progress8.svg
index 900b681c69..03789e345f 100644
--- a/editor/icons/Progress8.svg
+++ b/editor/icons/Progress8.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-6.5996 2.7363a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.4277z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M9 1.078v3.055a4 4 0 0 1 1.027.426L12.186 2.4A7 7 0 0 0 9 1.078zM2.4 3.814A7 7 0 0 0 1.078 7h3.055a4 4 0 0 1 .426-1.027L2.4 3.814zm11.2 0-2.159 2.159A4 4 0 0 1 11.869 7h3.05a7 7 0 0 0-1.32-3.186zM1.08 9a7 7 0 0 0 1.32 3.185l2.158-2.158A4 4 0 0 1 4.13 9H1.08zm10.786 0a4 4 0 0 1-.425 1.027l2.158 2.158A7 7 0 0 0 14.921 9h-3.055zm-5.894 2.441L3.814 13.6a7 7 0 0 0 3.185 1.322v-3.055a4 4 0 0 1-1.027-.426zm4.055 0a4 4 0 0 1-1.028.428v3.05a7 7 0 0 0 3.186-1.32l-2.158-2.158z" fill-opacity=".196"/><path d="M7 1a7 7 0 0 0-3.186 1.32l2.159 2.159A4 4 0 0 1 7 4.05z"/></g></svg>
diff --git a/editor/icons/QuadMesh.svg b/editor/icons/QuadMesh.svg
index 86cc1bc233..54808dbefe 100644
--- a/editor/icons/QuadMesh.svg
+++ b/editor/icons/QuadMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 2h12v12H2zl12 12" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/Range.svg b/editor/icons/Range.svg
index 49311546b0..e3f42cdedb 100644
--- a/editor/icons/Range.svg
+++ b/editor/icons/Range.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.8027344 2.7714844c-1.0905892.2029663-1.089037 1.7659969.00195 1.9667968l2.8808595.5761719.576172 2.8808594c.231158 1.3504655 2.264924.9453327 1.960937-.390625l-.7070279-3.5371094c-.039663-.1968491-.137665-.3771998-.28125-.5175781-.138135-.1351849-.312483-.2274468-.501953-.265625l-3.5371095-.7070312c-.1291868-.0278728-.262617-.0298643-.3925781-.0058594zm-3.9941406 4.2167968c-.6571498-.0349349-1.1683412.5633914-1.03125 1.2070313l.7070312 3.5371095c.079467.394998.3882047.703736.7832031.783203l3.5371094.707031c1.3359577.303987 1.7410905-1.729779.390625-1.960937l-2.8808594-.576172-.5761719-2.8808595c-.0369237-.1982539-.1329195-.3807141-.2753906-.5234375-.1744016-.1751556-.407488-.2795227-.6542968-.2929688z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.75 8 0.75 3.5 3.5 0.75 M8 3.75 l3.5 0.75 0.75 3.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="#8eef97" fill="none"/></svg>
diff --git a/editor/icons/Reload.svg b/editor/icons/Reload.svg
index 4891455cea..9887d0d671 100644
--- a/editor/icons/Reload.svg
+++ b/editor/icons/Reload.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 8a4 4 0 1 1 4 4v2a6 6 0 1 0-6-6H1l3 4 3-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/ReloadSmall.svg b/editor/icons/ReloadSmall.svg
index ca13da056d..970383f239 100644
--- a/editor/icons/ReloadSmall.svg
+++ b/editor/icons/ReloadSmall.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1038.4)"><path d="m8 1039.4a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1618 1050.3)"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M2 7a6 6 0 1 1 6 6v-2a4 4 0 1 0-4-4h2l-3 4-3-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/ReverseGradient.svg b/editor/icons/ReverseGradient.svg
index 55bc5a1678..0a7c434fec 100644
--- a/editor/icons/ReverseGradient.svg
+++ b/editor/icons/ReverseGradient.svg
@@ -1 +1 @@
-<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#e0e0e0"/><stop offset="1" stop-color="#e0e0e0" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1=".99998" x2="15.00008" xlink:href="#a" y1="2.99998" y2="2.99998"/><linearGradient id="c" gradientTransform="matrix(-14.0001 0 0 14.0001 15 13)" gradientUnits="userSpaceOnUse" x1="0" x2="1" xlink:href="#a" y1="0" y2="0"/><path d="m1 1h14v4h-14z" fill="url(#b)"/><path d="m1 11h14v4h-14z" fill="url(#c)"/><path d="m6 6 2 4 2-4z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#e0e0e0"/><stop offset="1" stop-color="#e0e0e0" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="1" x2="15" xlink:href="#a"/><linearGradient id="c" gradientTransform="matrix(-14.0001 0 0 14.0001 15 13)" gradientUnits="userSpaceOnUse" x1="0" x2="1" xlink:href="#a" y1="0" y2="0"/><path d="M1 1h14v4H1z" fill="url(#b)"/><path d="M1 11h14v4H1z" fill="url(#c)"/><path d="m6 6 2 4 2-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/RibbonTrailMesh.svg b/editor/icons/RibbonTrailMesh.svg
index 3f6cf0bfef..7b22a2b9bf 100644
--- a/editor/icons/RibbonTrailMesh.svg
+++ b/editor/icons/RibbonTrailMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f" stroke-width=".25" transform="rotate(90)"><path d="m6.5625-14.062499h1.875v13.124999h-1.875z"/><path d="m.9375-11.249999h1.875v7.499999h-1.875z"/><path d="m12.187499-11.249999h1.875v7.5h-1.875z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 2h8M1 8h14M4 14h8" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/RotateLeft.svg b/editor/icons/RotateLeft.svg
index 4891455cea..9887d0d671 100644
--- a/editor/icons/RotateLeft.svg
+++ b/editor/icons/RotateLeft.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 8a4 4 0 1 1 4 4v2a6 6 0 1 0-6-6H1l3 4 3-4z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/RotateRight.svg b/editor/icons/RotateRight.svg
index 7c9da781dc..4adc69c480 100644
--- a/editor/icons/RotateRight.svg
+++ b/editor/icons/RotateRight.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="matrix(-1 0 0 1 16.026308 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M 11 8 a 4 4 90 1 0 -4 4 v 2 a 6 6 90 1 1 6 -6 h 2 l -3 4 l -3 -4 z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Script.svg b/editor/icons/Script.svg
index 997a4b5e06..12c3fe6101 100644
--- a/editor/icons/Script.svg
+++ b/editor/icons/Script.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1a1 1 0 0 0 -1 1v10h-1v-2h-2v2a1 1 0 0 0 .5.86523 1 1 0 0 0 .5.13477v1h7a2 2 0 0 0 2-2v-8h3v-2a2 2 0 0 0 -2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 1v1a1 1 0 0 0-1 1v10H4v-2H2v2a1 1 0 0 0 .5.865A1 1 0 0 0 3 14v1h7a2 2 0 0 0 2-2V5h3V3a2 2 0 0 0-2-2z" fill="#e0e0e0"/><path d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 1 0 4 0V3a1 1 0 0 1 2 0v3h5V5H8V3a2 2 0 0 0-2-2zM2 11h2v2a1 1 0 0 1-2 0z" fill="#b3b3b3"/></svg>
diff --git a/editor/icons/ScriptCreate.svg b/editor/icons/ScriptCreate.svg
index 70e13e14c4..e1cd78f528 100644
--- a/editor/icons/ScriptCreate.svg
+++ b/editor/icons/ScriptCreate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#5fff97" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 1v1a1 1 0 0 0-1 1v10H4v-2H2v2a1 1 0 0 0 1 1v1h6v-1H8v-4h2V8h2V5h3V3a2 2 0 0 0-2-2z" fill="#e0e0e0"/><path d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 1 0 4 0V3a1 1 0 0 1 2 0v3h5V5H8V3a2 2 0 0 0-2-2zM2 11h2v2a1 1 0 0 1-2 0z" fill="#b3b3b3"/><path d="M13 13h2v-2h-2V9h-2v2H9v2h2v2h2z" fill="#5fff97"/></svg>
diff --git a/editor/icons/ScriptCreateDialog.svg b/editor/icons/ScriptCreateDialog.svg
index b62891faea..90b34f531e 100644
--- a/editor/icons/ScriptCreateDialog.svg
+++ b/editor/icons/ScriptCreateDialog.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm5.5722656 1h3.9980464a1.1426143 1.1426143 0 0 1 1.142579 1.1425781v1.1425781h-1.712891-2.2851562v-.5703124-.5722657c0-.6310659-.5115295-1.1425781-1.1425782-1.1425781zm0 .5722656c.3155215 0 .5703125.254791.5703125.5703125v.5722657.5703124.5722657h.5722657 2.2851562v3.9980471a1.1426143 1.1426143 0 0 1 -1.1425781 1.142578h-4c.6310487 0 1.1425781-.511529 1.1425781-1.142578v-5.7128909c0-.0785019.01823-.1545692.046875-.2226562v-.0019531c.02868-.0672829.0683226-.1266374.1191406-.1777344.00097-.00096.0029352-.0010048.0039063-.0019532.0513303-.0508898.1121075-.0944618.1796875-.1230468.0683505-.028909.1437752-.0429688.2226562-.0429688zm-2.2851562 5.1406254h1.1425781v1.142578c0 .315522-.2567441.572265-.5722656.572265-.0776611 0-.15125-.016852-.21875-.044922-.00206-.000799-.0038594-.003049-.0058594-.003906-.0656506-.028192-.1236101-.067817-.1738281-.117187a.57130715.57130715 0 0 1 -.0097656-.009766c-.0490902-.050487-.0893425-.107988-.1171876-.173828-.028908-.06835-.0449218-.143776-.0449218-.222656z"/><circle cx="-23.915255" cy="3.118624" r="0"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v1h14V3a2 2 0 0 0-2-2zm9 1h1v1h-1zM1 5v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V5zm5.572 1h3.998a1.143 1.143 0 0 1 1.143 1.143v1.142H7.715V7.143C7.715 6.512 7.203 6 6.572 6zm0 .572a.57.57 0 0 1 .57.57v1.716H10v3.998a1.143 1.143 0 0 1-1.143 1.143h-4c.631 0 1.143-.511 1.143-1.143V7.143a.57.57 0 0 1 .047-.223v-.002a.562.562 0 0 1 .119-.178c.001 0 .003 0 .004-.002a.578.578 0 0 1 .18-.123.57.57 0 0 1 .222-.043zm-2.285 5.14H5.43v1.143a.573.573 0 0 1-.791.528l-.006-.004a.564.564 0 0 1-.174-.117.571.571 0 0 1-.01-.01.564.564 0 0 1-.162-.397z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/ScriptExtend.svg b/editor/icons/ScriptExtend.svg
index 96291e8aa2..ac3f5909fc 100644
--- a/editor/icons/ScriptExtend.svg
+++ b/editor/icons/ScriptExtend.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h7c.73866 0 1.3763-.40437 1.7227-1h-3.7227v-4h4v-5h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m16 1048.4-3-3v2h-4v2h4v2z" fill="#5fb2ff" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 1v1a1 1 0 0 0-1 1v10H4v-2H2v2a1 1 0 0 0 1 1v1h7a1.99 1.99 0 0 0 1.723-1H8v-4h4V5h3V3a2 2 0 0 0-2-2z" fill="#e0e0e0"/><path d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 1 0 4 0V3a1 1 0 0 1 2 0v3h5V5H8V3a2 2 0 0 0-2-2zM2 11h2v2a1 1 0 0 1-2 0z" fill="#b3b3b3"/><path d="m16 12-3-3v2H9v2h4v2z" fill="#5fb2ff"/></svg>
diff --git a/editor/icons/ScriptRemove.svg b/editor/icons/ScriptRemove.svg
index 392d38e06d..5cafa263b9 100644
--- a/editor/icons/ScriptRemove.svg
+++ b/editor/icons/ScriptRemove.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-.46484-3h3v-2c0-1.1046-.89543-2-2-2h-7z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff5f5f" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 1v1a1 1 0 0 0-1 1v10H4v-2H2v2a1 1 0 0 0 1 1v1h5.635l-1.584-1.584 1.414-1.414-1.414-1.416 3.535-3.535L12 8.465V5h3V3a2 2 0 0 0-2-2H6z" fill="#e0e0e0"/><path d="M6 1a2 2 0 0 0-2 2v7H1v3a2 2 0 1 0 4 0V3a1 1 0 0 1 2 0v3h5V5H8V3a2 2 0 0 0-2-2zM2 11h2v2a1 1 0 0 1-2 0z" fill="#b3b3b3"/><path d="m13.414 12 1.414-1.414-1.414-1.414L12 10.586l-1.414-1.414-1.415 1.414L10.586 12l-1.415 1.414 1.415 1.414L12 13.414l1.414 1.414 1.414-1.414z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/SeparationRayShape3D.svg b/editor/icons/SeparationRayShape3D.svg
index 44d32fe83b..65c68d0b04 100644
--- a/editor/icons/SeparationRayShape3D.svg
+++ b/editor/icons/SeparationRayShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="m8 1-6 5 4 2.666v4.334l2 2v-5-2z" fill="#a2d2ff"/><path d="m8 1v7 2l-2-1.334v1.334l2 1.5v3.5l2-2v-4.334l4-2.666z" fill="#2998ff"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1 3 6a5 2 0 0 0 3 1.8v6.4a2 .8 0 0 0 2 .8z" fill="#a2d2ff"/><path d="m8 1 5 5a5 2 0 0 1-3 1.8v6.4a2 .8 0 0 1-2 .8V9.5a5 2 0 0 1-2-.2V7.8A5 2 0 0 0 8 8z" fill="#2998ff"/></svg>
diff --git a/editor/icons/Shortcut.svg b/editor/icons/Shortcut.svg
index 2e9a69d8b6..10a5c894c6 100644
--- a/editor/icons/Shortcut.svg
+++ b/editor/icons/Shortcut.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 2c-.55228 0-1 .4477-1 1v9.084c.0004015.506.448.91602 1 .91602h8c.552 0 .9996-.41002 1-.91602v-9.084c0-.5523-.44772-1-1-1zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a.99998.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9zm6 0h3l-1 3h2l-4 4 1-3h-2z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path fill="#e0e0e0" d="M4 2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1Zm3 2h3L9 7h2l-4 4 1-3H6zM1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4Z"/></svg>
diff --git a/editor/icons/SphereMesh.svg b/editor/icons/SphereMesh.svg
index be2dd44a34..83dd42f530 100644
--- a/editor/icons/SphereMesh.svg
+++ b/editor/icons/SphereMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7s7-3.1458 7-7c0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm3.7852 6.2812c-.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-.072301 2.5419-.26704 3.7852-.57031zm-9.5645.017578c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#ffca5f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/TextEdit.svg b/editor/icons/TextEdit.svg
index a749c17c91..1053ad1882 100644
--- a/editor/icons/TextEdit.svg
+++ b/editor/icons/TextEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v4h1v-4z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h10v10H3zm1 1v4h1V4z" fill="#8eef97"/></svg>
diff --git a/editor/icons/TextFile.svg b/editor/icons/TextFile.svg
index f480217dcd..972c40b0b0 100644
--- a/editor/icons/TextFile.svg
+++ b/editor/icons/TextFile.svg
@@ -1 +1 @@
-<svg enable-background="new" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.370548 12.198712 1.078638-.0225c-.004-.738576-.008-1.477152-.01198-2.215728-1.429703.011985-2.859406.02397-4.289109.035955.004.759672.008 1.519344.01198 2.279016.40349-.01135.806981-.02271 1.210471-.03406v3.755044h2m-7.2700003-3.749287c.332722.21587.665444.431741.998166.647611-.3328629.218648-.6657258.437297-.9985887.655945-.0000001.818044-.0000002 1.636088-.0000003 2.454132.5662705-.533749 1.1325409-1.067498 1.6988114-1.601247.6353035.532396 1.2706071 1.064791 1.9059106 1.597187-.00095-.757409-.0019-1.514817-.00285-2.272226-.2987204-.278501-.5974407-.557002-.8961611-.835503.2983766-.205775.5967531-.41155.8951297-.617325.00283-.73844.00565-1.476881.00848-2.215321-.63732.474447-1.27464.948893-1.91196 1.42334-.5656447-.504299-1.1312895-1.008599-1.6969342-1.5128982m-1.4606388 2.2314242c.3595459-.0075.7190917-.015 1.0786376-.0225-.00399-.738576-.00799-1.477152-.011985-2.2157276-1.4297028.011985-2.8594057.02397-4.2891085.035955.00399.7596716.00799 1.5193436.011985 2.2790156.4034903-.01135.8069806-.02271 1.2104709-.03406v3.755044h2m2.3600877-14.999998c-.18815.7526-.3763 1.5052-.56445 2.2578-.3833928.1379205-.7411891.4041566-1.0765556.0469548-.5337315-.3203516-1.0674629-.6407032-1.6011944-.9610548-.4713667.4713667-.9427333.9427333-1.4141 1.4141.3984333.6647.7968667 1.3294 1.1953 1.9941-.1706946.369732-.2331288.8106877-.7232054.7948719-.6052849.1510593-1.2105697.3021187-1.8158546.4531781v2h5.2715c-.6869282-1.0800497-.0133438-2.6625661 1.2286888-2.9370347 1.2082391-.3582 2.5455142.6777799 2.4998312 1.9370347.104409.4657408-.6052318 1.1778026.181951 1h4.818019c0-.6666667 0-1.3333333 0-2-.7526-.18815-1.5052-.3763-2.2578-.56445-.138671-.3826756-.40361-.7396543-.047118-1.0747035.320406-.5343322.640812-1.0686643.961218-1.6029965-.471367-.4713667-.942733-.9427333-1.4141-1.4141-.6647.3984333-1.3294.7968667-1.9941 1.1953-.3697319-.1706947-.8106877-.2331288-.7948719-.7232054-.1510593-.6052849-.3021187-1.2105697-.4531781-1.8158546-.6666322.00004002-1.3334865-.00008002-1.99998.00006z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M13.37 12.199h1.08V9.983h-4.289v2.28h1.21v3.755h2zm-7.27.048 1 .648-1 .656v2.454l1.7-1.601L9.705 16v-2.272l-.896-.836.895-.617v-2.216l-1.912 1.424L6.101 9.97zm-1.46-.045h1.079V9.986h-4.29v2.279h1.21V16h2ZM7 1l-.564 2.258c-.384.138-.742.404-1.077.047l-1.601-.961-1.414 1.414 1.195 1.994c-.17.37-.233.81-.723.795L1 7v2h5.27a2 2 0 1 1 3.5 0H15V7l-2.258-.565c-.139-.382-.403-.74-.047-1.074l.961-1.603-1.414-1.414-1.994 1.195c-.37-.17-.81-.233-.795-.723L9 1H7z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/TrackContinuous.svg b/editor/icons/TrackContinuous.svg
index 7f64ad7dbb..951a13a28e 100644
--- a/editor/icons/TrackContinuous.svg
+++ b/editor/icons/TrackContinuous.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4c6 0 6-4 12-4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 16 8" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 6c6 0 6-4 12-4" fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
diff --git a/editor/icons/TransitionEnd.svg b/editor/icons/TransitionEnd.svg
index d0263c159e..62c9e1fae9 100644
--- a/editor/icons/TransitionEnd.svg
+++ b/editor/icons/TransitionEnd.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="translate(-2 -1036.4)"/><rect height="10.067283" ry=".76286" width="3.068124" x="11.16989" y="3.008411"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M2.988 3c-.547.01-.987.451-.988.998v8a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 2.988 3z"/><rect height="10.067" ry=".763" width="3.068" x="11.17" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionEndAuto.svg b/editor/icons/TransitionEndAuto.svg
index 89eb373df6..de114507a8 100644
--- a/editor/icons/TransitionEndAuto.svg
+++ b/editor/icons/TransitionEndAuto.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="translate(-2 -1036.4)"/><rect height="10.067283" ry=".76286" width="3.068124" x="11.16989" y="3.008411"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57"><path d="M2.988 3c-.547.01-.987.451-.988.998v8a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 2.988 3z" fill-rule="evenodd"/><rect height="10.067" ry=".763" width="3.068" x="11.17" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionEndAutoBig.svg b/editor/icons/TransitionEndAutoBig.svg
index 97774d7d6d..b7a9b85b23 100644
--- a/editor/icons/TransitionEndAutoBig.svg
+++ b/editor/icons/TransitionEndAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 -4.197589 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="14.371336" y="3.007612"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042" stroke-width="1.41"><path d="M2.836 2.996a1.413 1.413 0 0 0-1.394 1.407v11.28a1.41 1.41 0 0 0 2.192 1.173l8.46-5.64a1.41 1.41 0 0 0 0-2.346l-8.46-5.64a1.41 1.41 0 0 0-.798-.234z"/><rect height="14.194" ry="1.076" width="4.326" x="14.371" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionEndBig.svg b/editor/icons/TransitionEndBig.svg
index 6cfcf44bf0..11f2871cc5 100644
--- a/editor/icons/TransitionEndBig.svg
+++ b/editor/icons/TransitionEndBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 -4.29479 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="14.411009" y="3.186887"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042" stroke-width="1.42"><path d="M2.79 3.175a1.424 1.424 0 0 0-1.403 1.417v11.363c0 1.134 1.264 1.811 2.208 1.182l8.522-5.681a1.42 1.42 0 0 0 0-2.364L3.595 3.411a1.42 1.42 0 0 0-.805-.236z"/><rect height="14.299" ry="1.084" width="4.358" x="14.411" y="3.187"/></g></svg>
diff --git a/editor/icons/TransitionImmediate.svg b/editor/icons/TransitionImmediate.svg
index ffab62410d..638675a349 100644
--- a/editor/icons/TransitionImmediate.svg
+++ b/editor/icons/TransitionImmediate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#e0e0e0" fill-rule="evenodd" transform="translate(-2 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.988 3c-.547.01-.987.451-.988.998v8a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 2.988 3z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/TransitionImmediateAuto.svg b/editor/icons/TransitionImmediateAuto.svg
index 98c583f407..a4ee688469 100644
--- a/editor/icons/TransitionImmediateAuto.svg
+++ b/editor/icons/TransitionImmediateAuto.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#77ce57" fill-rule="evenodd" transform="translate(-2 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2.988 3c-.547.01-.987.451-.988.998v8a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 2.988 3z" fill="#77ce57"/></svg>
diff --git a/editor/icons/TransitionImmediateAutoBig.svg b/editor/icons/TransitionImmediateAutoBig.svg
index 36a49621eb..accc4e49fd 100644
--- a/editor/icons/TransitionImmediateAutoBig.svg
+++ b/editor/icons/TransitionImmediateAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#77ce57" fill-rule="evenodd" stroke="#414042" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M5.111 2.306c-.86.015-1.55.708-1.553 1.568v12.568c0 1.254 1.399 2.003 2.443 1.307l9.426-6.284a1.571 1.571 0 0 0 0-2.614L6.001 2.567a1.57 1.57 0 0 0-.89-.261z" fill="#77ce57" stroke="#414042" stroke-width="1.571"/></svg>
diff --git a/editor/icons/TransitionImmediateBig.svg b/editor/icons/TransitionImmediateBig.svg
index aa79e63457..ce35cb0770 100644
--- a/editor/icons/TransitionImmediateBig.svg
+++ b/editor/icons/TransitionImmediateBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#e0e0e0" fill-rule="evenodd" stroke="#414042" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M5.111 2.306c-.86.015-1.55.708-1.553 1.568v12.568c0 1.254 1.399 2.003 2.443 1.307l9.426-6.284a1.571 1.571 0 0 0 0-2.614L6.001 2.567a1.57 1.57 0 0 0-.89-.261z" fill="#e0e0e0" stroke="#414042" stroke-width="1.571"/></svg>
diff --git a/editor/icons/TransitionSync.svg b/editor/icons/TransitionSync.svg
index 439d17fc3b..87e25b870b 100644
--- a/editor/icons/TransitionSync.svg
+++ b/editor/icons/TransitionSync.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="translate(2.554247 -1036.4)"/><rect height="10.067283" ry=".76286" width="3.068124" x="1.965517" y="3.008411"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M7.543 3c-.547.01-.988.451-.989.998v8a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 7.543 3z"/><rect height="10.067" ry=".763" width="3.068" x="1.966" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionSyncAuto.svg b/editor/icons/TransitionSyncAuto.svg
index 022e1d8a7d..9e22974d49 100644
--- a/editor/icons/TransitionSyncAuto.svg
+++ b/editor/icons/TransitionSyncAuto.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="translate(3.081581 -1036.4)"/><rect height="10.067283" ry=".76286" width="3.068124" x="1.965517" y="3.008411"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57"><path d="M8.07 3c-.547.01-.987.451-.988.998v8a1 1 0 0 0 1.554.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 8.07 3z"/><rect height="10.067" ry=".763" width="3.068" x="1.966" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionSyncAutoBig.svg b/editor/icons/TransitionSyncAutoBig.svg
index 440d4c4770..6ca4e20465 100644
--- a/editor/icons/TransitionSyncAutoBig.svg
+++ b/editor/icons/TransitionSyncAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 2.175293 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="1.625573" y="3.007612"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042" stroke-width="1.41"><path d="M9.209 2.996a1.413 1.413 0 0 0-1.394 1.407v11.28a1.41 1.41 0 0 0 2.192 1.173l8.46-5.64a1.41 1.41 0 0 0 0-2.346l-8.46-5.64a1.41 1.41 0 0 0-.798-.234z"/><rect height="14.194" ry="1.076" width="4.326" x="1.626" y="3.008"/></g></svg>
diff --git a/editor/icons/TransitionSyncBig.svg b/editor/icons/TransitionSyncBig.svg
index c6ef188e98..4fc445e268 100644
--- a/editor/icons/TransitionSyncBig.svg
+++ b/editor/icons/TransitionSyncBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 1.874702 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="1.461856" y="3.186887"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042" stroke-width="1.42"><path d="M8.96 3.175a1.424 1.424 0 0 0-1.404 1.417v11.363c0 1.134 1.264 1.811 2.208 1.182l8.522-5.681a1.42 1.42 0 0 0 0-2.364L9.764 3.411a1.42 1.42 0 0 0-.804-.236z"/><rect height="14.299" ry="1.084" width="4.358" x="1.462" y="3.187"/></g></svg>
diff --git a/editor/icons/TubeTrailMesh.svg b/editor/icons/TubeTrailMesh.svg
index 3ca524226f..1cbab36cbe 100644
--- a/editor/icons/TubeTrailMesh.svg
+++ b/editor/icons/TubeTrailMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m14.0625 7.5c0-1.6377-.2123-3.12-.5969-4.2737-.1923-.57682-.4237-1.0754-.7508-1.4905-.3271-.41505-.8259-.79834-1.4648-.79834h-7.5c-.6389 0-1.1396.38329-1.4667.79834s-.5585.91366-.7507 1.4905c-.3846 1.1536-.5951 2.6359-.5951 4.2737s.2105 3.12.5951 4.2737c.1922.57682.4236 1.0754.7507 1.4905.3271.41505.8278.79834 1.4667.79834h7.5c.6389 0 1.1377-.38329 1.4648-.79834s.5585-.91366.7508-1.4905c.3846-1.1536.5969-2.6359.5969-4.2737zm-2.8125-4.6875002c.4358 1.0052002 0 0 .4358 1.0052002.2941.88221.5017 2.2134.5017 3.6823s-.2076 2.8-.5017 3.6823c-.1449.4347 0 0-.4358 1.005199l-7.5.000041c-.1212-.15705-.2929-.57092-.4376-1.0052-.2941-.88221-.4999-2.2134-.4999-3.6823s.2058-2.8.4999-3.6823c.1447-.43433.3164-.8482.4376-1.0052"/><path d="m6.5625-11.25h1.875v7.5h-1.875z" stroke-width=".25" transform="rotate(90)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M11.75 2a5 8 0 0 1 0 11h-8.5a5 8 0 0 1 0 -11z M4 7.5 h7" fill="none" stroke-width="2" stroke-linejoin="round" stroke="#ffca5f"/></svg>
diff --git a/editor/icons/VBoxContainer.svg b/editor/icons/VBoxContainer.svg
index c515d61d83..18de011cde 100644
--- a/editor/icons/VBoxContainer.svg
+++ b/editor/icons/VBoxContainer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1039.4c0-1.1046-.89543-2-2-2h-10c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2zm-2 0v2h-10v-2zm0 4v2h-10v-2zm0 4v2h-10v-2z" fill="#8eef97" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h10v2H3zm0 4h10v2H3zm0 4h10v2H3z" fill="#8eef97"/></svg>
diff --git a/editor/icons/VisualShaderNodeColorOp.svg b/editor/icons/VisualShaderNodeColorOp.svg
index 005da8b6e1..168168d8b3 100644
--- a/editor/icons/VisualShaderNodeColorOp.svg
+++ b/editor/icons/VisualShaderNodeColorOp.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><g fill="#ffffff"><path d="m4 1050.3622h6v-10h-6z" fill-rule="evenodd" stroke="#ffffff" stroke-linejoin="round" stroke-width="2"/><path d="m1 1041.3622h2v2h-2z"/><path d="m1 1047.3622h2v2h-2z"/><path d="m11 1044.3622h2v2h-2z"/></g><g fill-opacity=".862745"><path d="m5 1041.3622h4v2h-4z" fill="#ff0000"/><path d="m5 1044.3622h4v2h-4z" fill="#00ff00"/><path d="m5 1047.3622h4v2h-4z" fill="#0000ff"/></g></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M4 1a1 1 0 0 0-1 1v1H1v2h2v4H1v2h2v1a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V8h2V6h-2V2a1 1 0 0 0-1-1zm1 3 4 3-4 3z" fill="#fff"/><g fill-opacity=".863"><path d="M5 3h4v2H5z" fill="red"/><path d="M5 6h4v2H5z" fill="#0f0"/><path d="M5 9h4v2H5z" fill="#00f"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeColorUniform.svg b/editor/icons/VisualShaderNodeColorUniform.svg
index db41e5eca3..a6e3645428 100644
--- a/editor/icons/VisualShaderNodeColorUniform.svg
+++ b/editor/icons/VisualShaderNodeColorUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1038.3622c-1.10457 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2z" fill="#fff"/><g fill-opacity=".392157"><path d="m7 2a3 3 0 0 0 -3 3 3 3 0 0 0 .2109375 1.1054688 3 3 0 0 0 -2.2109375 2.8945312 3 3 0 0 0 3 3 3 3 0 0 0 2-.767578 3 3 0 0 0 2 .767578 3 3 0 0 0 3-3 3 3 0 0 0 -2.2148438-2.890625 3 3 0 0 0 .2148438-1.109375 3 3 0 0 0 -3-3z" fill="#ffffff" transform="translate(0 1038.3622)"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/></g></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M2 0a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z" fill="#fff"/><g fill-opacity=".392"><path d="M7 2a3 3 0 0 0-3 3 3 3 0 0 0 .21 1.106A3 3 0 0 0 2 9a3 3 0 0 0 3 3 3 3 0 0 0 2-.767A3 3 0 0 0 9 12a3 3 0 0 0 3-3 3 3 0 0 0-2.215-2.89A3 3 0 0 0 10 5a3 3 0 0 0-3-3z" fill="#fff"/><circle cx="7" cy="5" fill="red" r="3"/><circle cx="5" cy="9" fill="#00f" r="3"/><circle cx="9" cy="9" fill="#0f0" r="3"/><circle cx="7" cy="5" fill="red" r="3"/><circle cx="5" cy="9" fill="#00f" r="3"/><circle cx="9" cy="9" fill="#0f0" r="3"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeFloatFunc.svg b/editor/icons/VisualShaderNodeFloatFunc.svg
index 382c4e66af..7cf2a5f608 100644
--- a/editor/icons/VisualShaderNodeFloatFunc.svg
+++ b/editor/icons/VisualShaderNodeFloatFunc.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#cf68ea" transform="translate(0 -1038.3622)"><path d="m6 1042.3622h2v4.999982h-2z"/><path d="m9.0703125 1a3 3 0 0 0 -1.5703125.4023438 3 3 0 0 0 -1.5 2.5976562h2a1 1 0 0 1 1-1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5-2.5976562 3 3 0 0 0 -1.4296875-.4023438z" transform="translate(0 1038.3622)"/><path d="m10 1042.3622h2v1.000017h-2z"/><path d="m2 10a3 3 0 0 0 1.5 2.597656 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.597656h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" transform="translate(0 1038.3622)"/><path d="m6-1048.3622h2v1.000017h-2z" transform="scale(1 -1)"/><path d="m4 1044.3622h6v2h-6z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M3 10 a 2 2 0 0 0 4 0v-6a2 2 0 0 1 4 0v1 M4 7h6" stroke-width="2" stroke="#cf68ea" fill="none"/></svg>
diff --git a/editor/icons/VisualShaderNodeFloatOp.svg b/editor/icons/VisualShaderNodeFloatOp.svg
index 546ffc148e..54048f0e61 100644
--- a/editor/icons/VisualShaderNodeFloatOp.svg
+++ b/editor/icons/VisualShaderNodeFloatOp.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#cf68ea" transform="translate(0 -1038.3622)"><path d="m4 1c-.5522619.0001-.9999448.4477-1 1v10c.0000552.5523.4477381.9999 1 1h6c.552262-.0001.999945-.4477 1-1v-10c-.000055-.5523-.447738-.9999-1-1zm1 3 4 3-4 3z" fill-rule="evenodd" transform="translate(0 1038.3622)"/><path d="m1 1041.3622h2v2h-2z"/><path d="m1 1047.3622h2v2h-2z"/><path d="m11 1044.3622h2v2h-2z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M4 1a1 1 0 0 0-1 1v1H1v2h2v4H1v2h2v1a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V8h2V6h-2V2a1 1 0 0 0-1-1zm1 3 4 3-4 3z" fill="#cf68ea"/></svg>
diff --git a/editor/icons/VisualShaderNodeFloatUniform.svg b/editor/icons/VisualShaderNodeFloatUniform.svg
index dda5d098a3..9612ed0fa5 100644
--- a/editor/icons/VisualShaderNodeFloatUniform.svg
+++ b/editor/icons/VisualShaderNodeFloatUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2zm4 2h5v2h-5a1.0000174 1.0000174 0 0 0 -1 1 1.0000174 1.0000174 0 0 0 1 1h2c1.6568542 0 3 1.3431 3 3s-1.3431458 3-3 3h-5v-2h5a1.0000174 1.0000174 0 0 0 1-1 1.0000174 1.0000174 0 0 0 -1-1h-2c-1.6568542 0-3-1.3431-3-3s1.3431458-3 3-3z" fill="#cf68ea"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M2 0a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm4 2h5v2H6a1 1 0 0 0 0 2h2a3 3 0 1 1 0 6H3v-2h5a1 1 0 0 0 0-2H6a3 3 0 1 1 0-6z" fill="#cf68ea"/></svg>
diff --git a/editor/icons/VisualShaderNodeIntFunc.svg b/editor/icons/VisualShaderNodeIntFunc.svg
index 382c4e66af..7cf2a5f608 100644
--- a/editor/icons/VisualShaderNodeIntFunc.svg
+++ b/editor/icons/VisualShaderNodeIntFunc.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#cf68ea" transform="translate(0 -1038.3622)"><path d="m6 1042.3622h2v4.999982h-2z"/><path d="m9.0703125 1a3 3 0 0 0 -1.5703125.4023438 3 3 0 0 0 -1.5 2.5976562h2a1 1 0 0 1 1-1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5-2.5976562 3 3 0 0 0 -1.4296875-.4023438z" transform="translate(0 1038.3622)"/><path d="m10 1042.3622h2v1.000017h-2z"/><path d="m2 10a3 3 0 0 0 1.5 2.597656 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.597656h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" transform="translate(0 1038.3622)"/><path d="m6-1048.3622h2v1.000017h-2z" transform="scale(1 -1)"/><path d="m4 1044.3622h6v2h-6z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M3 10 a 2 2 0 0 0 4 0v-6a2 2 0 0 1 4 0v1 M4 7h6" stroke-width="2" stroke="#cf68ea" fill="none"/></svg>
diff --git a/editor/icons/VisualShaderNodeIntOp.svg b/editor/icons/VisualShaderNodeIntOp.svg
index 546ffc148e..54048f0e61 100644
--- a/editor/icons/VisualShaderNodeIntOp.svg
+++ b/editor/icons/VisualShaderNodeIntOp.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#cf68ea" transform="translate(0 -1038.3622)"><path d="m4 1c-.5522619.0001-.9999448.4477-1 1v10c.0000552.5523.4477381.9999 1 1h6c.552262-.0001.999945-.4477 1-1v-10c-.000055-.5523-.447738-.9999-1-1zm1 3 4 3-4 3z" fill-rule="evenodd" transform="translate(0 1038.3622)"/><path d="m1 1041.3622h2v2h-2z"/><path d="m1 1047.3622h2v2h-2z"/><path d="m11 1044.3622h2v2h-2z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M4 1a1 1 0 0 0-1 1v1H1v2h2v4H1v2h2v1a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V8h2V6h-2V2a1 1 0 0 0-1-1zm1 3 4 3-4 3z" fill="#cf68ea"/></svg>
diff --git a/editor/icons/VisualShaderNodeIntUniform.svg b/editor/icons/VisualShaderNodeIntUniform.svg
index dda5d098a3..9612ed0fa5 100644
--- a/editor/icons/VisualShaderNodeIntUniform.svg
+++ b/editor/icons/VisualShaderNodeIntUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2zm4 2h5v2h-5a1.0000174 1.0000174 0 0 0 -1 1 1.0000174 1.0000174 0 0 0 1 1h2c1.6568542 0 3 1.3431 3 3s-1.3431458 3-3 3h-5v-2h5a1.0000174 1.0000174 0 0 0 1-1 1.0000174 1.0000174 0 0 0 -1-1h-2c-1.6568542 0-3-1.3431-3-3s1.3431458-3 3-3z" fill="#cf68ea"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M2 0a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm4 2h5v2H6a1 1 0 0 0 0 2h2a3 3 0 1 1 0 6H3v-2h5a1 1 0 0 0 0-2H6a3 3 0 1 1 0-6z" fill="#cf68ea"/></svg>
diff --git a/editor/icons/VisualShaderNodeVectorFunc.svg b/editor/icons/VisualShaderNodeVectorFunc.svg
index e452bc3d49..11405f13e5 100644
--- a/editor/icons/VisualShaderNodeVectorFunc.svg
+++ b/editor/icons/VisualShaderNodeVectorFunc.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" transform="translate(0 -1038.3622)"><path d="m6 1042.3622h2v4.999982h-2z"/><path d="m9.0703125 1a3 3 0 0 0 -1.5703125.4023438 3 3 0 0 0 -1.5 2.5976562h2a1 1 0 0 1 1-1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5-2.5976562 3 3 0 0 0 -1.4296875-.4023438z" transform="translate(0 1038.3622)"/><path d="m10 1042.3622h2v1.000017h-2z"/><path d="m2 10a3 3 0 0 0 1.5 2.597656 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.597656h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" transform="translate(0 1038.3622)"/><path d="m6-1048.3622h2v1.000017h-2z" transform="scale(1 -1)"/><path d="m4 1044.3622h6v2h-6z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="M3 10 a 2 2 0 0 0 4 0v-6a2 2 0 0 1 4 0v1 M4 7h6" stroke-width="2" stroke="#77ce57" fill="none"/></svg>
diff --git a/editor/icons/Warning.svg b/editor/icons/Warning.svg
index cdb88dd2d2..405ce666b0 100644
--- a/editor/icons/Warning.svg
+++ b/editor/icons/Warning.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#ffdd65" height="8" ry="4" width="8"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle fill="#ffdd65" cx="4" cy="4" r="4"/></svg>
diff --git a/editor/icons/World2D.svg b/editor/icons/World2D.svg
index d784836694..94d42a2d34 100644
--- a/editor/icons/World2D.svg
+++ b/editor/icons/World2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1037.4a1.0001 1.0001 0 0 0 -1 1v10a1.0001 1.0001 0 0 0 1 1c2.3667 0 3.9746.4629 5.7246.9629s3.6421 1.0371 6.2754 1.0371a1.0001 1.0001 0 0 0 1-1v-10a1.0001 1.0001 0 0 0 -1-1c-2.3667 0-3.9746-.4609-5.7246-.9609s-3.6421-1.0391-6.2754-1.0391zm1 2.0957c1.7984.1158 3.2574.448 4.7246.8672 1.4977.4279 3.194.8188 5.2754.9414v8.002c-1.7985-.1158-3.2574-.448-4.7246-.8672-1.4977-.4279-3.194-.8208-5.2754-.9434z" fill="#e0e0e0" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 12c6 0 6 2 12 2V4C8 4 8 2 2 2z" stroke="#e0e0e0" stroke-width="2" stroke-linejoin="round" fill="none"/></svg>
diff --git a/editor/icons/WorldEnvironment.svg b/editor/icons/WorldEnvironment.svg
index 6c7e34657f..8d9c541a86 100644
--- a/editor/icons/WorldEnvironment.svg
+++ b/editor/icons/WorldEnvironment.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.0039062a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.96392.096801-1.9566.1103-2.9844.027344-.0016335-.063192-.0078125-.12632-.0078125-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348-3.5684zm6.168.55469c-.22615.98866-.65424 1.9884-1.3008 3.0059-.63811-1.0042-1.0645-1.9908-1.293-2.9668.89027.054126 1.7517.029377 2.5938-.039062z" fill="#fc7f7f"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0075968.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z" fill="#8da5f3"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none"><g stroke-width="1.5"><path d="M2 8a6.5 2 0 0 0 6 1.25M8 2c-3 4-3 8 0 12" stroke="#fc7f7f"/><path d="M14 8a6.5 2 0 0 1-6 1.25M8 2c3 4 3 8 0 12" stroke="#8da5f3" stroke-linejoin="round"/></g><g stroke-width="2"><path d="M8 2a6 6 0 0 1 0 12" stroke="#8da5f3"/><path d="M8 2a6 6 0 0 0 0 12m-1 0" stroke="#fc7f7f"/></g><path d="M7.5 14v-1.325M7.5 2v1.325" stroke="#fc7f7f"/></g></svg>
diff --git a/editor/icons/XRCamera3D.svg b/editor/icons/XRCamera3D.svg
index b4657c9f2c..e6d35a08a7 100644
--- a/editor/icons/XRCamera3D.svg
+++ b/editor/icons/XRCamera3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9.5 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117-.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3zm-5.5 12v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 0a3 3 0 0 0-3 2.777 3 3 0 1 0-3 5.047V10a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V9l3 2V5l-3 2V5.23A3 3 0 0 0 9.5 0zM4 12v1a1 1 0 0 0 1 1 1 1 0 0 0-1 1v1h1v-1h1v1h1v-1a1 1 0 0 0-1-1 1 1 0 0 0 1-1v-1H6v1H5v-1zm5 0v4h1v-1h1v1h1v-1a1 1 0 0 0-.137-.5A1 1 0 0 0 12 14v-1a1 1 0 0 0-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg>
diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
index 6214a2b70d..bffc100faf 100644
--- a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
+++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
@@ -31,6 +31,7 @@
#include "post_import_plugin_skeleton_rest_fixer.h"
#include "editor/import/scene_import_settings.h"
+#include "scene/3d/bone_attachment_3d.h"
#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
@@ -105,42 +106,6 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
global_transform.origin = Vector3(); // Translation by a Node is not a bone animation, so the retargeted model should be at the origin.
}
- // Calc IBM difference.
- LocalVector<Vector<Transform3D>> ibm_diffs;
- {
- TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D");
- while (nodes.size()) {
- ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back());
- ERR_CONTINUE(!mi);
-
- Ref<Skin> skin = mi->get_skin();
- ERR_CONTINUE(!skin.is_valid());
-
- Node *node = mi->get_node(mi->get_skeleton_path());
- ERR_CONTINUE(!node);
-
- Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node);
- if (!mesh_skeleton || mesh_skeleton != src_skeleton) {
- continue;
- }
-
- Vector<Transform3D> ibm_diff;
- ibm_diff.resize(src_skeleton->get_bone_count());
- Transform3D *ibm_diff_w = ibm_diff.ptrw();
-
- int skin_len = skin->get_bind_count();
- for (int i = 0; i < skin_len; i++) {
- StringName bn = skin->get_bind_name(i);
- int bone_idx = src_skeleton->find_bone(bn);
- if (bone_idx >= 0) {
- ibm_diff_w[bone_idx] = global_transform * src_skeleton->get_bone_global_rest(bone_idx) * skin->get_bind_pose(i);
- }
- }
-
- ibm_diffs.push_back(ibm_diff);
- }
- }
-
// Apply node transforms.
if (bool(p_options["retarget/rest_fixer/apply_node_transforms"])) {
Vector3 scl = global_transform.basis.get_scale_local();
@@ -288,12 +253,11 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
Vector<Transform3D> silhouette_diff; // Transform values to be ignored when overwrite axis.
silhouette_diff.resize(src_skeleton->get_bone_count());
Transform3D *silhouette_diff_w = silhouette_diff.ptrw();
+ LocalVector<Transform3D> pre_silhouette_skeleton_global_rest;
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ pre_silhouette_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
+ }
if (bool(p_options["retarget/rest_fixer/fix_silhouette/enable"])) {
- LocalVector<Transform3D> old_skeleton_global_rest;
- for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
- old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
- }
-
Vector<int> bones_to_process = prof_skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
int prof_idx = bones_to_process[0];
@@ -450,7 +414,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
// For skin modification in overwrite rest.
for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
- silhouette_diff_w[i] = old_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).inverse();
+ silhouette_diff_w[i] = pre_silhouette_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).affine_inverse();
}
is_rest_changed = true;
@@ -645,14 +609,20 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
if (is_rest_changed) {
// Fix skin.
{
+ HashSet<Ref<Skin>> mutated_skins;
TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D");
- int skin_idx = 0;
while (nodes.size()) {
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back());
ERR_CONTINUE(!mi);
Ref<Skin> skin = mi->get_skin();
- ERR_CONTINUE(!skin.is_valid());
+ if (skin.is_null()) {
+ continue;
+ }
+ if (mutated_skins.has(skin)) {
+ continue;
+ }
+ mutated_skins.insert(skin);
Node *node = mi->get_node(mi->get_skeleton_path());
ERR_CONTINUE(!node);
@@ -662,19 +632,39 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
continue;
}
- Vector<Transform3D> ibm_diff = ibm_diffs[skin_idx];
-
int skin_len = skin->get_bind_count();
for (int i = 0; i < skin_len; i++) {
StringName bn = skin->get_bind_name(i);
int bone_idx = src_skeleton->find_bone(bn);
if (bone_idx >= 0) {
- Transform3D new_rest = silhouette_diff[bone_idx] * src_skeleton->get_bone_global_rest(bone_idx);
- skin->set_bind_pose(i, new_rest.inverse() * ibm_diff[bone_idx]);
+ Transform3D adjust_transform = src_skeleton->get_bone_global_rest(bone_idx).affine_inverse() * silhouette_diff[bone_idx].affine_inverse() * pre_silhouette_skeleton_global_rest[bone_idx];
+ adjust_transform.scale(global_transform.basis.get_scale_local());
+ skin->set_bind_pose(i, adjust_transform * skin->get_bind_pose(i));
}
}
-
- skin_idx++;
+ }
+ nodes = src_skeleton->get_children();
+ while (nodes.size()) {
+ BoneAttachment3D *attachment = Object::cast_to<BoneAttachment3D>(nodes.pop_back());
+ if (attachment == nullptr) {
+ continue;
+ }
+ int bone_idx = attachment->get_bone_idx();
+ if (bone_idx == -1) {
+ bone_idx = src_skeleton->find_bone(attachment->get_bone_name());
+ }
+ ERR_CONTINUE(bone_idx < 0 || bone_idx >= src_skeleton->get_bone_count());
+ Transform3D adjust_transform = src_skeleton->get_bone_global_rest(bone_idx).affine_inverse() * silhouette_diff[bone_idx].affine_inverse() * pre_silhouette_skeleton_global_rest[bone_idx];
+ adjust_transform.scale(global_transform.basis.get_scale_local());
+
+ TypedArray<Node> child_nodes = attachment->get_children();
+ while (child_nodes.size()) {
+ Node3D *child = Object::cast_to<Node3D>(child_nodes.pop_back());
+ if (child == nullptr) {
+ continue;
+ }
+ child->set_transform(adjust_transform * child->get_transform());
+ }
}
}
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index c05e7582eb..b4fee00c1d 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -407,6 +407,20 @@ void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String
save_to_ctex_format(f, image, p_compress_mode, used_channels, p_vram_compression, p_lossy_quality);
}
+void ResourceImporterTexture::_save_editor_meta(const Dictionary &p_metadata, const String &p_to_path) {
+ Ref<FileAccess> f = FileAccess::open(p_to_path, FileAccess::WRITE);
+ ERR_FAIL_COND(f.is_null());
+
+ f->store_var(p_metadata);
+}
+
+Dictionary ResourceImporterTexture::_load_editor_meta(const String &p_path) const {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V_MSG(f.is_null(), Dictionary(), "Missing required editor-specific import metadata for a texture; please, reimport.");
+
+ return f->get_var();
+}
+
Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
// Parse import options.
int32_t loader_flags = ImageFormatLoader::FLAG_NONE;
@@ -667,6 +681,18 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
if (editor_image.is_valid()) {
_save_ctex(editor_image, p_save_path + ".editor.ctex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+
+ // Generate and save editor-specific metadata, which we cannot save to the .import file.
+ Dictionary editor_meta;
+
+ if (use_editor_scale) {
+ editor_meta["editor_scale"] = EDSCALE;
+ }
+ if (convert_editor_colors) {
+ editor_meta["editor_dark_theme"] = EditorSettings::get_singleton()->is_dark_theme();
+ }
+
+ _save_editor_meta(editor_meta, p_save_path + ".editor.meta");
}
if (r_metadata) {
@@ -678,16 +704,11 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
if (editor_image.is_valid()) {
meta["has_editor_variant"] = true;
- if (use_editor_scale) {
- meta["editor_scale"] = EDSCALE;
- }
- if (convert_editor_colors) {
- meta["editor_dark_theme"] = EditorSettings::get_singleton()->is_dark_theme();
- }
}
*r_metadata = meta;
}
+
return OK;
}
@@ -713,14 +734,17 @@ String ResourceImporterTexture::get_import_settings_string() const {
}
bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const {
- //will become invalid if formats are missing to import
Dictionary meta = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path);
if (meta.has("has_editor_variant")) {
- if (meta.has("editor_scale") && (float)meta["editor_scale"] != EDSCALE) {
+ String imported_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_path);
+ String editor_meta_path = imported_path.replace(".editor.ctex", ".editor.meta");
+ Dictionary editor_meta = _load_editor_meta(editor_meta_path);
+
+ if (editor_meta.has("editor_scale") && (float)editor_meta["editor_scale"] != EDSCALE) {
return false;
}
- if (meta.has("editor_dark_theme") && (bool)meta["editor_dark_theme"] != EditorSettings::get_singleton()->is_dark_theme()) {
+ if (editor_meta.has("editor_dark_theme") && (bool)editor_meta["editor_dark_theme"] != EditorSettings::get_singleton()->is_dark_theme()) {
return false;
}
}
@@ -734,6 +758,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
return true; // Do not care about non-VRAM.
}
+ // Will become invalid if formats are missing to import.
Vector<String> formats_imported;
if (meta.has("imported_formats")) {
formats_imported = meta["imported_formats"];
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index 86d4dd7e35..c2bdbb6fa2 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -75,6 +75,8 @@ protected:
static const char *compression_formats[];
void _save_ctex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel);
+ void _save_editor_meta(const Dictionary &p_metadata, const String &p_to_path);
+ Dictionary _load_editor_meta(const String &p_to_path) const;
public:
static void save_to_ctex_format(Ref<FileAccess> f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality);
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 9dff5127ae..ea210872f7 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -1109,6 +1109,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
add_options.push_back(AddOption("Add3", "AnimationNodeAdd3", 3));
add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2", 2));
add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3", 3));
+ add_options.push_back(AddOption("Sub2", "AnimationNodeSub2", 2));
add_options.push_back(AddOption("TimeSeek", "AnimationNodeTimeSeek", 1));
add_options.push_back(AddOption("TimeScale", "AnimationNodeTimeScale", 1));
add_options.push_back(AddOption("Transition", "AnimationNodeTransition"));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 368c81a0f4..dcf3dc5b1b 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4587,7 +4587,11 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SKELETON_MAKE_BONES: {
HashMap<Node *, Object *> &selection = editor_selection->get_selection();
- Node *editor_root = EditorNode::get_singleton()->get_edited_scene()->get_tree()->get_edited_scene_root();
+ Node *editor_root = get_tree()->get_edited_scene_root();
+
+ if (!editor_root || selection.is_empty()) {
+ return;
+ }
undo_redo->create_action(TTR("Create Custom Bone2D(s) from Node(s)"));
for (const KeyValue<Node *, Object *> &E : selection) {
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index 3bf2b95c26..d7c4686bbf 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -164,7 +164,7 @@ void EditorPropertyAnchorsPreset::_option_selected(int p_which) {
}
void EditorPropertyAnchorsPreset::update_property() {
- int64_t which = get_edited_object()->get(get_edited_property());
+ int64_t which = get_edited_property_value();
for (int i = 0; i < options->get_item_count(); i++) {
Variant val = options->get_item_metadata(i);
@@ -255,7 +255,7 @@ void EditorPropertySizeFlags::_preset_selected(int p_which) {
}
void EditorPropertySizeFlags::_expand_toggled() {
- uint32_t value = get_edited_object()->get(get_edited_property());
+ uint32_t value = get_edited_property_value();
if (flag_expand->is_visible() && flag_expand->is_pressed()) {
value |= Control::SIZE_EXPAND;
@@ -288,7 +288,7 @@ void EditorPropertySizeFlags::_flag_toggled() {
}
void EditorPropertySizeFlags::update_property() {
- uint32_t value = get_edited_object()->get(get_edited_property());
+ uint32_t value = get_edited_property_value();
for (int i = 0; i < flag_checks.size(); i++) {
int flag_value = flag_checks[i]->get_meta("_value");
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 7c87f009a6..1e5e15f6ae 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -33,276 +33,358 @@
#include "canvas_item_editor_plugin.h"
#include "core/core_string_names.h"
#include "core/input/input.h"
+#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/gui/editor_spin_slider.h"
+#include "scene/gui/flow_container.h"
+#include "scene/gui/menu_button.h"
#include "scene/gui/popup_menu.h"
+#include "scene/gui/separator.h"
-CurveEditor::CurveEditor() {
- _selected_point = -1;
- _hover_point = -1;
- _selected_tangent = TANGENT_NONE;
- _hover_radius = 6;
- _tangents_length = 40;
- _dragging = false;
- _has_undo_data = false;
- _gizmo_handle_scale = EDITOR_GET("interface/touchscreen/scale_gizmo_handles");
-
+CurveEdit::CurveEdit() {
set_focus_mode(FOCUS_ALL);
set_clip_contents(true);
+}
- _context_menu = memnew(PopupMenu);
- _context_menu->connect("id_pressed", callable_mp(this, &CurveEditor::on_context_menu_item_selected));
- add_child(_context_menu);
+void CurveEdit::_on_mouse_exited() {
+ hovered_index = -1;
+ hovered_tangent_index = TANGENT_NONE;
+ queue_redraw();
+}
- _presets_menu = memnew(PopupMenu);
- _presets_menu->set_name("_presets_menu");
- _presets_menu->add_item(TTR("Flat 0"), PRESET_FLAT0);
- _presets_menu->add_item(TTR("Flat 1"), PRESET_FLAT1);
- _presets_menu->add_item(TTR("Linear"), PRESET_LINEAR);
- _presets_menu->add_item(TTR("Ease In"), PRESET_EASE_IN);
- _presets_menu->add_item(TTR("Ease Out"), PRESET_EASE_OUT);
- _presets_menu->add_item(TTR("Smoothstep"), PRESET_SMOOTHSTEP);
- _presets_menu->connect("id_pressed", callable_mp(this, &CurveEditor::on_preset_item_selected));
- _context_menu->add_child(_presets_menu);
+void CurveEdit::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_selected_index", "index"), &CurveEdit::set_selected_index);
}
-void CurveEditor::set_curve(Ref<Curve> curve) {
- if (curve == _curve_ref) {
+void CurveEdit::set_curve(Ref<Curve> p_curve) {
+ if (p_curve == curve) {
return;
}
- if (_curve_ref.is_valid()) {
- _curve_ref->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveEditor::_curve_changed));
- _curve_ref->disconnect(Curve::SIGNAL_RANGE_CHANGED, callable_mp(this, &CurveEditor::_curve_changed));
+ if (curve.is_valid()) {
+ curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveEdit::_curve_changed));
+ curve->disconnect(Curve::SIGNAL_RANGE_CHANGED, callable_mp(this, &CurveEdit::_curve_changed));
}
- _curve_ref = curve;
+ curve = p_curve;
- if (_curve_ref.is_valid()) {
- _curve_ref->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveEditor::_curve_changed));
- _curve_ref->connect(Curve::SIGNAL_RANGE_CHANGED, callable_mp(this, &CurveEditor::_curve_changed));
+ if (curve.is_valid()) {
+ curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveEdit::_curve_changed));
+ curve->connect(Curve::SIGNAL_RANGE_CHANGED, callable_mp(this, &CurveEdit::_curve_changed));
}
- _selected_point = -1;
- _hover_point = -1;
- _selected_tangent = TANGENT_NONE;
+ // Note: if you edit a curve, then set another, and try to undo,
+ // it will normally apply on the previous curve, but you won't see it.
+}
+Ref<Curve> CurveEdit::get_curve() {
+ return curve;
+}
+
+void CurveEdit::set_snap_enabled(bool p_enabled) {
+ snap_enabled = p_enabled;
queue_redraw();
+ if (curve.is_valid()) {
+ if (snap_enabled) {
+ curve->set_meta(SNAME("_snap_enabled"), true);
+ } else {
+ curve->remove_meta(SNAME("_snap_enabled"));
+ }
+ }
+}
- // Note: if you edit a curve, then set another, and try to undo,
- // it will normally apply on the previous curve, but you won't see it
+void CurveEdit::set_snap_count(int p_snap_count) {
+ snap_count = p_snap_count;
+ queue_redraw();
+ if (curve.is_valid()) {
+ if (snap_count != CurveEditor::DEFAULT_SNAP) {
+ curve->set_meta(SNAME("_snap_count"), snap_count);
+ } else {
+ curve->remove_meta(SNAME("_snap_count"));
+ }
+ }
}
-Size2 CurveEditor::get_minimum_size() const {
- return Vector2(64, 150) * EDSCALE;
+Size2 CurveEdit::get_minimum_size() const {
+ return Vector2(64, 135) * EDSCALE;
}
-void CurveEditor::_notification(int p_what) {
+void CurveEdit::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_DRAW: {
- _draw();
+ case NOTIFICATION_ENTER_TREE: {
+ connect("mouse_exited", callable_mp(this, &CurveEdit::_on_mouse_exited));
} break;
+ case NOTIFICATION_THEME_CHANGED:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/touchscreen/scale_gizmo_handles")) {
- _gizmo_handle_scale = EDITOR_GET("interface/touchscreen/scale_gizmo_handles");
+ float gizmo_scale = EDITOR_GET("interface/touchscreen/scale_gizmo_handles");
+ point_radius = Math::round(BASE_POINT_RADIUS * get_theme_default_base_scale() * gizmo_scale);
+ hover_radius = Math::round(BASE_HOVER_RADIUS * get_theme_default_base_scale() * gizmo_scale);
+ tangent_radius = Math::round(BASE_TANGENT_RADIUS * get_theme_default_base_scale() * gizmo_scale);
+ tangent_hover_radius = Math::round(BASE_TANGENT_HOVER_RADIUS * get_theme_default_base_scale() * gizmo_scale);
+ tangent_length = Math::round(BASE_TANGENT_LENGTH * get_theme_default_base_scale());
+ } break;
+ case NOTIFICATION_DRAW: {
+ _redraw();
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (!is_visible()) {
+ grabbing = GRAB_NONE;
}
} break;
}
}
-void CurveEditor::gui_input(const Ref<InputEvent> &p_event) {
- Ref<InputEventMouseButton> mb_ref = p_event;
- if (mb_ref.is_valid()) {
- const InputEventMouseButton &mb = **mb_ref;
+void CurveEdit::gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid()) {
+ // Deleting points or making tangents linear.
+ if (k->is_pressed() && k->get_keycode() == Key::KEY_DELETE) {
+ if (selected_tangent_index != TANGENT_NONE) {
+ toggle_linear(selected_index, selected_tangent_index);
+ } else if (selected_index != -1) {
+ if (grabbing == GRAB_ADD) {
+ curve->remove_point(selected_index); // Point is temporary, so remove directly from curve.
+ set_selected_index(-1);
+ } else {
+ remove_point(selected_index);
+ }
+ grabbing = GRAB_NONE;
+ hovered_index = -1;
+ hovered_tangent_index = TANGENT_NONE;
+ }
+ accept_event();
+ }
- if (mb.is_pressed() && !_dragging) {
- Vector2 mpos = mb.get_position();
+ if (k->get_keycode() == Key::SHIFT || k->get_keycode() == Key::ALT) {
+ queue_redraw(); // Redraw to show the axes or constraints.
+ }
+ }
- _selected_tangent = get_tangent_at(mpos);
- if (_selected_tangent == TANGENT_NONE) {
- set_selected_point(get_point_at(mpos));
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->is_pressed()) {
+ Vector2 mpos = mb->get_position();
+
+ if (mb->get_button_index() == MouseButton::RIGHT || mb->get_button_index() == MouseButton::MIDDLE) {
+ if (mb->get_button_index() == MouseButton::RIGHT && grabbing == GRAB_MOVE) {
+ // Move a point to its old position.
+ curve->set_point_value(selected_index, initial_grab_pos.y);
+ curve->set_point_offset(selected_index, initial_grab_pos.x);
+ set_selected_index(initial_grab_index);
+ hovered_index = get_point_at(mpos);
+ grabbing = GRAB_NONE;
+ } else {
+ // Remove a point or make a tangent linear.
+ selected_tangent_index = get_tangent_at(mpos);
+ if (selected_tangent_index != TANGENT_NONE) {
+ toggle_linear(selected_index, selected_tangent_index);
+ } else {
+ int point_to_remove = get_point_at(mpos);
+ if (point_to_remove != -1) {
+ if (grabbing == GRAB_ADD) {
+ curve->remove_point(point_to_remove); // Point is temporary, so remove directly from curve.
+ set_selected_index(-1);
+ } else {
+ remove_point(point_to_remove);
+ }
+ hovered_index = get_point_at(mpos);
+ grabbing = GRAB_NONE;
+ }
+ }
}
+ }
- switch (mb.get_button_index()) {
- case MouseButton::RIGHT:
- _context_click_pos = mpos;
- open_context_menu(get_screen_position() + mpos);
- break;
-
- case MouseButton::MIDDLE:
- remove_point(_hover_point);
- break;
-
- case MouseButton::LEFT:
- _dragging = true;
- break;
- default:
- break;
+ // Selecting or creating points.
+ if (mb->get_button_index() == MouseButton::LEFT) {
+ if (grabbing == GRAB_NONE) {
+ selected_tangent_index = get_tangent_at(mpos);
+ if (selected_tangent_index == TANGENT_NONE) {
+ set_selected_index(get_point_at(mpos));
+ }
+ queue_redraw();
}
- }
- if (!mb.is_pressed() && _dragging && mb.get_button_index() == MouseButton::LEFT) {
- _dragging = false;
- if (_has_undo_data) {
- EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent"));
- undo_redo->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data());
- undo_redo->add_undo_method(*_curve_ref, "_set_data", _undo_data);
- // Note: this will trigger one more "changed" signal even if nothing changes,
- // but it's ok since it would have fired every frame during the drag anyways
- undo_redo->commit_action();
-
- _has_undo_data = false;
+ if (selected_index != -1) {
+ // If an existing point/tangent was grabbed, remember a few things about it.
+ grabbing = GRAB_MOVE;
+ initial_grab_pos = curve->get_point_position(selected_index);
+ initial_grab_index = selected_index;
+ if (selected_index > 0) {
+ initial_grab_left_tangent = curve->get_point_left_tangent(selected_index);
+ }
+ if (selected_index < curve->get_point_count() - 1) {
+ initial_grab_right_tangent = curve->get_point_right_tangent(selected_index);
+ }
+ } else if (grabbing == GRAB_NONE) {
+ // Adding a new point. Insert a temporary point for the user to adjust, so it's not in the undo/redo.
+ Vector2 new_pos = get_world_pos(mpos).clamp(Vector2(0.0, curve->get_min_value()), Vector2(1.0, curve->get_max_value()));
+ if (snap_enabled || mb->is_ctrl_pressed()) {
+ new_pos.x = Math::snapped(new_pos.x, 1.0 / snap_count);
+ new_pos.y = Math::snapped(new_pos.y - curve->get_min_value(), curve->get_range() / snap_count) + curve->get_min_value();
+ }
+
+ new_pos.x = get_offset_without_collision(selected_index, new_pos.x, mpos.x >= get_view_pos(new_pos).x);
+
+ // Add a temporary point for the user to adjust before adding it permanently.
+ int new_idx = curve->add_point_no_update(new_pos);
+ set_selected_index(new_idx);
+ grabbing = GRAB_ADD;
+ initial_grab_pos = new_pos;
}
}
}
- Ref<InputEventMouseMotion> mm_ref = p_event;
- if (mm_ref.is_valid()) {
- const InputEventMouseMotion &mm = **mm_ref;
-
- Vector2 mpos = mm.get_position();
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) {
+ if (selected_tangent_index != TANGENT_NONE) {
+ // Finish moving a tangent control.
+ if (selected_index == 0) {
+ set_point_right_tangent(selected_index, curve->get_point_right_tangent(selected_index));
+ } else if (selected_index == curve->get_point_count() - 1) {
+ set_point_left_tangent(selected_index, curve->get_point_left_tangent(selected_index));
+ } else {
+ set_point_tangents(selected_index, curve->get_point_left_tangent(selected_index), curve->get_point_right_tangent(selected_index));
+ }
+ grabbing = GRAB_NONE;
+ } else if (grabbing == GRAB_MOVE) {
+ // Finish moving a point.
+ set_point_position(selected_index, curve->get_point_position(selected_index));
+ grabbing = GRAB_NONE;
+ } else if (grabbing == GRAB_ADD) {
+ // Finish inserting a new point. Remove the temporary point and insert a permanent one in its place.
+ Vector2 new_pos = curve->get_point_position(selected_index);
+ curve->remove_point(selected_index);
+ add_point(new_pos);
+ grabbing = GRAB_NONE;
+ }
+ queue_redraw();
+ }
- if (_dragging && _curve_ref.is_valid()) {
- if (_selected_point != -1) {
- Curve &curve = **_curve_ref;
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ Vector2 mpos = mm->get_position();
- if (!_has_undo_data) {
- // Save full curve state before dragging points,
- // because this operation can modify their order
- _undo_data = curve.get_data();
- _has_undo_data = true;
- }
+ if (grabbing != GRAB_NONE && curve.is_valid()) {
+ if (selected_index != -1) {
+ if (selected_tangent_index == TANGENT_NONE) {
+ // Drag point.
+ Vector2 new_pos = get_world_pos(mpos).clamp(Vector2(0.0, curve->get_min_value()), Vector2(1.0, curve->get_max_value()));
- const float curve_amplitude = curve.get_max_value() - curve.get_min_value();
- // Snap to "round" coordinates when holding Ctrl.
- // Be more precise when holding Shift as well.
- float snap_threshold;
- if (mm.is_ctrl_pressed()) {
- snap_threshold = mm.is_shift_pressed() ? 0.025 : 0.1;
- } else {
- snap_threshold = 0.0;
- }
+ if (snap_enabled || mm->is_ctrl_pressed()) {
+ new_pos.x = Math::snapped(new_pos.x, 1.0 / snap_count);
+ new_pos.y = Math::snapped(new_pos.y - curve->get_min_value(), curve->get_range() / snap_count) + curve->get_min_value();
+ }
- if (_selected_tangent == TANGENT_NONE) {
- // Drag point
+ // Allow to snap to axes with Shift.
+ if (mm->is_shift_pressed()) {
+ Vector2 initial_mpos = get_view_pos(initial_grab_pos);
+ if (Math::abs(mpos.x - initial_mpos.x) > Math::abs(mpos.y - initial_mpos.y)) {
+ new_pos.y = initial_grab_pos.y;
+ } else {
+ new_pos.x = initial_grab_pos.x;
+ }
+ }
- Vector2 point_pos = get_world_pos(mpos).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude));
+ // Allow to constraint the point between the adjacent two with Alt.
+ if (mm->is_alt_pressed()) {
+ float prev_point_offset = (selected_index > 0) ? (curve->get_point_position(selected_index - 1).x + 0.00001) : 0.0;
+ float next_point_offset = (selected_index < curve->get_point_count() - 1) ? (curve->get_point_position(selected_index + 1).x - 0.00001) : 1.0;
+ new_pos.x = CLAMP(new_pos.x, prev_point_offset, next_point_offset);
+ }
- int i = curve.set_point_offset(_selected_point, point_pos.x);
- // The index may change if the point is dragged across another one
- set_hover_point_index(i);
- set_selected_point(i);
+ new_pos.x = get_offset_without_collision(selected_index, new_pos.x, mpos.x >= get_view_pos(new_pos).x);
- // This is to prevent the user from losing a point out of view.
- if (point_pos.y < curve.get_min_value()) {
- point_pos.y = curve.get_min_value();
- } else if (point_pos.y > curve.get_max_value()) {
- point_pos.y = curve.get_max_value();
- }
+ // The index may change if the point is dragged across another one.
+ int i = curve->set_point_offset(selected_index, new_pos.x);
+ hovered_index = i;
+ set_selected_index(i);
- curve.set_point_value(_selected_point, point_pos.y);
+ new_pos.y = CLAMP(new_pos.y, curve->get_min_value(), curve->get_max_value());
+ curve->set_point_value(selected_index, new_pos.y);
} else {
- // Drag tangent
-
- const Vector2 point_pos = curve.get_point_position(_selected_point);
- const Vector2 control_pos = get_world_pos(mpos).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude));
+ // Drag tangent.
- Vector2 dir = (control_pos - point_pos).normalized();
+ const Vector2 new_pos = curve->get_point_position(selected_index);
+ const Vector2 control_pos = get_world_pos(mpos);
- real_t tangent;
- if (!Math::is_zero_approx(dir.x)) {
- tangent = dir.y / dir.x;
- } else {
- tangent = 9999 * (dir.y >= 0 ? 1 : -1);
- }
+ Vector2 dir = (control_pos - new_pos).normalized();
+ real_t tangent = dir.y / (dir.x > 0 ? MAX(dir.x, 0.00001) : MIN(dir.x, -0.00001));
- bool link = !Input::get_singleton()->is_key_pressed(Key::SHIFT);
+ // Must keep track of the hovered index as the cursor might move outside of the editor while dragging.
+ hovered_tangent_index = selected_tangent_index;
- if (_selected_tangent == TANGENT_LEFT) {
- curve.set_point_left_tangent(_selected_point, tangent);
+ // Adjust the tangents.
+ if (selected_tangent_index == TANGENT_LEFT) {
+ curve->set_point_left_tangent(selected_index, tangent);
- // Note: if a tangent is set to linear, it shouldn't be linked to the other
- if (link && _selected_point != (curve.get_point_count() - 1) && curve.get_point_right_mode(_selected_point) != Curve::TANGENT_LINEAR) {
- curve.set_point_right_tangent(_selected_point, tangent);
+ // Align the other tangent if it isn't linear and Shift is not pressed.
+ // If Shift is pressed at any point, restore the initial angle of the other tangent.
+ if (selected_index != (curve->get_point_count() - 1) && curve->get_point_right_mode(selected_index) != Curve::TANGENT_LINEAR) {
+ curve->set_point_right_tangent(selected_index, mm->is_shift_pressed() ? initial_grab_right_tangent : tangent);
}
} else {
- curve.set_point_right_tangent(_selected_point, tangent);
+ curve->set_point_right_tangent(selected_index, tangent);
- if (link && _selected_point != 0 && curve.get_point_left_mode(_selected_point) != Curve::TANGENT_LINEAR) {
- curve.set_point_left_tangent(_selected_point, tangent);
+ if (selected_index != 0 && curve->get_point_left_mode(selected_index) != Curve::TANGENT_LINEAR) {
+ curve->set_point_left_tangent(selected_index, mm->is_shift_pressed() ? initial_grab_left_tangent : tangent);
}
}
}
}
-
} else {
- set_hover_point_index(get_point_at(mpos));
- }
- }
-
- Ref<InputEventKey> key_ref = p_event;
- if (key_ref.is_valid()) {
- const InputEventKey &key = **key_ref;
-
- if (key.is_pressed() && _selected_point != -1) {
- if (key.get_keycode() == Key::KEY_DELETE) {
- remove_point(_selected_point);
- }
+ // Grab mode is GRAB_NONE, so do hovering logic.
+ hovered_index = get_point_at(mpos);
+ hovered_tangent_index = get_tangent_at(mpos);
+ queue_redraw();
}
}
}
-void CurveEditor::on_preset_item_selected(int preset_id) {
- ERR_FAIL_COND(preset_id < 0 || preset_id >= PRESET_COUNT);
- ERR_FAIL_COND(_curve_ref.is_null());
+void CurveEdit::use_preset(int p_preset_id) {
+ ERR_FAIL_COND(p_preset_id < 0 || p_preset_id >= PRESET_COUNT);
+ ERR_FAIL_COND(curve.is_null());
- Curve &curve = **_curve_ref;
- Array previous_data = curve.get_data();
+ Array previous_data = curve->get_data();
+ curve->clear_points();
- curve.clear_points();
+ float min_value = curve->get_min_value();
+ float max_value = curve->get_max_value();
- switch (preset_id) {
- case PRESET_FLAT0:
- curve.add_point(Vector2(0, 0));
- curve.add_point(Vector2(1, 0));
- curve.set_point_right_mode(0, Curve::TANGENT_LINEAR);
- curve.set_point_left_mode(1, Curve::TANGENT_LINEAR);
- break;
-
- case PRESET_FLAT1:
- curve.add_point(Vector2(0, 1));
- curve.add_point(Vector2(1, 1));
- curve.set_point_right_mode(0, Curve::TANGENT_LINEAR);
- curve.set_point_left_mode(1, Curve::TANGENT_LINEAR);
+ switch (p_preset_id) {
+ case PRESET_CONSTANT:
+ curve->add_point(Vector2(0, (min_value + max_value) / 2.0));
+ curve->add_point(Vector2(1, (min_value + max_value) / 2.0));
+ curve->set_point_right_mode(0, Curve::TANGENT_LINEAR);
+ curve->set_point_left_mode(1, Curve::TANGENT_LINEAR);
break;
case PRESET_LINEAR:
- curve.add_point(Vector2(0, 0));
- curve.add_point(Vector2(1, 1));
- curve.set_point_right_mode(0, Curve::TANGENT_LINEAR);
- curve.set_point_left_mode(1, Curve::TANGENT_LINEAR);
+ curve->add_point(Vector2(0, min_value));
+ curve->add_point(Vector2(1, max_value));
+ curve->set_point_right_mode(0, Curve::TANGENT_LINEAR);
+ curve->set_point_left_mode(1, Curve::TANGENT_LINEAR);
break;
case PRESET_EASE_IN:
- curve.add_point(Vector2(0, 0));
- curve.add_point(Vector2(1, 1), (curve.get_max_value() - curve.get_min_value()) * 1.4, 0);
+ curve->add_point(Vector2(0, min_value));
+ curve->add_point(Vector2(1, max_value), curve->get_range() * 1.4, 0);
break;
case PRESET_EASE_OUT:
- curve.add_point(Vector2(0, 0), 0, (curve.get_max_value() - curve.get_min_value()) * 1.4);
- curve.add_point(Vector2(1, 1));
+ curve->add_point(Vector2(0, min_value), 0, curve->get_range() * 1.4);
+ curve->add_point(Vector2(1, max_value));
break;
case PRESET_SMOOTHSTEP:
- curve.add_point(Vector2(0, 0));
- curve.add_point(Vector2(1, 1));
+ curve->add_point(Vector2(0, min_value));
+ curve->add_point(Vector2(1, max_value));
break;
default:
@@ -311,236 +393,269 @@ void CurveEditor::on_preset_item_selected(int preset_id) {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Load Curve Preset"));
- undo_redo->add_do_method(&curve, "_set_data", curve.get_data());
- undo_redo->add_undo_method(&curve, "_set_data", previous_data);
+ undo_redo->add_do_method(*curve, "_set_data", curve->get_data());
+ undo_redo->add_do_method(this, "set_selected_index", -1);
+ undo_redo->add_undo_method(*curve, "_set_data", previous_data);
+ undo_redo->add_undo_method(this, "set_selected_index", selected_index);
undo_redo->commit_action();
}
-void CurveEditor::_curve_changed() {
+void CurveEdit::_curve_changed() {
queue_redraw();
- // Point count can change in case of undo
- if (_selected_point >= _curve_ref->get_point_count()) {
- set_selected_point(-1);
+ // Point count can change in case of undo.
+ if (selected_index >= curve->get_point_count()) {
+ set_selected_index(-1);
}
}
-void CurveEditor::on_context_menu_item_selected(int action_id) {
- switch (action_id) {
- case CONTEXT_ADD_POINT:
- add_point(_context_click_pos);
- break;
-
- case CONTEXT_REMOVE_POINT:
- remove_point(_selected_point);
- break;
-
- case CONTEXT_LINEAR:
- toggle_linear();
- break;
+int CurveEdit::get_point_at(Vector2 p_pos) const {
+ if (curve.is_null()) {
+ return -1;
+ }
- case CONTEXT_LEFT_LINEAR:
- toggle_linear(TANGENT_LEFT);
- break;
+ // Use a square-shaped hover region. If hovering multiple points, pick the closer one.
+ const Rect2 hover_rect = Rect2(p_pos, Vector2(0, 0)).grow(hover_radius);
+ int closest_idx = -1;
+ float closest_dist_squared = hover_radius * hover_radius * 2;
- case CONTEXT_RIGHT_LINEAR:
- toggle_linear(TANGENT_RIGHT);
- break;
+ for (int i = 0; i < curve->get_point_count(); ++i) {
+ Vector2 p = get_view_pos(curve->get_point_position(i));
+ if (hover_rect.has_point(p) && p.distance_squared_to(p_pos) < closest_dist_squared) {
+ closest_dist_squared = p.distance_squared_to(p_pos);
+ closest_idx = i;
+ }
}
-}
-void CurveEditor::open_context_menu(Vector2 pos) {
- _context_menu->set_position(pos);
+ return closest_idx;
+}
- _context_menu->clear();
+CurveEdit::TangentIndex CurveEdit::get_tangent_at(Vector2 p_pos) const {
+ if (curve.is_null() || selected_index < 0) {
+ return TANGENT_NONE;
+ }
- if (_curve_ref.is_valid()) {
- _context_menu->add_item(TTR("Add Point"), CONTEXT_ADD_POINT);
+ const Rect2 hover_rect = Rect2(p_pos, Vector2(0, 0)).grow(tangent_hover_radius);
- if (_selected_point >= 0) {
- _context_menu->add_item(TTR("Remove Point"), CONTEXT_REMOVE_POINT);
+ if (selected_index != 0) {
+ Vector2 control_pos = get_tangent_view_pos(selected_index, TANGENT_LEFT);
+ if (hover_rect.has_point(control_pos)) {
+ return TANGENT_LEFT;
+ }
+ }
- if (_selected_tangent != TANGENT_NONE) {
- _context_menu->add_separator();
+ if (selected_index != curve->get_point_count() - 1) {
+ Vector2 control_pos = get_tangent_view_pos(selected_index, TANGENT_RIGHT);
+ if (hover_rect.has_point(control_pos)) {
+ return TANGENT_RIGHT;
+ }
+ }
- _context_menu->add_check_item(TTR("Linear"), CONTEXT_LINEAR);
+ return TANGENT_NONE;
+}
- bool is_linear = _selected_tangent == TANGENT_LEFT
- ? _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR
- : _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
+// FIXME: This function should be bounded better.
+float CurveEdit::get_offset_without_collision(int p_current_index, float p_offset, bool p_prioritize_right) {
+ float safe_offset = p_offset;
+ bool prioritizing_right = p_prioritize_right;
- _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear);
+ for (int i = 0; i < curve->get_point_count(); i++) {
+ if (i == p_current_index) {
+ continue;
+ }
- } else {
- if (_selected_point > 0 || _selected_point + 1 < _curve_ref->get_point_count()) {
- _context_menu->add_separator();
- }
+ if (curve->get_point_position(i).x > safe_offset) {
+ break;
+ }
- if (_selected_point > 0) {
- _context_menu->add_check_item(TTR("Left Linear"), CONTEXT_LEFT_LINEAR);
- _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LEFT_LINEAR),
- _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR);
+ if (curve->get_point_position(i).x == safe_offset) {
+ if (prioritizing_right) {
+ safe_offset += 0.00001;
+ if (safe_offset > 1.0) {
+ safe_offset = 1.0;
+ prioritizing_right = false;
}
- if (_selected_point + 1 < _curve_ref->get_point_count()) {
- _context_menu->add_check_item(TTR("Right Linear"), CONTEXT_RIGHT_LINEAR);
- _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_RIGHT_LINEAR),
- _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR);
+ } else {
+ safe_offset -= 0.00001;
+ if (safe_offset < 0.0) {
+ safe_offset = 0.0;
+ prioritizing_right = true;
}
}
+ i = -1;
}
-
- _context_menu->add_separator();
}
- _context_menu->add_submenu_item(TTR("Load Preset"), _presets_menu->get_name());
-
- _context_menu->reset_size();
- _context_menu->popup();
+ return safe_offset;
}
-int CurveEditor::get_point_at(Vector2 pos) const {
- if (_curve_ref.is_null()) {
- return -1;
- }
- const Curve &curve = **_curve_ref;
-
- const float true_hover_radius = Math::round(_hover_radius * _gizmo_handle_scale * EDSCALE);
- const float r = true_hover_radius * true_hover_radius;
+void CurveEdit::add_point(Vector2 p_pos) {
+ ERR_FAIL_COND(curve.is_null());
- for (int i = 0; i < curve.get_point_count(); ++i) {
- Vector2 p = get_view_pos(curve.get_point_position(i));
- if (p.distance_squared_to(pos) <= r) {
- return i;
- }
- }
+ // Add a point to get its index, then remove it immediately. Trick to feed the UndoRedo.
+ int new_idx = curve->add_point(p_pos);
+ curve->remove_point(new_idx);
- return -1;
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Add Curve Point"));
+ undo_redo->add_do_method(*curve, "add_point", p_pos);
+ undo_redo->add_do_method(this, "set_selected_index", new_idx);
+ undo_redo->add_undo_method(*curve, "remove_point", new_idx);
+ undo_redo->add_undo_method(this, "set_selected_index", -1);
+ undo_redo->commit_action();
}
-CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const {
- if (_curve_ref.is_null() || _selected_point < 0) {
- return TANGENT_NONE;
- }
+void CurveEdit::remove_point(int p_index) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- if (_selected_point != 0) {
- Vector2 control_pos = get_tangent_view_pos(_selected_point, TANGENT_LEFT);
- if (control_pos.distance_to(pos) < _hover_radius * _gizmo_handle_scale) {
- return TANGENT_LEFT;
- }
- }
+ Curve::Point p = curve->get_point(p_index);
+ Vector2 old_pos = (grabbing == GRAB_MOVE) ? initial_grab_pos : p.position;
- if (_selected_point != _curve_ref->get_point_count() - 1) {
- Vector2 control_pos = get_tangent_view_pos(_selected_point, TANGENT_RIGHT);
- if (control_pos.distance_to(pos) < _hover_radius * _gizmo_handle_scale) {
- return TANGENT_RIGHT;
- }
+ int new_selected_index = selected_index;
+ // Reselect the old selected point if it's not the deleted one.
+ if (new_selected_index > p_index) {
+ new_selected_index -= 1;
+ } else if (new_selected_index == p_index) {
+ new_selected_index = -1;
}
- return TANGENT_NONE;
-}
-
-void CurveEditor::add_point(Vector2 pos) {
- ERR_FAIL_COND(_curve_ref.is_null());
-
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Remove Curve Point"));
+ undo_redo->add_do_method(*curve, "remove_point", p_index);
+ undo_redo->add_do_method(this, "set_selected_index", new_selected_index);
+ undo_redo->add_undo_method(*curve, "add_point", old_pos, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
+ undo_redo->add_undo_method(this, "set_selected_index", selected_index);
+ undo_redo->commit_action();
+}
- Vector2 point_pos = get_world_pos(pos);
- if (point_pos.y < 0.0) {
- point_pos.y = 0.0;
- } else if (point_pos.y > 1.0) {
- point_pos.y = 1.0;
- }
+void CurveEdit::set_point_position(int p_index, Vector2 p_pos) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- // Small trick to get the point index to feed the undo method
- int i = _curve_ref->add_point(point_pos);
- _curve_ref->remove_point(i);
+ if (initial_grab_pos == p_pos) {
+ return;
+ }
- undo_redo->add_do_method(*_curve_ref, "add_point", point_pos);
- undo_redo->add_undo_method(*_curve_ref, "remove_point", i);
+ // Pretend the point started from its old place.
+ curve->set_point_value(p_index, initial_grab_pos.y);
+ curve->set_point_offset(p_index, initial_grab_pos.x);
+ // Note: Changing the offset may modify the order.
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Modify Curve Point"));
+ undo_redo->add_do_method(*curve, "set_point_value", initial_grab_index, p_pos.y);
+ undo_redo->add_do_method(*curve, "set_point_offset", initial_grab_index, p_pos.x);
+ undo_redo->add_do_method(this, "set_selected_index", p_index);
+ undo_redo->add_undo_method(*curve, "set_point_value", p_index, initial_grab_pos.y);
+ undo_redo->add_undo_method(*curve, "set_point_offset", p_index, initial_grab_pos.x);
+ undo_redo->add_undo_method(this, "set_selected_index", initial_grab_index);
undo_redo->commit_action();
}
-void CurveEditor::remove_point(int index) {
- ERR_FAIL_COND(_curve_ref.is_null());
+void CurveEdit::set_point_tangents(int p_index, float p_left, float p_right) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(TTR("Remove Curve Point"));
-
- Curve::Point p = _curve_ref->get_point(index);
+ if (initial_grab_left_tangent == p_left) {
+ set_point_right_tangent(p_index, p_right);
+ return;
+ } else if (initial_grab_right_tangent == p_right) {
+ set_point_left_tangent(p_index, p_left);
+ return;
+ }
- undo_redo->add_do_method(*_curve_ref, "remove_point", index);
- undo_redo->add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
+ curve->set_point_left_tangent(p_index, initial_grab_left_tangent);
+ curve->set_point_right_tangent(p_index, initial_grab_right_tangent);
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Modify Curve Point's Tangents"));
+ undo_redo->add_do_method(*curve, "set_point_left_tangent", p_index, p_left);
+ undo_redo->add_do_method(*curve, "set_point_right_tangent", p_index, p_right);
+ undo_redo->add_do_method(this, "set_selected_index", p_index);
+ undo_redo->add_undo_method(*curve, "set_point_left_tangent", p_index, initial_grab_left_tangent);
+ undo_redo->add_undo_method(*curve, "set_point_right_tangent", p_index, initial_grab_right_tangent);
+ undo_redo->add_undo_method(this, "set_selected_index", p_index);
+ undo_redo->commit_action();
+}
- if (index == _selected_point) {
- set_selected_point(-1);
- }
+void CurveEdit::set_point_left_tangent(int p_index, float p_tangent) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- if (index == _hover_point) {
- set_hover_point_index(-1);
+ if (initial_grab_left_tangent == p_tangent) {
+ return;
}
+ curve->set_point_left_tangent(p_index, initial_grab_left_tangent);
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Modify Curve Point's Left Tangent"));
+ undo_redo->add_do_method(*curve, "set_point_left_tangent", p_index, p_tangent);
+ undo_redo->add_do_method(this, "set_selected_index", p_index);
+ undo_redo->add_undo_method(*curve, "set_point_left_tangent", p_index, initial_grab_left_tangent);
+ undo_redo->add_undo_method(this, "set_selected_index", p_index);
undo_redo->commit_action();
}
-void CurveEditor::toggle_linear(TangentIndex tangent) {
- ERR_FAIL_COND(_curve_ref.is_null());
+void CurveEdit::set_point_right_tangent(int p_index, float p_tangent) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(TTR("Toggle Curve Linear Tangent"));
-
- if (tangent == TANGENT_NONE) {
- tangent = _selected_tangent;
+ if (initial_grab_right_tangent == p_tangent) {
+ return;
}
- if (tangent == TANGENT_LEFT) {
- bool is_linear = _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR;
+ curve->set_point_right_tangent(p_index, initial_grab_right_tangent);
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Modify Curve Point's Right Tangent"));
+ undo_redo->add_do_method(*curve, "set_point_right_tangent", p_index, p_tangent);
+ undo_redo->add_do_method(this, "set_selected_index", p_index);
+ undo_redo->add_undo_method(*curve, "set_point_right_tangent", p_index, initial_grab_right_tangent);
+ undo_redo->add_undo_method(this, "set_selected_index", p_index);
+ undo_redo->commit_action();
+}
- Curve::TangentMode prev_mode = _curve_ref->get_point_left_mode(_selected_point);
- Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR;
+void CurveEdit::toggle_linear(int p_index, TangentIndex p_tangent) {
+ ERR_FAIL_COND(curve.is_null());
+ ERR_FAIL_INDEX_MSG(p_index, curve->get_point_count(), "Curve point is out of bounds.");
- undo_redo->add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode);
- undo_redo->add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode);
+ if (p_tangent == TANGENT_NONE) {
+ return;
+ }
- } else {
- bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Toggle Linear Curve Point's Tangent"));
- Curve::TangentMode prev_mode = _curve_ref->get_point_right_mode(_selected_point);
- Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR;
+ Curve::TangentMode prev_mode = (p_tangent == TANGENT_LEFT) ? curve->get_point_left_mode(p_index) : curve->get_point_right_mode(p_index);
+ Curve::TangentMode mode = (prev_mode == Curve::TANGENT_LINEAR) ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR;
+ float prev_angle = (p_tangent == TANGENT_LEFT) ? curve->get_point_left_tangent(p_index) : curve->get_point_right_tangent(p_index);
- undo_redo->add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode);
- undo_redo->add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode);
+ // Add different methods in the UndoRedo based on the tangent passed.
+ if (p_tangent == TANGENT_LEFT) {
+ undo_redo->add_do_method(*curve, "set_point_left_mode", p_index, mode);
+ undo_redo->add_undo_method(*curve, "set_point_left_mode", p_index, prev_mode);
+ undo_redo->add_undo_method(*curve, "set_point_left_tangent", p_index, prev_angle);
+ } else {
+ undo_redo->add_do_method(*curve, "set_point_right_mode", p_index, mode);
+ undo_redo->add_undo_method(*curve, "set_point_right_mode", p_index, prev_mode);
+ undo_redo->add_undo_method(*curve, "set_point_right_tangent", p_index, prev_angle);
}
undo_redo->commit_action();
}
-void CurveEditor::set_selected_point(int index) {
- if (index != _selected_point) {
- _selected_point = index;
+void CurveEdit::set_selected_index(int p_index) {
+ if (p_index != selected_index) {
+ selected_index = p_index;
queue_redraw();
}
}
-void CurveEditor::set_hover_point_index(int index) {
- if (index != _hover_point) {
- _hover_point = index;
- queue_redraw();
- }
-}
-
-void CurveEditor::update_view_transform() {
+void CurveEdit::update_view_transform() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
const real_t margin = font->get_height(font_size) + 2 * EDSCALE;
- float min_y = 0;
- float max_y = 1;
-
- if (_curve_ref.is_valid()) {
- min_y = _curve_ref->get_min_value();
- max_y = _curve_ref->get_max_value();
- }
+ float min_y = curve.is_valid() ? curve->get_min_value() : 0.0;
+ float max_y = curve.is_valid() ? curve->get_max_value() : 1.0;
const Rect2 world_rect = Rect2(Curve::MIN_X, min_y, Curve::MAX_X, max_y - min_y);
const Size2 view_margin(margin, margin);
@@ -557,43 +672,62 @@ void CurveEditor::update_view_transform() {
_world_to_view = view_trans * world_trans;
}
-Vector2 CurveEditor::get_tangent_view_pos(int i, TangentIndex tangent) const {
+Vector2 CurveEdit::get_tangent_view_pos(int p_index, TangentIndex p_tangent) const {
Vector2 dir;
- if (tangent == TANGENT_LEFT) {
- dir = -Vector2(1, _curve_ref->get_point_left_tangent(i));
+ if (p_tangent == TANGENT_LEFT) {
+ dir = -Vector2(1, curve->get_point_left_tangent(p_index));
} else {
- dir = Vector2(1, _curve_ref->get_point_right_tangent(i));
+ dir = Vector2(1, curve->get_point_right_tangent(p_index));
}
- Vector2 point_pos = get_view_pos(_curve_ref->get_point_position(i));
- Vector2 control_pos = get_view_pos(_curve_ref->get_point_position(i) + dir);
+ Vector2 point_pos = curve->get_point_position(p_index);
+ Vector2 point_view_pos = get_view_pos(point_pos);
+ Vector2 control_view_pos = get_view_pos(point_pos + dir);
- return point_pos + Math::round(_tangents_length * _gizmo_handle_scale * EDSCALE) * (control_pos - point_pos).normalized();
+ Vector2 distance_from_point = tangent_length * (control_view_pos - point_view_pos).normalized();
+ Vector2 tangent_view_pos = point_view_pos + distance_from_point;
+
+ // Since the tangent is long, it might slip outside of the area of the editor for points close to the domain/range boundaries.
+ // The code below shrinks the tangent control by up to 50% so it always stays inside the editor for points within the bounds.
+ float fraction_inside = 1.0;
+ if (distance_from_point.x != 0.0) {
+ fraction_inside = MIN(fraction_inside, ((distance_from_point.x > 0 ? get_rect().size.x : 0) - point_view_pos.x) / distance_from_point.x);
+ }
+ if (distance_from_point.y != 0.0) {
+ fraction_inside = MIN(fraction_inside, ((distance_from_point.y > 0 ? get_rect().size.y : 0) - point_view_pos.y) / distance_from_point.y);
+ }
+
+ if (fraction_inside < 1.0 && fraction_inside > 0.5) {
+ tangent_view_pos = point_view_pos + distance_from_point * fraction_inside;
+ }
+
+ return tangent_view_pos;
}
-Vector2 CurveEditor::get_view_pos(Vector2 world_pos) const {
- return _world_to_view.xform(world_pos);
+Vector2 CurveEdit::get_view_pos(Vector2 p_world_pos) const {
+ return _world_to_view.xform(p_world_pos);
}
-Vector2 CurveEditor::get_world_pos(Vector2 view_pos) const {
- return _world_to_view.affine_inverse().xform(view_pos);
+Vector2 CurveEdit::get_world_pos(Vector2 p_view_pos) const {
+ return _world_to_view.affine_inverse().xform(p_view_pos);
}
-// Uses non-baked points, but takes advantage of ordered iteration to be faster
+// Uses non-baked points, but takes advantage of ordered iteration to be faster.
template <typename T>
-static void plot_curve_accurate(const Curve &curve, float step, T plot_func) {
+static void plot_curve_accurate(const Curve &curve, float step, Vector2 scaling, T plot_func) {
if (curve.get_point_count() <= 1) {
- // Not enough points to make a curve, so it's just a straight line
+ // Not enough points to make a curve, so it's just a straight line.
+ // The added tiny vectors make the drawn line stay exactly within the bounds in practice.
float y = curve.sample(0);
- plot_func(Vector2(0, y), Vector2(1.f, y), true);
+ plot_func(Vector2(0, y) * scaling + Vector2(0.5, 0), Vector2(1.f, y) * scaling - Vector2(1.5, 0), true);
} else {
Vector2 first_point = curve.get_point_position(0);
Vector2 last_point = curve.get_point_position(curve.get_point_count() - 1);
// Edge lines
- plot_func(Vector2(0, first_point.y), first_point, false);
- plot_func(Vector2(Curve::MAX_X, last_point.y), last_point, false);
+ plot_func(Vector2(0, first_point.y) * scaling + Vector2(0.5, 0), first_point * scaling, false);
+ plot_func(Vector2(Curve::MAX_X, last_point.y) * scaling - Vector2(1.5, 0), last_point * scaling, false);
// Draw section by section, so that we get maximum precision near points.
// It's an accurate representation, but slower than using the baked one.
@@ -604,16 +738,18 @@ static void plot_curve_accurate(const Curve &curve, float step, T plot_func) {
Vector2 pos = a;
Vector2 prev_pos = a;
- float len = b.x - a.x;
+ float scaled_step = step / scaling.x;
+ float samples = (b.x - a.x) / scaled_step;
- for (float x = step; x < len; x += step) {
+ for (int j = 1; j < samples; j++) {
+ float x = j * scaled_step;
pos.x = a.x + x;
pos.y = curve.sample_local_nocheck(i - 1, x);
- plot_func(prev_pos, pos, true);
+ plot_func(prev_pos * scaling, pos * scaling, true);
prev_pos = pos;
}
- plot_func(prev_pos, b, true);
+ plot_func(prev_pos * scaling, b * scaling, true);
}
}
}
@@ -629,50 +765,50 @@ struct CanvasItemPlotCurve {
color2(p_color2) {}
void operator()(Vector2 pos0, Vector2 pos1, bool in_definition) {
- // FIXME: Using a quad line breaks curve rendering.
- ci.draw_line(pos0, pos1, in_definition ? color1 : color2, -1);
+ ci.draw_line(pos0, pos1, in_definition ? color1 : color2, 0.5, true);
}
};
-void CurveEditor::_draw() {
- if (_curve_ref.is_null()) {
+void CurveEdit::_redraw() {
+ if (curve.is_null()) {
return;
}
- Curve &curve = **_curve_ref;
update_view_transform();
- // Background
+ // Draw background.
Vector2 view_size = get_rect().size;
draw_style_box(get_theme_stylebox(SNAME("panel"), SNAME("Tree")), Rect2(Point2(), view_size));
- // Grid
-
+ // Draw snapping grid, then primary grid.
draw_set_transform_matrix(_world_to_view);
Vector2 min_edge = get_world_pos(Vector2(0, view_size.y));
Vector2 max_edge = get_world_pos(Vector2(view_size.x, 0));
- const Color grid_color0 = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.15);
- const Color grid_color1 = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.07);
- draw_line(Vector2(min_edge.x, curve.get_min_value()), Vector2(max_edge.x, curve.get_min_value()), grid_color0);
- draw_line(Vector2(max_edge.x, curve.get_max_value()), Vector2(min_edge.x, curve.get_max_value()), grid_color0);
- draw_line(Vector2(0, min_edge.y), Vector2(0, max_edge.y), grid_color0);
- draw_line(Vector2(1, max_edge.y), Vector2(1, min_edge.y), grid_color0);
+ const Color grid_color_primary = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.25);
+ const Color grid_color = get_theme_color(SNAME("mono_color"), SNAME("Editor")) * Color(1, 1, 1, 0.1);
- float curve_height = (curve.get_max_value() - curve.get_min_value());
- const Vector2 grid_step(0.25, 0.5 * curve_height);
+ const Vector2i grid_steps = Vector2i(4, 2);
+ const Vector2 step_size = Vector2(1, curve->get_range()) / grid_steps;
- for (real_t x = 0; x < 1.0; x += grid_step.x) {
- draw_line(Vector2(x, min_edge.y), Vector2(x, max_edge.y), grid_color1);
- }
- for (real_t y = curve.get_min_value(); y < curve.get_max_value(); y += grid_step.y) {
- draw_line(Vector2(min_edge.x, y), Vector2(max_edge.x, y), grid_color1);
+ draw_line(Vector2(min_edge.x, curve->get_min_value()), Vector2(max_edge.x, curve->get_min_value()), grid_color_primary);
+ draw_line(Vector2(max_edge.x, curve->get_max_value()), Vector2(min_edge.x, curve->get_max_value()), grid_color_primary);
+ draw_line(Vector2(0, min_edge.y), Vector2(0, max_edge.y), grid_color_primary);
+ draw_line(Vector2(1, max_edge.y), Vector2(1, min_edge.y), grid_color_primary);
+
+ for (int i = 1; i < grid_steps.x; i++) {
+ real_t x = i * step_size.x;
+ draw_line(Vector2(x, min_edge.y), Vector2(x, max_edge.y), grid_color);
}
- // Markings
+ for (int i = 1; i < grid_steps.y; i++) {
+ real_t y = curve->get_min_value() + i * step_size.y;
+ draw_line(Vector2(min_edge.x, y), Vector2(max_edge.x, y), grid_color);
+ }
+ // Draw number markings.
draw_set_transform_matrix(Transform2D());
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
@@ -680,94 +816,218 @@ void CurveEditor::_draw() {
float font_height = font->get_height(font_size);
Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- {
- // X axis
- float y = curve.get_min_value();
- Vector2 off(0, font_height - 1);
- draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ for (int i = 0; i <= grid_steps.x; ++i) {
+ real_t x = i * step_size.x;
+ draw_string(font, get_view_pos(Vector2(x - step_size.x / 2, curve->get_min_value())) + Vector2(0, font_height - Math::round(2 * EDSCALE)), String::num(x, 2), HORIZONTAL_ALIGNMENT_CENTER, get_view_pos(Vector2(step_size.x, 0)).x, font_size, text_color);
}
- {
- // Y axis
- float m0 = curve.get_min_value();
- float m1 = 0.5 * (curve.get_min_value() + curve.get_max_value());
- float m2 = curve.get_max_value();
- Vector2 off(1, -1);
- draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
- draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ for (int i = 0; i <= grid_steps.y; ++i) {
+ real_t y = curve->get_min_value() + i * step_size.y;
+ draw_string(font, get_view_pos(Vector2(0, y)) + Vector2(2, -2), String::num(y, 2), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
}
- // Draw tangents for current point
+ // Draw curve.
- if (_selected_point >= 0) {
- const Color tangent_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ // An unusual transform so we can offset the curve before scaling it up, allowing the curve to be antialiased.
+ // The scaling up ensures that the curve rendering doesn't break when we use a quad line to draw it.
+ draw_set_transform_matrix(Transform2D(0, get_view_pos(Vector2(0, 0))));
- int i = _selected_point;
- Vector2 pos = curve.get_point_position(i);
+ const Color line_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
+ const Color edge_line_color = get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.75);
- if (i != 0) {
- Vector2 control_pos = get_tangent_view_pos(i, TANGENT_LEFT);
- draw_line(get_view_pos(pos), control_pos, tangent_color, Math::round(EDSCALE));
- draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(Math::round(2 * _gizmo_handle_scale * EDSCALE)), tangent_color);
- }
+ CanvasItemPlotCurve plot_func(*this, line_color, edge_line_color);
+ plot_curve_accurate(**curve, 2.f, (get_view_pos(Vector2(1, curve->get_max_value())) - get_view_pos(Vector2(0, curve->get_min_value()))) / Vector2(1, curve->get_range()), plot_func);
+
+ // Draw points, except for the selected one.
+ draw_set_transform_matrix(Transform2D());
+
+ bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
+
+ const Color point_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- if (i != curve.get_point_count() - 1) {
- Vector2 control_pos = get_tangent_view_pos(i, TANGENT_RIGHT);
- draw_line(get_view_pos(pos), control_pos, tangent_color, Math::round(EDSCALE));
- draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(Math::round(2 * _gizmo_handle_scale * EDSCALE)), tangent_color);
+ for (int i = 0; i < curve->get_point_count(); ++i) {
+ Vector2 pos = get_view_pos(curve->get_point_position(i));
+ if (selected_index != i) {
+ draw_rect(Rect2(pos, Vector2(0, 0)).grow(point_radius), point_color);
+ }
+ if (hovered_index == i && hovered_tangent_index == TANGENT_NONE) {
+ draw_rect(Rect2(pos, Vector2(0, 0)).grow(hover_radius - Math::round(3 * EDSCALE)), line_color, false, Math::round(1 * EDSCALE));
}
}
- // Draw lines
+ // Draw selected point and its tangents.
- draw_set_transform_matrix(_world_to_view);
+ if (selected_index >= 0) {
+ const Vector2 point_pos = curve->get_point_position(selected_index);
+ const Color selected_point_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
- const Color line_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- const Color edge_line_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
+ // Draw tangents if not dragging a point, or if holding a point without having moved it yet.
+ if (grabbing == GRAB_NONE || (grabbing != GRAB_NONE && (initial_grab_pos == point_pos || selected_tangent_index != TANGENT_NONE))) {
+ const Color selected_tangent_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")).darkened(0.25);
+ const Color tangent_color = get_theme_color(SNAME("font_color"), SNAME("Editor")).darkened(0.25);
- CanvasItemPlotCurve plot_func(*this, line_color, edge_line_color);
- plot_curve_accurate(curve, 4.f / view_size.x, plot_func);
+ if (selected_index != 0) {
+ Vector2 control_pos = get_tangent_view_pos(selected_index, TANGENT_LEFT);
+ Color left_tangent_color = (selected_tangent_index == TANGENT_LEFT) ? selected_tangent_color : tangent_color;
- // Draw points
+ draw_line(get_view_pos(point_pos), control_pos, left_tangent_color, 0.5 * EDSCALE, true);
+ // Square for linear mode, circle otherwise.
+ if (curve->get_point_left_mode(selected_index) == Curve::TANGENT_FREE) {
+ draw_circle(control_pos, tangent_radius, left_tangent_color);
+ } else {
+ draw_rect(Rect2(control_pos, Vector2(0, 0)).grow(tangent_radius), left_tangent_color);
+ }
+ // Hover indicator.
+ if (hovered_tangent_index == TANGENT_LEFT || (hovered_tangent_index == TANGENT_RIGHT && !shift_pressed && curve->get_point_left_mode(selected_index) != Curve::TANGENT_LINEAR)) {
+ draw_rect(Rect2(control_pos, Vector2(0, 0)).grow(tangent_hover_radius - Math::round(3 * EDSCALE)), tangent_color, false, Math::round(1 * EDSCALE));
+ }
+ }
- draw_set_transform_matrix(Transform2D());
+ if (selected_index != curve->get_point_count() - 1) {
+ Vector2 control_pos = get_tangent_view_pos(selected_index, TANGENT_RIGHT);
+ Color right_tangent_color = (selected_tangent_index == TANGENT_RIGHT) ? selected_tangent_color : tangent_color;
- const Color point_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
- const Color selected_point_color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+ draw_line(get_view_pos(point_pos), control_pos, right_tangent_color, 0.5 * EDSCALE, true);
+ // Square for linear mode, circle otherwise.
+ if (curve->get_point_right_mode(selected_index) == Curve::TANGENT_FREE) {
+ draw_circle(control_pos, tangent_radius, right_tangent_color);
+ } else {
+ draw_rect(Rect2(control_pos, Vector2(0, 0)).grow(tangent_radius), right_tangent_color);
+ }
+ // Hover indicator.
+ if (hovered_tangent_index == TANGENT_RIGHT || (hovered_tangent_index == TANGENT_LEFT && !shift_pressed && curve->get_point_right_mode(selected_index) != Curve::TANGENT_LINEAR)) {
+ draw_rect(Rect2(control_pos, Vector2(0, 0)).grow(tangent_hover_radius - Math::round(3 * EDSCALE)), tangent_color, false, Math::round(1 * EDSCALE));
+ }
+ }
+ }
- for (int i = 0; i < curve.get_point_count(); ++i) {
- Vector2 pos = curve.get_point_position(i);
- draw_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(Math::round(3 * _gizmo_handle_scale * EDSCALE)), i == _selected_point ? selected_point_color : point_color);
- // TODO Circles are prettier. Needs a fix! Or a texture
- //draw_circle(pos, 2, point_color);
+ draw_rect(Rect2(get_view_pos(point_pos), Vector2(0, 0)).grow(point_radius), selected_point_color);
}
- // Hover
+ // Draw help text.
+
+ if (selected_index > 0 && selected_index < curve->get_point_count() - 1 && selected_tangent_index == TANGENT_NONE && hovered_tangent_index != TANGENT_NONE && !shift_pressed) {
+ float width = view_size.x - 50 * EDSCALE;
+ text_color.a *= 0.4;
+
+ draw_multiline_string(font, Vector2(25 * EDSCALE, font_height - Math::round(2 * EDSCALE)), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_CENTER, width, font_size, -1, text_color);
- if (_hover_point != -1) {
- const Color hover_color = line_color;
- Vector2 pos = curve.get_point_position(_hover_point);
- draw_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(Math::round(_hover_radius * _gizmo_handle_scale * EDSCALE)), hover_color, false, Math::round(EDSCALE));
+ } else if (selected_index != -1 && selected_tangent_index == TANGENT_NONE) {
+ const Vector2 point_pos = curve->get_point_position(selected_index);
+ float width = view_size.x - 50 * EDSCALE;
+ text_color.a *= 0.8;
+
+ draw_string(font, Vector2(25 * EDSCALE, font_height - Math::round(2 * EDSCALE)), vformat("(%.2f, %.2f)", point_pos.x, point_pos.y), HORIZONTAL_ALIGNMENT_CENTER, width, font_size, text_color);
+
+ } else if (selected_index != -1 && selected_tangent_index != TANGENT_NONE) {
+ float width = view_size.x - 50 * EDSCALE;
+ text_color.a *= 0.8;
+ real_t theta = Math::rad_to_deg(Math::atan(selected_tangent_index == TANGENT_LEFT ? -1 * curve->get_point_left_tangent(selected_index) : curve->get_point_right_tangent(selected_index)));
+
+ draw_string(font, Vector2(25 * EDSCALE, font_height - Math::round(2 * EDSCALE)), String::num(theta, 1) + String::utf8(" °"), HORIZONTAL_ALIGNMENT_CENTER, width, font_size, text_color);
}
- // Help text
+ // Draw temporary constraints and snapping axes.
+ draw_set_transform_matrix(_world_to_view);
- float width = view_size.x - 60 * EDSCALE;
- if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) {
- text_color.a *= 0.4;
- draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color);
- } else if (curve.get_point_count() == 0) {
- text_color.a *= 0.4;
- draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color);
+ if (Input::get_singleton()->is_key_pressed(Key::ALT) && grabbing != GRAB_NONE && selected_tangent_index == TANGENT_NONE) {
+ float prev_point_offset = (selected_index > 0) ? curve->get_point_position(selected_index - 1).x : 0.0;
+ float next_point_offset = (selected_index < curve->get_point_count() - 1) ? curve->get_point_position(selected_index + 1).x : 1.0;
+
+ draw_line(Vector2(prev_point_offset, curve->get_min_value()), Vector2(prev_point_offset, curve->get_max_value()), Color(point_color, 0.6));
+ draw_line(Vector2(next_point_offset, curve->get_min_value()), Vector2(next_point_offset, curve->get_max_value()), Color(point_color, 0.6));
+ }
+
+ if (shift_pressed && grabbing != GRAB_NONE && selected_tangent_index == TANGENT_NONE) {
+ draw_line(Vector2(initial_grab_pos.x, curve->get_min_value()), Vector2(initial_grab_pos.x, curve->get_max_value()), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")).darkened(0.4));
+ draw_line(Vector2(0, initial_grab_pos.y), Vector2(1, initial_grab_pos.y), get_theme_color(SNAME("axis_y_color"), SNAME("Editor")).darkened(0.4));
}
}
-//---------------
+///////////////////////
+
+const int CurveEditor::DEFAULT_SNAP = 10;
+
+void CurveEditor::_set_snap_enabled(bool p_enabled) {
+ curve_editor_rect->set_snap_enabled(p_enabled);
+ snap_count_edit->set_visible(p_enabled);
+}
+
+void CurveEditor::_set_snap_count(int p_snap_count) {
+ curve_editor_rect->set_snap_count(CLAMP(p_snap_count, 2, 100));
+}
+
+void CurveEditor::_on_preset_item_selected(int p_preset_id) {
+ curve_editor_rect->use_preset(p_preset_id);
+}
+
+void CurveEditor::set_curve(const Ref<Curve> &p_curve) {
+ curve_editor_rect->set_curve(p_curve);
+}
+
+void CurveEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ spacing = Math::round(BASE_SPACING * get_theme_default_base_scale());
+ snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ PopupMenu *p = presets_button->get_popup();
+ p->clear();
+ p->add_icon_item(get_theme_icon(SNAME("CurveConstant"), SNAME("EditorIcons")), TTR("Constant"), CurveEdit::PRESET_CONSTANT);
+ p->add_icon_item(get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")), TTR("Linear"), CurveEdit::PRESET_LINEAR);
+ p->add_icon_item(get_theme_icon(SNAME("CurveIn"), SNAME("EditorIcons")), TTR("Ease In"), CurveEdit::PRESET_EASE_IN);
+ p->add_icon_item(get_theme_icon(SNAME("CurveOut"), SNAME("EditorIcons")), TTR("Ease Out"), CurveEdit::PRESET_EASE_OUT);
+ p->add_icon_item(get_theme_icon(SNAME("CurveInOut"), SNAME("EditorIcons")), TTR("Smoothstep"), CurveEdit::PRESET_SMOOTHSTEP);
+ } break;
+ case NOTIFICATION_READY: {
+ Ref<Curve> curve = curve_editor_rect->get_curve();
+ // Set snapping settings based on the curve's meta.
+ snap_button->set_pressed(curve->get_meta("_snap_enabled", false));
+ snap_count_edit->set_value(curve->get_meta("_snap_count", DEFAULT_SNAP));
+ } break;
+ }
+}
+
+CurveEditor::CurveEditor() {
+ HFlowContainer *toolbar = memnew(HFlowContainer);
+ add_child(toolbar);
+
+ snap_button = memnew(Button);
+ snap_button->set_tooltip_text(TTR("Toggle Grid Snap"));
+ snap_button->set_toggle_mode(true);
+ toolbar->add_child(snap_button);
+ snap_button->connect("toggled", callable_mp(this, &CurveEditor::_set_snap_enabled));
+
+ toolbar->add_child(memnew(VSeparator));
+
+ snap_count_edit = memnew(EditorSpinSlider);
+ snap_count_edit->set_min(2);
+ snap_count_edit->set_max(100);
+ snap_count_edit->set_value(DEFAULT_SNAP);
+ snap_count_edit->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ toolbar->add_child(snap_count_edit);
+ snap_count_edit->connect("value_changed", callable_mp(this, &CurveEditor::_set_snap_count));
+
+ presets_button = memnew(MenuButton);
+ presets_button->set_text(TTR("Presets"));
+ presets_button->set_switch_on_hover(true);
+ presets_button->set_h_size_flags(SIZE_EXPAND | SIZE_SHRINK_END);
+ toolbar->add_child(presets_button);
+ presets_button->get_popup()->connect("id_pressed", callable_mp(this, &CurveEditor::_on_preset_item_selected));
+
+ curve_editor_rect = memnew(CurveEdit);
+ add_child(curve_editor_rect);
+
+ // Some empty space below. Not a part of the curve editor so it can't draw in it.
+ Control *empty_space = memnew(Control);
+ empty_space->set_custom_minimum_size(Vector2(0, spacing));
+ add_child(empty_space);
+
+ set_mouse_filter(MOUSE_FILTER_STOP);
+ _set_snap_enabled(snap_button->is_pressed());
+ _set_snap_count(snap_count_edit->get_value());
+}
+
+///////////////////////
bool EditorInspectorPluginCurve::can_handle(Object *p_object) {
return Object::cast_to<Curve>(p_object) != nullptr;
@@ -779,73 +1039,58 @@ void EditorInspectorPluginCurve::parse_begin(Object *p_object) {
Ref<Curve> c(curve);
CurveEditor *editor = memnew(CurveEditor);
- editor->set_curve(curve);
+ editor->set_curve(c);
add_custom_control(editor);
}
CurveEditorPlugin::CurveEditorPlugin() {
- Ref<EditorInspectorPluginCurve> curve_plugin;
- curve_plugin.instantiate();
- EditorInspector::add_inspector_plugin(curve_plugin);
+ Ref<EditorInspectorPluginCurve> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
EditorInterface::get_singleton()->get_resource_previewer()->add_preview_generator(memnew(CurvePreviewGenerator));
}
-//-----------------------------------
-// Preview generator
+///////////////////////
bool CurvePreviewGenerator::handles(const String &p_type) const {
return p_type == "Curve";
}
Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 &p_size, Dictionary &p_metadata) const {
- Ref<Curve> curve_ref = p_from;
- ERR_FAIL_COND_V_MSG(curve_ref.is_null(), Ref<Texture2D>(), "It's not a reference to a valid Resource object.");
- Curve &curve = **curve_ref;
+ Ref<Curve> curve = p_from;
+ if (curve.is_null()) {
+ return Ref<Texture2D>();
+ }
- // FIXME: Should be ported to use p_size as done in b2633a97
- int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
+ Size2 thumbnail_size = p_size * EDSCALE;
Ref<Image> img_ref;
img_ref.instantiate();
Image &im = **img_ref;
-
- im.initialize_data(thumbnail_size, thumbnail_size / 2, false, Image::FORMAT_RGBA8);
+ im.initialize_data(thumbnail_size.x, thumbnail_size.y, false, Image::FORMAT_RGBA8);
Color bg_color(0.1, 0.1, 0.1, 1.0);
-
- im.fill(bg_color);
-
Color line_color(0.8, 0.8, 0.8, 1.0);
- float range_y = curve.get_max_value() - curve.get_min_value();
- int prev_y = 0;
- for (int x = 0; x < im.get_width(); ++x) {
+ im.fill(bg_color);
+ // Set the first pixel of the thumbnail.
+ float v = (curve->sample_baked(0) - curve->get_min_value()) / curve->get_range();
+ int y = CLAMP(im.get_height() - v * im.get_height(), 0, im.get_height() - 1);
+ im.set_pixel(0, y, line_color);
+
+ // Plot a line towards the next point.
+ int prev_y = y;
+ for (int x = 1; x < im.get_width(); ++x) {
float t = static_cast<float>(x) / im.get_width();
- float v = (curve.sample_baked(t) - curve.get_min_value()) / range_y;
- int y = CLAMP(im.get_height() - v * im.get_height(), 0, im.get_height());
+ v = (curve->sample_baked(t) - curve->get_min_value()) / curve->get_range();
+ y = CLAMP(im.get_height() - v * im.get_height(), 0, im.get_height() - 1);
- // Plot point
- if (y >= 0 && y < im.get_height()) {
- im.set_pixel(x, y, line_color);
+ Vector<Point2i> points = Geometry2D::bresenham_line(Point2i(x - 1, prev_y), Point2i(x, y));
+ for (Point2i point : points) {
+ im.set_pixelv(point, line_color);
}
-
- // Plot vertical line to fix discontinuity (not 100% correct but enough for a preview)
- if (x != 0 && Math::abs(y - prev_y) > 1) {
- int y0, y1;
- if (y < prev_y) {
- y0 = y;
- y1 = prev_y;
- } else {
- y0 = prev_y;
- y1 = y;
- }
- for (int ly = y0; ly < y1; ++ly) {
- im.set_pixel(x, ly, line_color);
- }
- }
-
prev_y = y;
}
+
return ImageTexture::create_from_image(img_ref);
}
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index 903f8d593e..0f582fca9a 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -36,22 +36,27 @@
#include "editor/editor_resource_preview.h"
#include "scene/resources/curve.h"
+class EditorSpinSlider;
+class MenuButton;
class PopupMenu;
-// Edits a y(x) curve
-class CurveEditor : public Control {
- GDCLASS(CurveEditor, Control);
+class CurveEdit : public Control {
+ GDCLASS(CurveEdit, Control);
public:
- CurveEditor();
+ CurveEdit();
- Size2 get_minimum_size() const override;
+ void set_snap_enabled(bool p_enabled);
+ void set_snap_count(int p_snap_count);
+ void use_preset(int p_preset_id);
+
+ void set_curve(Ref<Curve> p_curve);
+ Ref<Curve> get_curve();
- void set_curve(Ref<Curve> curve);
+ Size2 get_minimum_size() const override;
enum PresetID {
- PRESET_FLAT0 = 0,
- PRESET_FLAT1,
+ PRESET_CONSTANT = 0,
PRESET_LINEAR,
PRESET_EASE_IN,
PRESET_EASE_OUT,
@@ -59,14 +64,6 @@ public:
PRESET_COUNT
};
- enum ContextAction {
- CONTEXT_ADD_POINT = 0,
- CONTEXT_REMOVE_POINT,
- CONTEXT_LINEAR,
- CONTEXT_LEFT_LINEAR,
- CONTEXT_RIGHT_LINEAR
- };
-
enum TangentIndex {
TANGENT_NONE = -1,
TANGENT_LEFT = 0,
@@ -75,49 +72,103 @@ public:
protected:
void _notification(int p_what);
+ static void _bind_methods();
private:
virtual void gui_input(const Ref<InputEvent> &p_event) override;
- void on_preset_item_selected(int preset_id);
void _curve_changed();
- void on_context_menu_item_selected(int action_id);
-
- void open_context_menu(Vector2 pos);
- int get_point_at(Vector2 pos) const;
- TangentIndex get_tangent_at(Vector2 pos) const;
- void add_point(Vector2 pos);
- void remove_point(int index);
- void toggle_linear(TangentIndex tangent = TANGENT_NONE);
- void set_selected_point(int index);
- void set_hover_point_index(int index);
+
+ int get_point_at(Vector2 p_pos) const;
+ TangentIndex get_tangent_at(Vector2 p_pos) const;
+
+ float get_offset_without_collision(int p_current_index, float p_offset, bool p_prioritize_right = true);
+
+ void add_point(Vector2 p_pos);
+ void remove_point(int p_index);
+ void set_point_position(int p_index, Vector2 p_pos);
+
+ void set_point_tangents(int p_index, float p_left, float p_right);
+ void set_point_left_tangent(int p_index, float p_tangent);
+ void set_point_right_tangent(int p_index, float p_tangent);
+ void toggle_linear(int p_index, TangentIndex p_tangent = TANGENT_NONE);
+
void update_view_transform();
- Vector2 get_tangent_view_pos(int i, TangentIndex tangent) const;
- Vector2 get_view_pos(Vector2 world_pos) const;
- Vector2 get_world_pos(Vector2 view_pos) const;
+ void set_selected_index(int p_index);
+ void set_selected_tangent_index(TangentIndex p_tangent);
+
+ Vector2 get_tangent_view_pos(int p_index, TangentIndex p_tangent) const;
+ Vector2 get_view_pos(Vector2 p_world_pos) const;
+ Vector2 get_world_pos(Vector2 p_view_pos) const;
- void _draw();
+ void _on_mouse_exited();
+
+ void _redraw();
private:
Transform2D _world_to_view;
- Ref<Curve> _curve_ref;
- PopupMenu *_context_menu = nullptr;
+ Ref<Curve> curve;
PopupMenu *_presets_menu = nullptr;
- Array _undo_data;
- bool _has_undo_data;
+ int selected_index = -1;
+ int hovered_index = -1;
+ TangentIndex selected_tangent_index = TANGENT_NONE;
+ TangentIndex hovered_tangent_index = TANGENT_NONE;
+
+ // Make sure to use the scaled values below.
+ const int BASE_POINT_RADIUS = 4;
+ const int BASE_HOVER_RADIUS = 10;
+ const int BASE_TANGENT_RADIUS = 3;
+ const int BASE_TANGENT_HOVER_RADIUS = 8;
+ const int BASE_TANGENT_LENGTH = 36;
+
+ int point_radius = BASE_POINT_RADIUS;
+ int hover_radius = BASE_HOVER_RADIUS;
+ int tangent_radius = BASE_TANGENT_RADIUS;
+ int tangent_hover_radius = BASE_TANGENT_HOVER_RADIUS;
+ int tangent_length = BASE_TANGENT_LENGTH;
+
+ enum GrabMode {
+ GRAB_NONE,
+ GRAB_ADD,
+ GRAB_MOVE
+ };
+ GrabMode grabbing = GRAB_NONE;
+ Vector2 initial_grab_pos;
+ int initial_grab_index;
+ float initial_grab_left_tangent;
+ float initial_grab_right_tangent;
+
+ bool snap_enabled = false;
+ int snap_count = 10;
+};
+
+// CurveEdit + toolbar
+class CurveEditor : public VBoxContainer {
+ GDCLASS(CurveEditor, VBoxContainer);
+
+ // Make sure to use the scaled values below.
+ const int BASE_SPACING = 4;
+ int spacing = BASE_SPACING;
+
+ Button *snap_button = nullptr;
+ EditorSpinSlider *snap_count_edit = nullptr;
+ MenuButton *presets_button = nullptr;
+ CurveEdit *curve_editor_rect = nullptr;
- Vector2 _context_click_pos;
- int _selected_point;
- int _hover_point;
- TangentIndex _selected_tangent;
- bool _dragging;
+ void _set_snap_enabled(bool p_enabled);
+ void _set_snap_count(int p_snap_count);
+ void _on_preset_item_selected(int p_preset_id);
- // Constant
- float _hover_radius;
- float _tangents_length;
- float _gizmo_handle_scale = 1.0;
+protected:
+ void _notification(int p_what);
+
+public:
+ static const int DEFAULT_SNAP;
+ void set_curve(const Ref<Curve> &p_curve);
+
+ CurveEditor();
};
class EditorInspectorPluginCurve : public EditorInspectorPlugin {
diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp
index 7618ec3903..c3d1e920d7 100644
--- a/editor/plugins/font_config_plugin.cpp
+++ b/editor/plugins/font_config_plugin.cpp
@@ -227,7 +227,7 @@ void EditorPropertyFontMetaOverride::_object_id_selected(const StringName &p_pro
}
void EditorPropertyFontMetaOverride::update_property() {
- Variant updated_val = get_edited_object()->get(get_edited_property());
+ Variant updated_val = get_edited_property_value();
Dictionary dict = updated_val;
@@ -330,7 +330,7 @@ void EditorPropertyFontMetaOverride::update_property() {
}
void EditorPropertyFontMetaOverride::_edit_pressed() {
- Variant prop_val = get_edited_object()->get(get_edited_property());
+ Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL) {
Callable::CallError ce;
Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
@@ -415,7 +415,7 @@ void EditorPropertyOTVariation::_object_id_selected(const StringName &p_property
}
void EditorPropertyOTVariation::update_property() {
- Variant updated_val = get_edited_object()->get(get_edited_property());
+ Variant updated_val = get_edited_property_value();
Dictionary dict = updated_val;
@@ -511,7 +511,7 @@ void EditorPropertyOTVariation::update_property() {
}
void EditorPropertyOTVariation::_edit_pressed() {
- Variant prop_val = get_edited_object()->get(get_edited_property());
+ Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL) {
Callable::CallError ce;
Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
@@ -607,7 +607,7 @@ void EditorPropertyOTFeatures::_object_id_selected(const StringName &p_property,
}
void EditorPropertyOTFeatures::update_property() {
- Variant updated_val = get_edited_object()->get(get_edited_property());
+ Variant updated_val = get_edited_property_value();
Dictionary dict = updated_val;
@@ -814,7 +814,7 @@ void EditorPropertyOTFeatures::update_property() {
}
void EditorPropertyOTFeatures::_edit_pressed() {
- Variant prop_val = get_edited_object()->get(get_edited_property());
+ Variant prop_val = get_edited_property_value();
if (prop_val.get_type() == Variant::NIL) {
Callable::CallError ce;
Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
diff --git a/editor/plugins/gradient_editor.cpp b/editor/plugins/gradient_editor.cpp
index 2eb17b3f13..000db06d48 100644
--- a/editor/plugins/gradient_editor.cpp
+++ b/editor/plugins/gradient_editor.cpp
@@ -41,6 +41,7 @@ void GradientEditor::set_gradient(const Ref<Gradient> &p_gradient) {
gradient->connect("changed", callable_mp(this, &GradientEditor::_gradient_changed));
set_points(gradient->get_points());
set_interpolation_mode(gradient->get_interpolation_mode());
+ set_interpolation_color_space(gradient->get_interpolation_color_space());
}
void GradientEditor::reverse_gradient() {
@@ -93,6 +94,7 @@ void GradientEditor::_gradient_changed() {
Vector<Gradient::Point> grad_points = gradient->get_points();
set_points(grad_points);
set_interpolation_mode(gradient->get_interpolation_mode());
+ set_interpolation_color_space(gradient->get_interpolation_color_space());
queue_redraw();
editing = false;
}
@@ -104,9 +106,11 @@ void GradientEditor::_ramp_changed() {
undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets());
undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors());
undo_redo->add_do_method(gradient.ptr(), "set_interpolation_mode", get_interpolation_mode());
+ undo_redo->add_do_method(gradient.ptr(), "set_interpolation_color_space", get_interpolation_color_space());
undo_redo->add_undo_method(gradient.ptr(), "set_offsets", gradient->get_offsets());
undo_redo->add_undo_method(gradient.ptr(), "set_colors", gradient->get_colors());
undo_redo->add_undo_method(gradient.ptr(), "set_interpolation_mode", gradient->get_interpolation_mode());
+ undo_redo->add_undo_method(gradient.ptr(), "set_interpolation_color_space", gradient->get_interpolation_color_space());
undo_redo->commit_action();
editing = false;
}
@@ -171,6 +175,14 @@ Gradient::InterpolationMode GradientEditor::get_interpolation_mode() {
return interpolation_mode;
}
+void GradientEditor::set_interpolation_color_space(Gradient::ColorSpace p_color_space) {
+ interpolation_color_space = p_color_space;
+}
+
+Gradient::ColorSpace GradientEditor::get_interpolation_color_space() {
+ return interpolation_color_space;
+}
+
ColorPicker *GradientEditor::get_picker() {
return picker;
}
@@ -385,6 +397,7 @@ void GradientEditor::_notification(int p_what) {
// Draw color ramp.
gradient_cache->set_points(points);
gradient_cache->set_interpolation_mode(interpolation_mode);
+ gradient_cache->set_interpolation_color_space(interpolation_color_space);
preview_texture->set_gradient(gradient_cache);
draw_texture_rect(preview_texture, Rect2(handle_width / 2, 0, total_w, h));
diff --git a/editor/plugins/gradient_editor.h b/editor/plugins/gradient_editor.h
index a8757573d5..b78b740f4f 100644
--- a/editor/plugins/gradient_editor.h
+++ b/editor/plugins/gradient_editor.h
@@ -45,6 +45,7 @@ class GradientEditor : public Control {
int grabbed = -1;
Vector<Gradient::Point> points;
Gradient::InterpolationMode interpolation_mode = Gradient::GRADIENT_INTERPOLATE_LINEAR;
+ Gradient::ColorSpace interpolation_color_space = Gradient::GRADIENT_COLOR_SPACE_SRGB;
bool editing = false;
Ref<Gradient> gradient;
@@ -84,6 +85,9 @@ public:
void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode);
Gradient::InterpolationMode get_interpolation_mode();
+ void set_interpolation_color_space(Gradient::ColorSpace p_color_space);
+ Gradient::ColorSpace get_interpolation_color_space();
+
ColorPicker *get_picker();
PopupPanel *get_popup();
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
index e91afe28ee..3df8aeaa14 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
@@ -39,145 +39,191 @@
#include "scene/gui/flow_container.h"
#include "scene/gui/separator.h"
-Point2 GradientTexture2DEditorRect::_get_handle_position(const Handle p_handle) {
+void GradientTexture2DEdit::_on_mouse_exited() {
+ if (hovered != HANDLE_NONE) {
+ hovered = HANDLE_NONE;
+ queue_redraw();
+ }
+}
+
+Point2 GradientTexture2DEdit::_get_handle_pos(const Handle p_handle) {
// Get the handle's mouse position in pixels relative to offset.
- return (p_handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to()).clamp(Vector2(), Vector2(1, 1)) * size;
+ return (p_handle == HANDLE_FROM ? texture->get_fill_from() : texture->get_fill_to()).clamp(Vector2(), Vector2(1, 1)) * size;
}
-void GradientTexture2DEditorRect::_update_fill_position() {
- if (handle == HANDLE_NONE) {
- return;
+GradientTexture2DEdit::Handle GradientTexture2DEdit::get_handle_at(const Vector2 &p_pos) {
+ Point2 from_pos = _get_handle_pos(HANDLE_FROM);
+ Point2 to_pos = _get_handle_pos(HANDLE_TO);
+ // If both handles are at the position, grab the one that's closer.
+ if (p_pos.distance_squared_to(from_pos) < p_pos.distance_squared_to(to_pos)) {
+ return Rect2(from_pos.round() - handle_size / 2, handle_size).has_point(p_pos) ? HANDLE_FROM : HANDLE_NONE;
+ } else {
+ return Rect2(to_pos.round() - handle_size / 2, handle_size).has_point(p_pos) ? HANDLE_TO : HANDLE_NONE;
}
+}
- // Update the texture's fill_from/fill_to property based on mouse input.
- Vector2 percent = ((get_local_mouse_position() - offset) / size).clamp(Vector2(), Vector2(1, 1));
- if (snap_enabled) {
- percent = (percent - Vector2(0.5, 0.5)).snapped(Vector2(snap_size, snap_size)) + Vector2(0.5, 0.5);
+void GradientTexture2DEdit::set_fill_pos(const Vector2 &p_pos) {
+ if (p_pos.is_equal_approx(initial_grab_pos)) {
+ return;
}
- String property_name = handle == HANDLE_FILL_FROM ? "fill_from" : "fill_to";
-
+ const StringName property_name = (grabbed == HANDLE_FROM) ? "fill_from" : "fill_to";
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
- undo_redo->create_action(vformat(TTR("Set %s"), property_name), UndoRedo::MERGE_ENDS);
- undo_redo->add_do_property(texture.ptr(), property_name, percent);
- undo_redo->add_undo_property(texture.ptr(), property_name, handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to());
+ undo_redo->create_action(TTR("Move GradientTexture2D Fill Point"));
+ undo_redo->add_do_property(texture.ptr(), property_name, p_pos);
+ undo_redo->add_undo_property(texture.ptr(), property_name, initial_grab_pos);
undo_redo->commit_action();
}
-void GradientTexture2DEditorRect::gui_input(const Ref<InputEvent> &p_event) {
- // Grab/release handle.
+void GradientTexture2DEdit::gui_input(const Ref<InputEvent> &p_event) {
const Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
- if (mb->is_pressed()) {
- Point2 mouse_position = mb->get_position() - offset;
- if (Rect2(_get_handle_position(HANDLE_FILL_FROM).round() - handle_size / 2, handle_size).has_point(mouse_position)) {
- handle = HANDLE_FILL_FROM;
- } else if (Rect2(_get_handle_position(HANDLE_FILL_TO).round() - handle_size / 2, handle_size).has_point(mouse_position)) {
- handle = HANDLE_FILL_TO;
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == MouseButton::LEFT) {
+ if (mb->is_pressed()) {
+ grabbed = get_handle_at(mb->get_position() - offset);
+
+ if (grabbed != HANDLE_NONE) {
+ initial_grab_pos = _get_handle_pos(grabbed) / size;
+ queue_redraw();
+ }
} else {
- handle = HANDLE_NONE;
+ // Release the handle.
+ if (grabbed != HANDLE_NONE) {
+ set_fill_pos(_get_handle_pos(grabbed) / size);
+ grabbed = HANDLE_NONE;
+ queue_redraw();
+ }
}
- } else {
- _update_fill_position();
- handle = HANDLE_NONE;
+ }
+
+ if (grabbed != HANDLE_NONE && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) {
+ texture->set((grabbed == HANDLE_FROM) ? SNAME("fill_from") : SNAME("fill_to"), initial_grab_pos);
+ grabbed = HANDLE_NONE;
+ queue_redraw();
}
}
// Move handle.
const Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
- _update_fill_position();
+ Vector2 mpos = mm->get_position() - offset;
+
+ Handle handle_at_mpos = get_handle_at(mpos);
+ if (hovered != handle_at_mpos) {
+ hovered = handle_at_mpos;
+ queue_redraw();
+ }
+
+ if (grabbed == HANDLE_NONE) {
+ return;
+ }
+
+ Vector2 new_pos = (mpos / size).clamp(Vector2(0, 0), Vector2(1, 1));
+ if (snap_enabled || mm->is_ctrl_pressed()) {
+ new_pos = new_pos.snapped(Vector2(1.0 / snap_count, 1.0 / snap_count));
+ }
+
+ // Allow to snap to an axis with Shift.
+ if (mm->is_shift_pressed()) {
+ Vector2 initial_mpos = initial_grab_pos * size;
+ if (Math::abs(mpos.x - initial_mpos.x) > Math::abs(mpos.y - initial_mpos.y)) {
+ new_pos.y = initial_grab_pos.y;
+ } else {
+ new_pos.x = initial_grab_pos.x;
+ }
+ }
+ // Do it directly from the texture so there's no undo/redo until the handle is released.
+ texture->set((grabbed == HANDLE_FROM) ? SNAME("fill_from") : SNAME("fill_to"), new_pos);
}
}
-void GradientTexture2DEditorRect::set_texture(Ref<GradientTexture2D> &p_texture) {
+void GradientTexture2DEdit::set_texture(Ref<GradientTexture2D> &p_texture) {
texture = p_texture;
texture->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
}
-void GradientTexture2DEditorRect::set_snap_enabled(bool p_snap_enabled) {
+void GradientTexture2DEdit::set_snap_enabled(bool p_snap_enabled) {
snap_enabled = p_snap_enabled;
queue_redraw();
+ if (texture.is_valid()) {
+ if (snap_enabled) {
+ texture->set_meta(SNAME("_snap_enabled"), true);
+ } else {
+ texture->remove_meta(SNAME("_snap_enabled"));
+ }
+ }
}
-void GradientTexture2DEditorRect::set_snap_size(float p_snap_size) {
- snap_size = p_snap_size;
+void GradientTexture2DEdit::set_snap_count(int p_snap_count) {
+ snap_count = p_snap_count;
queue_redraw();
+ if (texture.is_valid()) {
+ if (snap_count != GradientTexture2DEditor::DEFAULT_SNAP) {
+ texture->set_meta(SNAME("_snap_count"), snap_count);
+ } else {
+ texture->remove_meta(SNAME("_snap_count"));
+ }
+ }
}
-void GradientTexture2DEditorRect::_notification(int p_what) {
+void GradientTexture2DEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
+ connect("mouse_exited", callable_mp(this, &GradientTexture2DEdit::_on_mouse_exited));
+ [[fallthrough]];
case NOTIFICATION_THEME_CHANGED: {
checkerboard->set_texture(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")));
} break;
-
case NOTIFICATION_DRAW: {
- if (texture.is_null()) {
- return;
- }
-
- const Ref<Texture2D> fill_from_icon = get_theme_icon(SNAME("EditorPathSmoothHandle"), SNAME("EditorIcons"));
- const Ref<Texture2D> fill_to_icon = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
- handle_size = fill_from_icon->get_size();
-
- Size2 rect_size = get_size();
-
- // Get the size and position to draw the texture and handles at.
- // Subtract handle sizes so they stay inside the preview, but keep the texture's aspect ratio.
- Size2 available_size = rect_size - handle_size;
- Size2 ratio = available_size / texture->get_size();
- size = MIN(ratio.x, ratio.y) * texture->get_size();
- offset = ((rect_size - size) / 2).round();
-
- checkerboard->set_rect(Rect2(offset, size));
-
- draw_set_transform(offset);
- draw_texture_rect(texture, Rect2(Point2(), size));
-
- // Draw grid snap lines.
- if (snap_enabled) {
- const Color primary_line_color = Color(0.5, 0.5, 0.5, 0.9);
- const Color line_color = Color(0.5, 0.5, 0.5, 0.5);
+ _draw();
+ } break;
+ }
+}
- // Draw border and centered axis lines.
- draw_rect(Rect2(Point2(), size), primary_line_color, false);
- draw_line(Point2(size.width / 2, 0), Point2(size.width / 2, size.height), primary_line_color);
- draw_line(Point2(0, size.height / 2), Point2(size.width, size.height / 2), primary_line_color);
+void GradientTexture2DEdit::_draw() {
+ if (texture.is_null()) {
+ return;
+ }
- // Draw vertical lines.
- int prev_idx = 0;
- for (int x = 0; x < size.width; x++) {
- int idx = int((x / size.width - 0.5) / snap_size);
+ const Ref<Texture2D> fill_from_icon = get_theme_icon(SNAME("EditorPathSmoothHandle"), SNAME("EditorIcons"));
+ const Ref<Texture2D> fill_to_icon = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
+ handle_size = fill_from_icon->get_size();
- if (x > 0 && prev_idx != idx) {
- draw_line(Point2(x, 0), Point2(x, size.height), line_color);
- }
+ Size2 rect_size = get_size();
- prev_idx = idx;
- }
+ // Get the size and position to draw the texture and handles at.
+ // Subtract handle sizes so they stay inside the preview, but keep the texture's aspect ratio.
+ Size2 available_size = rect_size - handle_size;
+ Size2 ratio = available_size / texture->get_size();
+ size = MIN(ratio.x, ratio.y) * texture->get_size();
+ offset = ((rect_size - size) / 2).round();
- // Draw horizontal lines.
- prev_idx = 0;
- for (int y = 0; y < size.height; y++) {
- int idx = int((y / size.height - 0.5) / snap_size);
+ checkerboard->set_rect(Rect2(offset, size));
- if (y > 0 && prev_idx != idx) {
- draw_line(Point2(0, y), Point2(size.width, y), line_color);
- }
+ draw_set_transform(offset);
+ draw_texture_rect(texture, Rect2(Point2(), size));
- prev_idx = idx;
- }
- }
+ // Draw grid snap lines.
+ if (snap_enabled || (Input::get_singleton()->is_key_pressed(Key::CTRL) && grabbed != HANDLE_NONE)) {
+ const Color line_color = Color(0.5, 0.5, 0.5, 0.5);
- // Draw handles.
- draw_texture(fill_from_icon, (_get_handle_position(HANDLE_FILL_FROM) - handle_size / 2).round());
- draw_texture(fill_to_icon, (_get_handle_position(HANDLE_FILL_TO) - handle_size / 2).round());
- } break;
+ for (int idx = 0; idx < snap_count + 1; idx++) {
+ float x = float(idx * size.width) / snap_count;
+ float y = float(idx * size.height) / snap_count;
+ draw_line(Point2(x, 0), Point2(x, size.height), line_color);
+ draw_line(Point2(0, y), Point2(size.width, y), line_color);
+ }
}
+
+ // Draw handles.
+ const Color focus_modulate = Color(0.5, 1, 2);
+ bool modulate_handle_from = grabbed == HANDLE_FROM || (grabbed != HANDLE_FROM && hovered == HANDLE_FROM);
+ bool modulate_handle_to = grabbed == HANDLE_TO || (grabbed != HANDLE_TO && hovered == HANDLE_TO);
+ draw_texture(fill_from_icon, (_get_handle_pos(HANDLE_FROM) - handle_size / 2).round(), modulate_handle_from ? focus_modulate : Color(1, 1, 1));
+ draw_texture(fill_to_icon, (_get_handle_pos(HANDLE_TO) - handle_size / 2).round(), modulate_handle_to ? focus_modulate : Color(1, 1, 1));
}
-GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
+GradientTexture2DEdit::GradientTexture2DEdit() {
checkerboard = memnew(TextureRect);
checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
checkerboard->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
@@ -189,6 +235,8 @@ GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
///////////////////////
+const int GradientTexture2DEditor::DEFAULT_SNAP = 10;
+
void GradientTexture2DEditor::_reverse_button_pressed() {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Swap GradientTexture2D Fill Points"));
@@ -201,12 +249,11 @@ void GradientTexture2DEditor::_reverse_button_pressed() {
void GradientTexture2DEditor::_set_snap_enabled(bool p_enabled) {
texture_editor_rect->set_snap_enabled(p_enabled);
-
- snap_size_edit->set_visible(p_enabled);
+ snap_count_edit->set_visible(p_enabled);
}
-void GradientTexture2DEditor::_set_snap_size(float p_snap_size) {
- texture_editor_rect->set_snap_size(MAX(p_snap_size, 0.01));
+void GradientTexture2DEditor::_set_snap_count(int p_snap_count) {
+ texture_editor_rect->set_snap_count(p_snap_count);
}
void GradientTexture2DEditor::set_texture(Ref<GradientTexture2D> &p_texture) {
@@ -221,6 +268,11 @@ void GradientTexture2DEditor::_notification(int p_what) {
reverse_button->set_icon(get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons")));
snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
} break;
+ case NOTIFICATION_READY: {
+ // Set snapping settings based on the texture's meta.
+ snap_button->set_pressed(texture->get_meta("_snap_enabled", false));
+ snap_count_edit->set_value(texture->get_meta("_snap_count", DEFAULT_SNAP));
+ } break;
}
}
@@ -241,21 +293,20 @@ GradientTexture2DEditor::GradientTexture2DEditor() {
toolbar->add_child(snap_button);
snap_button->connect("toggled", callable_mp(this, &GradientTexture2DEditor::_set_snap_enabled));
- snap_size_edit = memnew(EditorSpinSlider);
- snap_size_edit->set_min(0.01);
- snap_size_edit->set_max(0.5);
- snap_size_edit->set_step(0.01);
- snap_size_edit->set_value(0.1);
- snap_size_edit->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
- toolbar->add_child(snap_size_edit);
- snap_size_edit->connect("value_changed", callable_mp(this, &GradientTexture2DEditor::_set_snap_size));
+ snap_count_edit = memnew(EditorSpinSlider);
+ snap_count_edit->set_min(2);
+ snap_count_edit->set_max(100);
+ snap_count_edit->set_value(DEFAULT_SNAP);
+ snap_count_edit->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ toolbar->add_child(snap_count_edit);
+ snap_count_edit->connect("value_changed", callable_mp(this, &GradientTexture2DEditor::_set_snap_count));
- texture_editor_rect = memnew(GradientTexture2DEditorRect);
+ texture_editor_rect = memnew(GradientTexture2DEdit);
add_child(texture_editor_rect);
set_mouse_filter(MOUSE_FILTER_STOP);
_set_snap_enabled(snap_button->is_pressed());
- _set_snap_size(snap_size_edit->get_value());
+ _set_snap_count(snap_count_edit->get_value());
}
///////////////////////
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.h b/editor/plugins/gradient_texture_2d_editor_plugin.h
index 0b496b210e..5f693f5873 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.h
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.h
@@ -37,39 +37,48 @@
class Button;
class EditorSpinSlider;
-class GradientTexture2DEditorRect : public Control {
- GDCLASS(GradientTexture2DEditorRect, Control);
+class GradientTexture2DEdit : public Control {
+ GDCLASS(GradientTexture2DEdit, Control);
enum Handle {
HANDLE_NONE,
- HANDLE_FILL_FROM,
- HANDLE_FILL_TO
+ HANDLE_FROM,
+ HANDLE_TO
};
Ref<GradientTexture2D> texture;
bool snap_enabled = false;
- float snap_size = 0;
+ int snap_count = 0;
TextureRect *checkerboard = nullptr;
- Handle handle = HANDLE_NONE;
+ Handle hovered = HANDLE_NONE;
+ Handle grabbed = HANDLE_NONE;
+ Point2 initial_grab_pos;
+
Size2 handle_size;
Point2 offset;
Size2 size;
- Point2 _get_handle_position(const Handle p_handle);
- void _update_fill_position();
+ Point2 _get_handle_pos(const Handle p_handle);
+ Handle get_handle_at(const Vector2 &p_pos);
+ void set_fill_pos(const Vector2 &p_pos);
+
virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ void _on_mouse_exited();
+
+ void _draw();
+
protected:
void _notification(int p_what);
public:
void set_texture(Ref<GradientTexture2D> &p_texture);
void set_snap_enabled(bool p_snap_enabled);
- void set_snap_size(float p_snap_size);
+ void set_snap_count(int p_snap_count);
- GradientTexture2DEditorRect();
+ GradientTexture2DEdit();
};
class GradientTexture2DEditor : public VBoxContainer {
@@ -79,17 +88,18 @@ class GradientTexture2DEditor : public VBoxContainer {
Button *reverse_button = nullptr;
Button *snap_button = nullptr;
- EditorSpinSlider *snap_size_edit = nullptr;
- GradientTexture2DEditorRect *texture_editor_rect = nullptr;
+ EditorSpinSlider *snap_count_edit = nullptr;
+ GradientTexture2DEdit *texture_editor_rect = nullptr;
void _reverse_button_pressed();
void _set_snap_enabled(bool p_enabled);
- void _set_snap_size(float p_snap_size);
+ void _set_snap_count(int p_snap_count);
protected:
void _notification(int p_what);
public:
+ static const int DEFAULT_SNAP;
void set_texture(Ref<GradientTexture2D> &p_texture);
GradientTexture2DEditor();
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 6094b5bef6..09b0864559 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -169,7 +169,7 @@ void EditorPropertyRootMotion::_node_clear() {
}
void EditorPropertyRootMotion::update_property() {
- NodePath p = get_edited_object()->get(get_edited_property());
+ NodePath p = get_edited_property_value();
assign->set_tooltip_text(p);
if (p == NodePath()) {
assign->set_icon(Ref<Texture2D>());
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index e7d2d7a11f..b27bd49266 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -265,13 +265,20 @@ void ShaderEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
for (int i = 0; i < shader_tabs->get_tab_count(); i++) {
EditedShader edited_shader = edited_shaders[i];
if (edited_shader.shader_editor || edited_shader.visual_shader_editor) {
- shaders.push_back(edited_shader.shader->get_path());
+ String shader_path;
+ if (edited_shader.shader.is_valid()) {
+ shader_path = edited_shader.shader->get_path();
+ } else {
+ DEV_ASSERT(edited_shader.shader_inc.is_valid());
+ shader_path = edited_shader.shader_inc->get_path();
+ }
+ shaders.push_back(shader_path);
TextShaderEditor *shader_editor = Object::cast_to<TextShaderEditor>(shader_tabs->get_current_tab_control());
VisualShaderEditor *visual_shader_editor = Object::cast_to<VisualShaderEditor>(shader_tabs->get_current_tab_control());
if ((shader_editor && edited_shader.shader_editor == shader_editor) || (visual_shader_editor && edited_shader.visual_shader_editor == visual_shader_editor)) {
- selected_shader = edited_shader.shader->get_path();
+ selected_shader = shader_path;
}
}
}
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index f958e83b4d..a91ee9fa6c 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -105,10 +105,11 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla
// Create tiles and alternatives, then copy their properties.
for (int alternative_index = 0; alternative_index < atlas_source->get_alternative_tiles_count(tile_mapping.key); alternative_index++) {
int alternative_id = atlas_source->get_alternative_tile_id(tile_mapping.key, alternative_index);
+ int changed_id = -1;
if (alternative_id == 0) {
merged->create_tile(tile_mapping.value, atlas_source->get_tile_size_in_atlas(tile_mapping.key));
} else {
- merged->create_alternative_tile(tile_mapping.value, alternative_index);
+ changed_id = merged->create_alternative_tile(tile_mapping.value, alternative_index);
}
// Copy the properties.
@@ -116,7 +117,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla
List<PropertyInfo> properties;
src_tile_data->get_property_list(&properties);
- TileData *dst_tile_data = merged->get_tile_data(tile_mapping.value, alternative_id);
+ TileData *dst_tile_data = merged->get_tile_data(tile_mapping.value, changed_id == -1 ? alternative_id : changed_id);
for (PropertyInfo property : properties) {
if (!(property.usage & PROPERTY_USAGE_STORAGE)) {
continue;
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index a8c3b8e8d5..cc9ba25f46 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -271,10 +271,10 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na
} else {
if (components[1] == "duration") {
tile_set_atlas_source->set_tile_animation_frame_duration(tile.tile, frame, p_value);
- return true;
}
}
}
+ return true;
}
}
@@ -2719,14 +2719,14 @@ void EditorPropertyTilePolygon::update_property() {
if (String(count_property).is_empty()) {
if (base_type == "OccluderPolygon2D") {
// Single OccluderPolygon2D.
- Ref<OccluderPolygon2D> occluder = get_edited_object()->get(get_edited_property());
+ Ref<OccluderPolygon2D> occluder = get_edited_property_value();
generic_tile_polygon_editor->clear_polygons();
if (occluder.is_valid()) {
generic_tile_polygon_editor->add_polygon(occluder->get_polygon());
}
} else if (base_type == "NavigationPolygon") {
// Single OccluderPolygon2D.
- Ref<NavigationPolygon> navigation_polygon = get_edited_object()->get(get_edited_property());
+ Ref<NavigationPolygon> navigation_polygon = get_edited_property_value();
generic_tile_polygon_editor->clear_polygons();
if (navigation_polygon.is_valid()) {
for (int i = 0; i < navigation_polygon->get_outline_count(); i++) {
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 8ae7aaa380..89f1f86461 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/os/keyboard.h"
#include "core/os/time.h"
#include "editor/editor_file_system.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -942,7 +943,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
metadata_dialog->set_title(TTR("Create Version Control Metadata"));
metadata_dialog->set_min_size(Size2(200, 40));
metadata_dialog->get_ok_button()->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_create_vcs_metadata_files));
- add_child(metadata_dialog);
+ EditorInterface::get_singleton()->get_base_control()->add_child(metadata_dialog);
VBoxContainer *metadata_vb = memnew(VBoxContainer);
metadata_dialog->add_child(metadata_vb);
@@ -971,7 +972,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
set_up_dialog->set_min_size(Size2(600, 100));
set_up_dialog->add_cancel_button("Cancel");
set_up_dialog->set_hide_on_ok(true);
- add_child(set_up_dialog);
+ EditorInterface::get_singleton()->get_base_control()->add_child(set_up_dialog);
Button *set_up_apply_button = set_up_dialog->get_ok_button();
set_up_apply_button->set_text(TTR("Apply"));
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index db9c7098a6..890194dbac 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -6620,7 +6620,7 @@ void EditorPropertyVisualShaderMode::_option_selected(int p_which) {
}
void EditorPropertyVisualShaderMode::update_property() {
- int which = get_edited_object()->get(get_edited_property());
+ int which = get_edited_property_value();
options->select(which);
}
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index 6c63f0ba6a..e5db5f9d30 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -134,29 +134,21 @@ void BackgroundProgress::end_task(const String &p_task) {
ProgressDialog *ProgressDialog::singleton = nullptr;
-void ProgressDialog::_notification(int p_what) {
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- if (!is_visible()) {
- Node *p = get_parent();
- if (p) {
- p->remove_child(this);
- }
- }
- }
-}
-
void ProgressDialog::_popup() {
Size2 ms = main->get_combined_minimum_size();
ms.width = MAX(500 * EDSCALE, ms.width);
Ref<StyleBox> style = main->get_theme_stylebox(SNAME("panel"), SNAME("PopupMenu"));
ms += style->get_minimum_size();
+
main->set_offset(SIDE_LEFT, style->get_margin(SIDE_LEFT));
main->set_offset(SIDE_RIGHT, -style->get_margin(SIDE_RIGHT));
main->set_offset(SIDE_TOP, style->get_margin(SIDE_TOP));
main->set_offset(SIDE_BOTTOM, -style->get_margin(SIDE_BOTTOM));
- EditorInterface::get_singleton()->popup_dialog_centered(this, ms);
+ if (!is_inside_tree()) {
+ EditorInterface::get_singleton()->popup_dialog_centered(this, ms);
+ }
}
void ProgressDialog::add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
diff --git a/editor/progress_dialog.h b/editor/progress_dialog.h
index 7ac4864c9c..ae47e5f25c 100644
--- a/editor/progress_dialog.h
+++ b/editor/progress_dialog.h
@@ -88,7 +88,6 @@ class ProgressDialog : public PopupPanel {
bool canceled = false;
protected:
- void _notification(int p_what);
static void _bind_methods();
public:
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 032f3875bf..4b66193678 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -3578,6 +3578,13 @@ void SceneTreeDock::_list_all_subresources(PopupMenu *p_menu) {
p_menu->set_item_metadata(-1, pair.first->get_instance_id());
}
}
+
+ if (resources_by_type.is_empty()) {
+ p_menu->add_item(TTR("None"));
+ p_menu->set_item_disabled(-1, true);
+ }
+
+ p_menu->reset_size();
}
void SceneTreeDock::_gather_resources(Node *p_node, List<Pair<Ref<Resource>, Node *>> &r_resources) {
diff --git a/main/main.cpp b/main/main.cpp
index ec35b33321..68c977e9b7 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -459,7 +459,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
- OS::get_singleton()->print(" --debug-avoidance Show navigation polygons when running the scene.\n");
+ OS::get_singleton()->print(" --debug-avoidance Show navigation avoidance debug visuals when running the scene.\n");
OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
#endif
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
diff --git a/misc/extension_api_validation/4.0-stable.expected b/misc/extension_api_validation/4.0-stable.expected
index 7868fe39cf..88d41160ce 100644
--- a/misc/extension_api_validation/4.0-stable.expected
+++ b/misc/extension_api_validation/4.0-stable.expected
@@ -23,35 +23,35 @@ The previous type was simply wrong and didn't match the actual C++ definition. C
GH-74600
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimatedSprite2D/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimatedSprite3D/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Animation/methods/compress'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimationPlayer/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AudioStreamPlayer/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AudioStreamPlayer2D/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AudioStreamPlayer3D/methods/play'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/CanvasItem/methods/draw_set_transform'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve2D/methods/sample_baked'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve2D/methods/sample_baked_with_rotation'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve2D/methods/tessellate_even_length'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve3D/methods/sample_baked'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve3D/methods/sample_baked_with_rotation'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Curve3D/methods/tessellate_even_length'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/DisplayServer/methods/tts_speak'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Font/methods/find_variation'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/GridMap/methods/make_baked_meshes'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Image/methods/save_jpg_to_buffer'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Image/methods/save_webp_to_buffer'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Image/methods/bump_map_to_normal_map'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/PhysicsBody2D/methods/move_and_collide'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/PhysicsBody3D/methods/move_and_collide'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/PhysicsBody3D/methods/test_move'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RandomNumberGenerator/methods/randfn'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RenderingServer/methods/environment_set_ambient_light'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RenderingServer/methods/canvas_item_set_canvas_group_mode'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RenderingServer/methods/force_draw'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Window/methods/popup_centered_ratio'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Window/methods/popup_centered_clamped'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimatedSprite2D/methods/play', from 57037631 to 8D62DD1B. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimatedSprite3D/methods/play', from 57037631 to 8D62DD1B. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Animation/methods/compress', from 6B87C27F to D713F035. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimationPlayer/methods/play', from 846788DD to B9DCE17F. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AudioStreamPlayer/methods/play', from B54BA998 to 74B7272C. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AudioStreamPlayer2D/methods/play', from B54BA998 to 74B7272C. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AudioStreamPlayer3D/methods/play', from B54BA998 to 74B7272C. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/CanvasItem/methods/draw_set_transform', from F93CB735 to C3BC1B8B. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve2D/methods/sample_baked', from DF8CB3E7 to CE7C60AA. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve2D/methods/sample_baked_with_rotation', from 0F34F230 to C475D415. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve2D/methods/tessellate_even_length', from FC150C61 to 8A44C0E5. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve3D/methods/sample_baked', from FCBE3242 to 5078AD06. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve3D/methods/sample_baked_with_rotation', from 9431C26F to 7398459B. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Curve3D/methods/tessellate_even_length', from E96241BB to 07F10939. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/DisplayServer/methods/tts_speak', from DDE9B9D7 to DEFE6FA5. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Font/methods/find_variation', from DCDAC3C2 to 44828B18. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/GridMap/methods/make_baked_meshes', from 43AF36C6 to D72155A9. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Image/methods/bump_map_to_normal_map', from 1412C0CC to CC0E637C. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Image/methods/save_jpg_to_buffer', from 1285A12B to 234CCB09. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Image/methods/save_webp_to_buffer', from 49A857C1 to 4865C18E. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/PhysicsBody2D/methods/move_and_collide', from BE9F4C70 to 5B315D1A. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/PhysicsBody3D/methods/move_and_collide', from 44022073 to A86CD3DE. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/PhysicsBody3D/methods/test_move', from 7C246CBB to 288C8CC1. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RandomNumberGenerator/methods/randfn', from 839678C5 to 31E8912C. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RenderingServer/methods/canvas_item_set_canvas_group_mode', from 5D7655F8 to 0280768A. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RenderingServer/methods/environment_set_ambient_light', from 159C6D6E to 1D4E1F3F. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RenderingServer/methods/force_draw', from 359658A7 to 40254980. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Window/methods/popup_centered_clamped', from DE3D691D to 9BCAB29D. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Window/methods/popup_centered_ratio', from 71F7FFC1 to 3C7CD915. This means that the function has changed and no compatibility function was provided.
None of these methods were actually changed, the hash changes only affects GDExtensions, no compatibility workaround exists currently.
@@ -105,98 +105,169 @@ Unsure where these come from; when dumping the interface, these do actually stil
GH-76176
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_base_control'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_edited_scene_root'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_editor_main_screen'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_editor_paths'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_editor_settings'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_file_system_dock'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_resource_filesystem'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_resource_previewer'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_script_editor'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorInterface/methods/get_selection'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_base_control', from 31757941 to A5E188F5. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_edited_scene_root', from 6C6B0707 to BC5DCFF4. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_editor_main_screen', from 36955D8D to 65B2D3B5. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_editor_paths', from FA334A57 to 5F1D5DC4. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_editor_settings', from 932B4D2E to F399A3EB. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_file_system_dock', from 217210BD to DF93E7E7. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_resource_filesystem', from 1D5C1A47 to 2E802B7E. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_resource_previewer', from 5E161783 to 383C77ED. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_script_editor', from EB48A7D4 to 056A8923. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorInterface/methods/get_selection', from 0302AF0B to A05A4D13. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_base_control': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_edited_scene_root': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_editor_main_screen': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_editor_paths': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_editor_settings': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_file_system_dock': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_resource_filesystem': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_resource_previewer': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_script_editor': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorInterface/methods/get_selection': is_const changed value in new API, from false to true.
Functions were made `const`. No adjustments should be necessary.
GH-76026
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorScript/methods/get_editor_interface'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/EditorScript/methods/get_scene'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorScript/methods/get_editor_interface', from FBC1084A to 75D179CC. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/EditorScript/methods/get_scene', from 6C6B0707 to BC5DCFF4. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/EditorScript/methods/get_editor_interface': is_const changed value in new API, from false to true.
+Validate extension JSON: Error: Field 'classes/EditorScript/methods/get_scene': is_const changed value in new API, from false to true.
Functions were made `const`. No adjustments should be necessary.
GH-76418
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/Object/methods/get_meta_list'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimationNodeStateMachinePlayback/methods/get_travel_path'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RDShaderFile/methods/get_version_list'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/RenderingServer/methods/global_shader_parameter_get_list'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimationNodeStateMachinePlayback/methods/get_travel_path', from 43F252E9 to EE2D1D98. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Object/methods/get_meta_list', from 43F252E9 to EE2D1D98. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RDShaderFile/methods/get_version_list', from 43F252E9 to EE2D1D98. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RenderingServer/methods/global_shader_parameter_get_list', from 43F252E9 to EE2D1D98. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/AnimationNodeStateMachinePlayback/methods/get_travel_path/return_value': type changed value in new API, from "PackedStringArray" to "typedarray::StringName".
+Validate extension JSON: Error: Field 'classes/Object/methods/get_meta_list/return_value': type changed value in new API, from "PackedStringArray" to "typedarray::StringName".
+Validate extension JSON: Error: Field 'classes/RDShaderFile/methods/get_version_list/return_value': type changed value in new API, from "PackedStringArray" to "typedarray::StringName".
+Validate extension JSON: Error: Field 'classes/RenderingServer/methods/global_shader_parameter_get_list/return_value': type changed value in new API, from "PackedStringArray" to "typedarray::StringName".
+
+Validate extension JSON: Error: Field 'classes/Geometry3D/methods/segment_intersects_convex/arguments/2': type changed value in new API, from "Array" to "typedarray::Plane".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/9': type changed value in new API, from "Array" to "typedarray::RID".
+Validate extension JSON: Error: Field 'classes/SurfaceTool/methods/add_triangle_fan/arguments/5': default_value changed value in new API, from "[]" to "Array[Plane]([])".
+Validate extension JSON: Error: Field 'classes/SurfaceTool/methods/add_triangle_fan/arguments/5': type changed value in new API, from "Array" to "typedarray::Plane".
Return types change, fixed some internal type issues and unnecessarily changed the public type in the process.
GH-72749
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/Area2D/methods/get_priority'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Area2D/methods/set_priority'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Area3D/methods/get_priority'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Area3D/methods/set_priority'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Area2D/methods/get_priority', from 67C0E66E to E8C5525A. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Area2D/methods/set_priority', from 1647D661 to 4CAD1009. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Area3D/methods/get_priority', from 67C0E66E to E8C5525A. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Area3D/methods/set_priority', from 1647D661 to 4CAD1009. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/Area2D/methods/get_priority/return_value': meta changed value in new API, from "float" to "int32".
+Validate extension JSON: Error: Field 'classes/Area2D/methods/get_priority/return_value': type changed value in new API, from "float" to "int".
+Validate extension JSON: Error: Field 'classes/Area2D/methods/set_priority/arguments/0': meta changed value in new API, from "float" to "int32".
+Validate extension JSON: Error: Field 'classes/Area2D/methods/set_priority/arguments/0': type changed value in new API, from "float" to "int".
+Validate extension JSON: Error: Field 'classes/Area3D/methods/get_priority/return_value': meta changed value in new API, from "float" to "int32".
+Validate extension JSON: Error: Field 'classes/Area3D/methods/get_priority/return_value': type changed value in new API, from "float" to "int".
+Validate extension JSON: Error: Field 'classes/Area3D/methods/set_priority/arguments/0': meta changed value in new API, from "float" to "int32".
+Validate extension JSON: Error: Field 'classes/Area3D/methods/set_priority/arguments/0': type changed value in new API, from "float" to "int".
Type changed from `float` to `int`. Previously the `float` values were internally converted to `int`s anyways and the type ways inconsistent with the type of the priority property, which already was `int`.
GH-72152
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/MeshInstance3D/methods/create_multiple_convex_collisions'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/MeshInstance3D/methods/create_multiple_convex_collisions', from BFDD6D64 to 257A91A5. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/MeshInstance3D/methods/create_multiple_convex_collisions': arguments
Added an optional parameter with a default value. No adjustments should be necessary.
GH-75759
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimationNode/methods/blend_input'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/AnimationNode/methods/blend_node'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimationNode/methods/blend_input', from 5162412C to A178F700. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/AnimationNode/methods/blend_node', from 1263CBA5 to 0FB30106. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/AnimationNode/methods/_process/arguments': size changed value in new API, from 3 to 4.
+Validate extension JSON: Error: Field 'classes/AnimationNode/methods/blend_input/arguments': size changed value in new API, from 7 to 8.
+Validate extension JSON: Error: Field 'classes/AnimationNode/methods/blend_node/arguments': size changed value in new API, from 8 to 9.
-Added an optional parameter with a default value. No adjustments should be necessary.
+`_process`: Added a parameter to a virtual method.
+`blend_input`, `blend_node`: Added an optional parameter with a default value. No adjustments should be necessary.
GH-75017
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/RichTextLabel/methods/push_list'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/RichTextLabel/methods/push_list', from 8593DF77 to F0951C19. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/push_list/arguments': size changed value in new API, from 3 to 4.
Added an optional parameter with a default value. No adjustments should be necessary.
GH-76794
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/Tree/methods/edit_selected'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Tree/methods/edit_selected', from 859196D4 to 9AB67ACD. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/Tree/methods/edit_selected': arguments
Added an optional parameter with a default value. No adjustments should be necessary.
GH-75777
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/SyntaxHighlighter/methods/get_text_edit'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/SyntaxHighlighter/methods/get_text_edit', from 8248B40D to 70D54D11. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/SyntaxHighlighter/methods/get_text_edit': is_const changed value in new API, from false to true.
Function was made `const`. No adjustments should be necessary.
-GH-75250
---------
-Validate extension JSON: Error: Hash mismatch for 'classes/RichTextLabel/methods/push_paragraph'. This means that the function has changed and no compatibility function was provided.
-Added an optional parameter with a default value. No adjustments should be necessary.
+GH-75250 & GH-76401
+-------------------
+Validate extension JSON: Error: Hash changed for 'classes/RichTextLabel/methods/push_paragraph', from 3DD1D1C2 to BFDC71FE. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/push_paragraph/arguments': size changed value in new API, from 4 to 6.
+
+Added a optional parameters with default values. No adjustments should be necessary.
GH-77143
--------
-Validate extension JSON: Error: Hash mismatch for 'classes/WorkerThreadPool/methods/wait_for_task_completion'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/WorkerThreadPool/methods/wait_for_task_completion', from 4CAD1009 to 32573865. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/WorkerThreadPool/methods/wait_for_task_completion': return_value
Changed the return value from `void` to `Error`. No adjustments should be necessary.
+GH-64628
+--------
+Validate extension JSON: Error: Field 'classes/EditorResourcePreviewGenerator/methods/_generate/arguments': size changed value in new API, from 2 to 3.
+Validate extension JSON: Error: Field 'classes/EditorResourcePreviewGenerator/methods/_generate_from_path/arguments': size changed value in new API, from 2 to 3.
+
+Added parameters to virtual method.
+
+
+GH-76406
+--------
+Validate extension JSON: Error: Field 'classes/GDExtension/methods/open_library/arguments': size changed value in new API, from 2 to 3.
+
+Added an optional parameter with a default value. No adjustments should be necessary.
+
+
+GH-74242
+--------
+Validate extension JSON: Error: Field 'classes/PhysicsDirectSpaceState3DExtension/methods/_intersect_ray/arguments': size changed value in new API, from 8 to 9.
+Validate extension JSON: Error: Field 'classes/PhysicsDirectSpaceState3DExtension/methods/_intersect_ray/arguments/7': type changed value in new API, from "PhysicsServer3DExtensionRayResult*" to "bool".
+
+Added new second-to-last parameter to virtual method.
+
+
+GH-74707
+--------
+Validate extension JSON: Error: Field 'classes/PhysicsServer3DExtension/methods/_body_test_motion/arguments': size changed value in new API, from 7 to 8.
+Validate extension JSON: Error: Field 'classes/PhysicsServer3DExtension/methods/_body_test_motion/arguments/6': type changed value in new API, from "PhysicsServer3DExtensionMotionResult*" to "bool".
+
+Added new second-to-last parameter to virtual method.
+
+
GH-72842
--------
Validate extension JSON: API was removed: classes/PathFollow2D/methods/get_lookahead
@@ -211,9 +282,28 @@ Validate extension JSON: Error: Field 'classes/GLTFSkin/properties/godot_skin':
GH-76082
--------
-Validate extension JSON: Error: Hash mismatch for 'builtin_classes/Basis/methods/looking_at'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'builtin_classes/Transform3D/methods/looking_at'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Node3D/methods/look_at'. This means that the function has changed and no compatibility function was provided.
-Validate extension JSON: Error: Hash mismatch for 'classes/Node3D/methods/look_at_from_position'. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'builtin_classes/Basis/methods/looking_at', from 19076B74 to DE3FF159. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'builtin_classes/Transform3D/methods/looking_at', from 3018C31C to 056ADC36. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Node3D/methods/look_at', from 3BC64EA6 to BA2B4FA9. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Hash changed for 'classes/Node3D/methods/look_at_from_position', from 2BD0F953 to F2739FA7. This means that the function has changed and no compatibility function was provided.
+Validate extension JSON: Error: Field 'builtin_classes/Basis/methods/looking_at/arguments': size changed value in new API, from 2 to 3.
+Validate extension JSON: Error: Field 'builtin_classes/Transform3D/methods/looking_at/arguments': size changed value in new API, from 2 to 3.
+Validate extension JSON: Error: Field 'classes/Node3D/methods/look_at/arguments': size changed value in new API, from 2 to 3.
+Validate extension JSON: Error: Field 'classes/Node3D/methods/look_at_from_position/arguments': size changed value in new API, from 3 to 4.
Added an optional parameter with a default value. No adjustments should be necessary.
+
+
+GH-77411
+--------
+Validate extension JSON: Error: Field 'classes/Control/methods/_get_drag_data': is_const changed value in new API, from true to false.
+
+`const` was removed from virtual method, it may be necessary to adjust the constness of implementing methods.
+
+
+GH-75260
+--------
+Validate extension JSON: Error: Field 'classes/PhysicsDirectSpaceState2D/methods/collide_shape/return_value': type changed value in new API, from "typedarray::PackedVector2Array" to "typedarray::Vector2".
+Validate extension JSON: Error: Field 'classes/PhysicsDirectSpaceState3D/methods/collide_shape/return_value': type changed value in new API, from "typedarray::PackedVector3Array" to "typedarray::Vector3".
+
+The previous type declaration was simply wrong and the method did actually already return objects of the new type.
diff --git a/modules/csg/icons/CSGBox3D.svg b/modules/csg/icons/CSGBox3D.svg
index 2740cc2f8c..bb3a1f357a 100644
--- a/modules/csg/icons/CSGBox3D.svg
+++ b/modules/csg/icons/CSGBox3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/><path d="m8 .94531-7 3.5v7.2227l7 3.5.29492-.14844c-.18282-.30101-.29492-.64737-.29492-1.0195v-2c0-.72651.40824-1.3664 1-1.7168v-1.6699l4-2v1.3867h1c.36419 0 .70336.10754 1 .2832v-3.8379zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002z" fill="#fc7f7f" stroke-width="1.0667"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGCapsule3D.svg b/modules/csg/icons/CSGCapsule3D.svg
index db4f71864b..33a2d4a115 100644
--- a/modules/csg/icons/CSGCapsule3D.svg
+++ b/modules/csg/icons/CSGCapsule3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2418-5 4.9902v4.0176c0 2.7484 2.2473 4.9922 5 4.9922.092943 0 .18367-.008623.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72887.41095-1.3691 1.0059-1.7188v-.28125c.34771-.034464.68259-.10691 1.0156-.19922.10394-.99856.95603-1.8008 1.9785-1.8008h1v-2.0098c0-2.7484-2.2473-4.9902-5-4.9902zm-1.0059 2.127v4.8574c-.66556-.1047-1.2974-.37231-1.9941-.66211v-1.3223c0-1.3474.79841-2.4642 1.9941-2.873zm2.0117 0c1.1957.4088 1.9941 1.5256 1.9941 2.873v1.3457c-.68406.3054-1.3142.57292-1.9941.66602v-4.8848zm-4.0059 6.334c.67836.2231 1.3126.44599 1.9941.52539v2.8848c-1.1957-.4092-1.9941-1.5237-1.9941-2.8711v-.53906z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGCombiner3D.svg b/modules/csg/icons/CSGCombiner3D.svg
index 692ba54cb8..8598897e92 100644
--- a/modules/csg/icons/CSGCombiner3D.svg
+++ b/modules/csg/icons/CSGCombiner3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm0 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2z" fill="#fc7f7f"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M3 1a2 2 0 0 0-2 2h2zm2 0v2h2V1zm4 0v2h2V1zm4 0v2h2a2 2 0 0 0-2-2zM1 5v2h2V5zm12 0v2h2V5zM1 9v2h2V9zm0 4a2 2 0 0 0 2 2v-2zm4 0v2h2v-2z" fill="#fc7f7f"/></svg>
diff --git a/modules/csg/icons/CSGCylinder3D.svg b/modules/csg/icons/CSGCylinder3D.svg
index 4bc2427887..29d658dc46 100644
--- a/modules/csg/icons/CSGCylinder3D.svg
+++ b/modules/csg/icons/CSGCylinder3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-1.7469 0-3.328.22648-4.5586.63672-.61528.20512-1.1471.45187-1.5898.80078-.44272.34891-.85156.88101-.85156 1.5625v8c0 .68149.40884 1.2155.85156 1.5645.44272.34891.97457.59577 1.5898.80078 1.2306.41024 2.8117.63477 4.5586.63477.095648 0 .18467-.008426.2793-.009766-.1722-.29446-.2793-.62995-.2793-.99023v-1c-1.5668 0-2.9867-.2195-3.9277-.5332-.46329-.15435-.90474-.33752-1.0723-.4668v-5.8125c.1468.058667.2835.12515.44141.17773 1.2306.41024 2.8117.63477 4.5586.63477s3.328-.22453 4.5586-.63477c.15791-.052267.29461-.11864.44141-.17773v1.8125h1c.36396 0 .70348.10774 1 .2832v-4.2832c0-.68149-.40884-1.2136-.85156-1.5625-.44272-.34891-.97457-.59566-1.5898-.80078-1.2306-.41024-2.8117-.63672-4.5586-.63672zm0 2c1.5668 0 2.9867.22145 3.9277.53516.46368.15456.80138.33741.96875.4668-.16752.12928-.50546.3105-.96875.46484-.94102.31371-2.361.5332-3.9277.5332s-2.9867-.2195-3.9277-.5332c-.46329-.15435-.80123-.33556-.96875-.46484.16737-.12939.50507-.31224.96875-.4668.94102-.31371 2.361-.53516 3.9277-.53516z" fill="#fc7f7f" stroke-width="1.0667" transform="scale(.9375)"/><path d="m11.25 8.4375c-.51938 0-.9375.41812-.9375.9375v.9375h1.875v1.875h.9375c.51938 0 .9375-.41812.9375-.9375v-1.875c0-.51938-.41812-.9375-.9375-.9375zm.9375 3.75h-1.875v-1.875h-.9375c-.51938 0-.9375.41812-.9375.9375v1.875c0 .51938.41812.9375.9375.9375h1.875c.51938 0 .9375-.41812.9375-.9375z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGMesh3D.svg b/modules/csg/icons/CSGMesh3D.svg
index 8f4a1736fb..a1c2282fe5 100644
--- a/modules/csg/icons/CSGMesh3D.svg
+++ b/modules/csg/icons/CSGMesh3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h3.2695v-2h-3.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l4.916 4.916c.31428-.20669.68609-.33008 1.084-.33008 0-.3979.12338-.76971.33008-1.084l-4.916-4.916h5.8574c.17478.30301.42598.55488.72852.73047v3.2695h2v-3.2715c.61771-.35663.99874-1.0152 1-1.7285 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.73 2A2 2 0 1 0 2 4.73v6.541A2 2 0 1 0 4.729 14H8v-2H4.729A2 2 0 0 0 4 11.271V5.415l4.914 4.916A2 2 0 0 1 9.998 10a2 2 0 0 1 .33-1.084L5.414 4h5.856a2 2 0 0 0 .73.729V8h2V4.729A2 2 0 1 0 11.27 2z" fill="#fc7f7f"/><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/></svg>
diff --git a/modules/csg/icons/CSGPolygon3D.svg b/modules/csg/icons/CSGPolygon3D.svg
index 971f3577bb..8d4b61e039 100644
--- a/modules/csg/icons/CSGPolygon3D.svg
+++ b/modules/csg/icons/CSGPolygon3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002c-.14254.00487-.28238.04016-.41016.10352l-6 3c-.33878.16944-.55276.51574-.55273.89453v5.832c-.105.61631.37487 1.1768 1 1.168h5v2c.0000216.67546.64487 1.1297 1.2617.95898-.16118-.28721-.26172-.61135-.26172-.95898v-2c0-.72673.40794-1.3664 1-1.7168v-1.666l4-2v1.3828h1c.36397 0 .70348.10774 1 .2832v-3.2773c.000006-.00195.000006-.0039094 0-.0058594.000026-.37879-.21395-.72509-.55273-.89453l-6-3c-.15022-.074574-.31679-.11017-.48438-.10352zm.037109 2.1172 3.7637 1.8809-2.7637 1.3809v-1.3809c-.0000552-.55226-.44774-.99994-1-1h-1.7617l1.7617-.88086zm-5 2.8809h4v4h-4z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGSphere3D.svg b/modules/csg/icons/CSGSphere3D.svg
index 770af80632..16d45b3c99 100644
--- a/modules/csg/icons/CSGSphere3D.svg
+++ b/modules/csg/icons/CSGSphere3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 .093042 0 .18321-.01004.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72673.40794-1.3664 1-1.7168v-.33398c.34074-.019259.67728-.069097 1.0156-.10547.083091-1.0187.94713-1.8438 1.9844-1.8438h2c.35841 0 .69292.10484.98633.27539.003633-.092184.013672-.18235.013672-.27539 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm-5.7793 6.2988c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg>
diff --git a/modules/csg/icons/CSGTorus3D.svg b/modules/csg/icons/CSGTorus3D.svg
index ece9c68d28..5672244e5c 100644
--- a/modules/csg/icons/CSGTorus3D.svg
+++ b/modules/csg/icons/CSGTorus3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3c-1.8145 0-3.4691.41721-4.7461 1.1621-1.277.745-2.2539 1.9082-2.2539 3.3379 0 1.4298.9769 2.5949 2.2539 3.3398s2.9316 1.1602 4.7461 1.1602c0-1.0907.90931-2 2-2 0-.080836.013744-.15778.023438-.23633-.61769.14673-1.3008.23633-2.0234.23633-1.4992 0-2.8437-.36687-3.7383-.88867-.89456-.5219-1.2617-1.108-1.2617-1.6113 0-.5032.36716-1.0876 1.2617-1.6094.89456-.5219 2.2391-.89062 3.7383-.89062s2.8437.36872 3.7383.89062c.89456.5218 1.2617 1.1062 1.2617 1.6094 0 .15978-.053679.32822-.13281.5h1.1328c.32481 0 .62893.088408.90234.23047.057552-.23582.097656-.47718.097656-.73047 0-1.4297-.9769-2.5929-2.2539-3.3379-1.277-.7449-2.9316-1.1621-4.7461-1.1621z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><ellipse cx="8" cy="7.5" fill="none" rx="6" ry="3.5" stroke="#fc7f7f" stroke-width="2" mask="url(#a)"/></svg>
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index e3f5502391..a40afa702c 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="@GDScript" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
- Built-in GDScript functions.
+ Built-in GDScript constants, functions, and annotations.
</brief_description>
<description>
A list of GDScript-specific utility functions and annotations accessible from any script.
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
index 00d50d1737..3458eb43b5 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
@@ -311,6 +311,14 @@ void GDScriptEditorTranslationParserPlugin::_extract_from_call(GDScriptParser::C
}
}
}
+
+ if (p_call->callee && p_call->callee->type == GDScriptParser::Node::SUBSCRIPT) {
+ GDScriptParser::SubscriptNode *subscript_node = static_cast<GDScriptParser::SubscriptNode *>(p_call->callee);
+ if (subscript_node->base && subscript_node->base->type == GDScriptParser::Node::CALL) {
+ GDScriptParser::CallNode *call_node = static_cast<GDScriptParser::CallNode *>(subscript_node->base);
+ _extract_from_call(call_node);
+ }
+ }
}
void GDScriptEditorTranslationParserPlugin::_extract_fd_literals(GDScriptParser::ExpressionNode *p_expression) {
diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
index 62030c5464..6b8f2aa904 100644
--- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml
+++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
@@ -103,6 +103,17 @@
The return value is used to determine if this [GLTFDocumentExtension] instance should be used for importing a given GLTF file. If [constant OK], the import will use this [GLTFDocumentExtension] instance. If not overridden, [constant OK] is returned.
</description>
</method>
+ <method name="_parse_image_data" qualifiers="virtual">
+ <return type="int" enum="Error" />
+ <param index="0" name="state" type="GLTFState" />
+ <param index="1" name="image_data" type="PackedByteArray" />
+ <param index="2" name="mime_type" type="String" />
+ <param index="3" name="ret_image" type="Image" />
+ <description>
+ Part of the import process. This method is run after [method _parse_node_extensions] and before [method _parse_texture_json].
+ Runs when parsing image data from a GLTF file. The data could be sourced from a separate file, a URI, or a buffer, and then is passed as a byte array.
+ </description>
+ </method>
<method name="_parse_node_extensions" qualifiers="virtual">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
@@ -113,5 +124,15 @@
Runs when parsing the node extensions of a GLTFNode. This method can be used to process the extension JSON data into a format that can be used by [method _generate_scene_node]. The return value should be a member of the [enum Error] enum.
</description>
</method>
+ <method name="_parse_texture_json" qualifiers="virtual">
+ <return type="int" enum="Error" />
+ <param index="0" name="state" type="GLTFState" />
+ <param index="1" name="texture_json" type="Dictionary" />
+ <param index="2" name="ret_gltf_texture" type="GLTFTexture" />
+ <description>
+ Part of the import process. This method is run after [method _parse_image_data] and before [method _generate_scene_node].
+ Runs when parsing the texture JSON from the GLTF textures array. This can be used to set the source image index to use as the texture.
+ </description>
+ </method>
</methods>
</class>
diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml
index b3823ef970..7614839b8b 100644
--- a/modules/gltf/doc_classes/GLTFState.xml
+++ b/modules/gltf/doc_classes/GLTFState.xml
@@ -70,6 +70,7 @@
<method name="get_images">
<return type="Texture2D[]" />
<description>
+ Gets the images of the GLTF file as an array of [Texture2D]s. These are the images that the [member GLTFTexture.src_image] index refers to.
</description>
</method>
<method name="get_lights">
@@ -89,6 +90,14 @@
Returns an array of all [GLTFMesh]es in the GLTF file. These are the meshes that the [member GLTFNode.mesh] index refers to.
</description>
</method>
+ <method name="get_node_index">
+ <return type="int" />
+ <param index="0" name="scene_node" type="Node" />
+ <description>
+ Returns the index of the [GLTFNode] corresponding to this Godot scene node. This is the inverse of [method get_scene_node]. Useful during the export process.
+ [b]Note:[/b] Not every Godot scene node will have a corresponding [GLTFNode], and not every [GLTFNode] will have a scene node generated. If there is no [GLTFNode] index for this scene node, [code]-1[/code] is returned.
+ </description>
+ </method>
<method name="get_nodes">
<return type="GLTFNode[]" />
<description>
@@ -99,7 +108,8 @@
<return type="Node" />
<param index="0" name="idx" type="int" />
<description>
- Returns the Godot scene node that corresponds to the same index as the [GLTFNode] it was generated from. Not every [GLTFNode] will have a scene node generated, and not every generated scene node will have a corresponding [GLTFNode].
+ Returns the Godot scene node that corresponds to the same index as the [GLTFNode] it was generated from. This is the inverse of [method get_node_index]. Useful during the import process.
+ [b]Note:[/b] Not every [GLTFNode] will have a scene node generated, and not every generated scene node will have a corresponding [GLTFNode]. If there is no scene node for this [GLTFNode] index, [code]null[/code] is returned.
</description>
</method>
<method name="get_skeletons">
@@ -182,6 +192,7 @@
<return type="void" />
<param index="0" name="images" type="Texture2D[]" />
<description>
+ Sets the images in the state stored as an array of [Texture2D]s. This can be used during export. These are the images that the [member GLTFTexture.src_image] index refers to.
</description>
</method>
<method name="set_lights">
diff --git a/modules/gltf/doc_classes/GLTFTexture.xml b/modules/gltf/doc_classes/GLTFTexture.xml
index df315edb9a..768e7a8945 100644
--- a/modules/gltf/doc_classes/GLTFTexture.xml
+++ b/modules/gltf/doc_classes/GLTFTexture.xml
@@ -10,7 +10,8 @@
<member name="sampler" type="int" setter="set_sampler" getter="get_sampler" default="-1">
ID of the texture sampler to use when sampling the image. If -1, then the default texture sampler is used (linear filtering, and repeat wrapping in both axes).
</member>
- <member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="0">
+ <member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="-1">
+ The index of the image associated with this texture, see [method GLTFState.get_images]. If -1, then this texture does not have an image assigned.
</member>
</members>
</class>
diff --git a/modules/gltf/extensions/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp
index bedb42eb32..2804a8b0a2 100644
--- a/modules/gltf/extensions/gltf_document_extension.cpp
+++ b/modules/gltf/extensions/gltf_document_extension.cpp
@@ -35,6 +35,8 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_import_preflight, "state", "extensions");
GDVIRTUAL_BIND(_get_supported_extensions);
GDVIRTUAL_BIND(_parse_node_extensions, "state", "gltf_node", "extensions");
+ GDVIRTUAL_BIND(_parse_image_data, "state", "image_data", "mime_type", "ret_image");
+ GDVIRTUAL_BIND(_parse_texture_json, "state", "texture_json", "ret_gltf_texture");
GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent");
GDVIRTUAL_BIND(_import_post_parse, "state");
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
@@ -68,6 +70,22 @@ Error GLTFDocumentExtension::parse_node_extensions(Ref<GLTFState> p_state, Ref<G
return err;
}
+Error GLTFDocumentExtension::parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) {
+ ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
+ ERR_FAIL_NULL_V(r_image, ERR_INVALID_PARAMETER);
+ Error err = OK;
+ GDVIRTUAL_CALL(_parse_image_data, p_state, p_image_data, p_mime_type, r_image, err);
+ return err;
+}
+
+Error GLTFDocumentExtension::parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) {
+ ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
+ ERR_FAIL_NULL_V(r_gltf_texture, ERR_INVALID_PARAMETER);
+ Error err = OK;
+ GDVIRTUAL_CALL(_parse_texture_json, p_state, p_texture_json, r_gltf_texture, err);
+ return err;
+}
+
Node3D *GLTFDocumentExtension::generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) {
ERR_FAIL_NULL_V(p_state, nullptr);
ERR_FAIL_NULL_V(p_gltf_node, nullptr);
diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h
index 3531f81f6f..d922588a29 100644
--- a/modules/gltf/extensions/gltf_document_extension.h
+++ b/modules/gltf/extensions/gltf_document_extension.h
@@ -44,6 +44,8 @@ public:
virtual Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions);
virtual Vector<String> get_supported_extensions();
virtual Error parse_node_extensions(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &p_extensions);
+ virtual Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image);
+ virtual Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture);
virtual Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent);
virtual Error import_post_parse(Ref<GLTFState> p_state);
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
@@ -58,6 +60,8 @@ public:
GDVIRTUAL2R(Error, _import_preflight, Ref<GLTFState>, Vector<String>);
GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
GDVIRTUAL3R(Error, _parse_node_extensions, Ref<GLTFState>, Ref<GLTFNode>, Dictionary);
+ GDVIRTUAL4R(Error, _parse_image_data, Ref<GLTFState>, PackedByteArray, String, Ref<Image>);
+ GDVIRTUAL3R(Error, _parse_texture_json, Ref<GLTFState>, Dictionary, Ref<GLTFTexture>);
GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *);
GDVIRTUAL1R(Error, _import_post_parse, Ref<GLTFState>);
GDVIRTUAL4R(Error, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
diff --git a/modules/gltf/extensions/gltf_document_extension_texture_webp.cpp b/modules/gltf/extensions/gltf_document_extension_texture_webp.cpp
new file mode 100644
index 0000000000..ded4970968
--- /dev/null
+++ b/modules/gltf/extensions/gltf_document_extension_texture_webp.cpp
@@ -0,0 +1,68 @@
+/**************************************************************************/
+/* gltf_document_extension_texture_webp.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "gltf_document_extension_texture_webp.h"
+
+#include "scene/3d/area_3d.h"
+
+// Import process.
+Error GLTFDocumentExtensionTextureWebP::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) {
+ if (!p_extensions.has("EXT_texture_webp")) {
+ return ERR_SKIP;
+ }
+ return OK;
+}
+
+Vector<String> GLTFDocumentExtensionTextureWebP::get_supported_extensions() {
+ Vector<String> ret;
+ ret.push_back("EXT_texture_webp");
+ return ret;
+}
+
+Error GLTFDocumentExtensionTextureWebP::parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) {
+ if (p_mime_type == "image/webp") {
+ return r_image->load_webp_from_buffer(p_image_data);
+ }
+ return OK;
+}
+
+Error GLTFDocumentExtensionTextureWebP::parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) {
+ if (!p_texture_json.has("extensions")) {
+ return OK;
+ }
+ const Dictionary &extensions = p_texture_json["extensions"];
+ if (!extensions.has("EXT_texture_webp")) {
+ return OK;
+ }
+ const Dictionary &texture_webp = extensions["EXT_texture_webp"];
+ ERR_FAIL_COND_V(!texture_webp.has("source"), ERR_PARSE_ERROR);
+ r_gltf_texture->set_src_image(texture_webp["source"]);
+ return OK;
+}
diff --git a/modules/gltf/extensions/gltf_document_extension_texture_webp.h b/modules/gltf/extensions/gltf_document_extension_texture_webp.h
new file mode 100644
index 0000000000..9abf09a41f
--- /dev/null
+++ b/modules/gltf/extensions/gltf_document_extension_texture_webp.h
@@ -0,0 +1,47 @@
+/**************************************************************************/
+/* gltf_document_extension_texture_webp.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H
+#define GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H
+
+#include "gltf_document_extension.h"
+
+class GLTFDocumentExtensionTextureWebP : public GLTFDocumentExtension {
+ GDCLASS(GLTFDocumentExtensionTextureWebP, GLTFDocumentExtension);
+
+public:
+ // Import process.
+ Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) override;
+ Vector<String> get_supported_extensions() override;
+ Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image) override;
+ Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture) override;
+};
+
+#endif // GLTF_DOCUMENT_EXTENSION_TEXTURE_WEBP_H
diff --git a/modules/gltf/extensions/physics/gltf_physics_body.cpp b/modules/gltf/extensions/physics/gltf_physics_body.cpp
index b7fb23d37f..a187fc53a1 100644
--- a/modules/gltf/extensions/physics/gltf_physics_body.cpp
+++ b/modules/gltf/extensions/physics/gltf_physics_body.cpp
@@ -112,6 +112,9 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_
physics_body->linear_velocity = body->get_linear_velocity();
physics_body->angular_velocity = body->get_angular_velocity();
physics_body->inertia = body->get_inertia();
+ if (body->get_center_of_mass() != Vector3()) {
+ WARN_PRINT("GLTFPhysicsBody: This rigid body has a center of mass offset from the origin, which will be ignored when exporting to GLTF.");
+ }
if (cast_to<VehicleBody3D>(p_body_node)) {
physics_body->body_type = "vehicle";
} else {
@@ -140,6 +143,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
body->set_linear_velocity(linear_velocity);
body->set_angular_velocity(angular_velocity);
body->set_inertia(inertia);
+ body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
return body;
}
if (body_type == "rigid") {
@@ -148,6 +152,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const {
body->set_linear_velocity(linear_velocity);
body->set_angular_velocity(angular_velocity);
body->set_inertia(inertia);
+ body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM);
return body;
}
if (body_type == "static") {
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 251aa6375f..d77d9c6f66 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -678,11 +678,11 @@ void GLTFDocument::_compute_node_heights(Ref<GLTFState> p_state) {
}
}
-static Vector<uint8_t> _parse_base64_uri(const String &uri) {
- int start = uri.find(",");
+static Vector<uint8_t> _parse_base64_uri(const String &p_uri) {
+ int start = p_uri.find(",");
ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
- CharString substr = uri.substr(start + 1).ascii();
+ CharString substr = p_uri.substr(start + 1).ascii();
int strlen = substr.length();
@@ -696,6 +696,7 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) {
return buf;
}
+
Error GLTFDocument::_encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path) {
print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size()));
@@ -3066,6 +3067,129 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> p_state, const String &p_pa
return OK;
}
+Ref<Image> GLTFDocument::_parse_image_bytes_into_image(Ref<GLTFState> p_state, const Vector<uint8_t> &p_bytes, const String &p_mime_type, int p_index) {
+ Ref<Image> r_image;
+ r_image.instantiate();
+ // Check if any GLTFDocumentExtensions want to import this data as an image.
+ for (Ref<GLTFDocumentExtension> ext : document_extensions) {
+ ERR_CONTINUE(ext.is_null());
+ Error err = ext->parse_image_data(p_state, p_bytes, p_mime_type, r_image);
+ ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing image " + itos(p_index) + " in file " + p_state->filename + ". Continuing.");
+ if (!r_image->is_empty()) {
+ return r_image;
+ }
+ }
+ // If no extension wanted to import this data as an image, try to load a PNG or JPEG.
+ // First we honor the mime types if they were defined.
+ if (p_mime_type == "image/png") { // Load buffer as PNG.
+ r_image->load_png_from_buffer(p_bytes);
+ } else if (p_mime_type == "image/jpeg") { // Loader buffer as JPEG.
+ r_image->load_jpg_from_buffer(p_bytes);
+ }
+ // If we didn't pass the above tests, we attempt loading as PNG and then JPEG directly.
+ // This covers URIs with base64-encoded data with application/* type but
+ // no optional mimeType property, or bufferViews with a bogus mimeType
+ // (e.g. `image/jpeg` but the data is actually PNG).
+ // That's not *exactly* what the spec mandates but this lets us be
+ // lenient with bogus glb files which do exist in production.
+ if (r_image->is_empty()) { // Try PNG first.
+ r_image->load_png_from_buffer(p_bytes);
+ }
+ if (r_image->is_empty()) { // And then JPEG.
+ r_image->load_jpg_from_buffer(p_bytes);
+ }
+ // If it still can't be loaded, give up and insert an empty image as placeholder.
+ if (r_image->is_empty()) {
+ ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", p_index, p_mime_type));
+ }
+ return r_image;
+}
+
+void GLTFDocument::_parse_image_save_image(Ref<GLTFState> p_state, const String &p_mime_type, int p_index, Ref<Image> p_image) {
+ GLTFState::GLTFHandleBinary handling = GLTFState::GLTFHandleBinary(p_state->handle_binary_image);
+ if (p_image->is_empty() || handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_DISCARD_TEXTURES) {
+ p_state->images.push_back(Ref<Texture2D>());
+ p_state->source_images.push_back(Ref<Image>());
+ return;
+ }
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint() && handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
+ if (p_state->base_path.is_empty()) {
+ p_state->images.push_back(Ref<Texture2D>());
+ p_state->source_images.push_back(Ref<Image>());
+ } else if (p_image->get_name().is_empty()) {
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be named. Skipping it.", p_index));
+ p_state->images.push_back(Ref<Texture2D>());
+ p_state->source_images.push_back(Ref<Image>());
+ } else {
+ Error err = OK;
+ bool must_import = true;
+ Vector<uint8_t> img_data = p_image->get_data();
+ Dictionary generator_parameters;
+ String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + p_image->get_name() + ".png";
+ if (FileAccess::exists(file_path + ".import")) {
+ Ref<ConfigFile> config;
+ config.instantiate();
+ config->load(file_path + ".import");
+ if (config->has_section_key("remap", "generator_parameters")) {
+ generator_parameters = (Dictionary)config->get_value("remap", "generator_parameters");
+ }
+ if (!generator_parameters.has("md5")) {
+ must_import = false; // Didn't come from a gltf document; don't overwrite.
+ }
+ String existing_md5 = generator_parameters["md5"];
+ unsigned char md5_hash[16];
+ CryptoCore::md5(img_data.ptr(), img_data.size(), md5_hash);
+ String new_md5 = String::hex_encode_buffer(md5_hash, 16);
+ generator_parameters["md5"] = new_md5;
+ if (new_md5 == existing_md5) {
+ must_import = false;
+ }
+ }
+ if (must_import) {
+ err = p_image->save_png(file_path);
+ ERR_FAIL_COND(err != OK);
+ // ResourceLoader::import will crash if not is_editor_hint(), so this case is protected above and will fall through to uncompressed.
+ HashMap<StringName, Variant> custom_options;
+ custom_options[SNAME("mipmaps/generate")] = true;
+ // Will only use project settings defaults if custom_importer is empty.
+ EditorFileSystem::get_singleton()->update_file(file_path);
+ EditorFileSystem::get_singleton()->reimport_append(file_path, custom_options, String(), generator_parameters);
+ }
+ Ref<Texture2D> saved_image = ResourceLoader::load(file_path, "Texture2D");
+ if (saved_image.is_valid()) {
+ p_state->images.push_back(saved_image);
+ p_state->source_images.push_back(saved_image->get_image());
+ } else {
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded with the name: %s. Skipping it.", p_index, p_image->get_name()));
+ // Placeholder to keep count.
+ p_state->images.push_back(Ref<Texture2D>());
+ p_state->source_images.push_back(Ref<Image>());
+ }
+ }
+ return;
+ }
+#endif // TOOLS_ENABLED
+ if (handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
+ Ref<PortableCompressedTexture2D> tex;
+ tex.instantiate();
+ tex->set_name(p_image->get_name());
+ tex->set_keep_compressed_buffer(true);
+ tex->create_from_image(p_image, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
+ p_state->images.push_back(tex);
+ p_state->source_images.push_back(p_image);
+ return;
+ }
+ // This handles the case of HANDLE_BINARY_EMBED_AS_UNCOMPRESSED, and it also serves
+ // as a fallback for HANDLE_BINARY_EXTRACT_TEXTURES when this is not the editor.
+ Ref<ImageTexture> tex;
+ tex.instantiate();
+ tex->set_name(p_image->get_name());
+ tex->set_image(p_image);
+ p_state->images.push_back(tex);
+ p_state->source_images.push_back(p_image);
+}
+
Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_path) {
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
if (!p_state->json.has("images")) {
@@ -3077,7 +3201,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
const Array &images = p_state->json["images"];
HashSet<String> used_names;
for (int i = 0; i < images.size(); i++) {
- const Dictionary &d = images[i];
+ const Dictionary &dict = images[i];
// glTF 2.0 supports PNG and JPEG types, which can be specified as (from spec):
// "- a URI to an external file in one of the supported images formats, or
@@ -3088,23 +3212,19 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
// We'll assume that we use either URI or bufferView, so let's warn the user
// if their image somehow uses both. And fail if it has neither.
- ERR_CONTINUE_MSG(!d.has("uri") && !d.has("bufferView"), "Invalid image definition in glTF file, it should specify an 'uri' or 'bufferView'.");
- if (d.has("uri") && d.has("bufferView")) {
+ ERR_CONTINUE_MSG(!dict.has("uri") && !dict.has("bufferView"), "Invalid image definition in glTF file, it should specify an 'uri' or 'bufferView'.");
+ if (dict.has("uri") && dict.has("bufferView")) {
WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'uri' will take precedence.");
}
- String mimetype;
- if (d.has("mimeType")) { // Should be "image/png" or "image/jpeg".
- mimetype = d["mimeType"];
+ String mime_type;
+ if (dict.has("mimeType")) { // Should be "image/png", "image/jpeg", or something handled by an extension.
+ mime_type = dict["mimeType"];
}
- Vector<uint8_t> data;
- const uint8_t *data_ptr = nullptr;
- int data_size = 0;
-
String image_name;
- if (d.has("name")) {
- image_name = d["name"];
+ if (dict.has("name")) {
+ image_name = dict["name"];
image_name = image_name.get_file().get_basename().validate_filename();
}
if (image_name.is_empty()) {
@@ -3114,31 +3234,17 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
image_name += "_" + itos(i);
}
used_names.insert(image_name);
-
- if (d.has("uri")) {
+ // Load the image data. If we get a byte array, store here for later.
+ Vector<uint8_t> data;
+ if (dict.has("uri")) {
// Handles the first two bullet points from the spec (embedded data, or external file).
- String uri = d["uri"];
-
+ String uri = dict["uri"];
if (uri.begins_with("data:")) { // Embedded data using base64.
- // Validate data MIME types and throw a warning if it's one we don't know/support.
- if (!uri.begins_with("data:application/octet-stream;base64") &&
- !uri.begins_with("data:application/gltf-buffer;base64") &&
- !uri.begins_with("data:image/png;base64") &&
- !uri.begins_with("data:image/jpeg;base64")) {
- WARN_PRINT(vformat("glTF: Image index '%d' uses an unsupported URI data type: %s. Skipping it.", i, uri));
- p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
- continue;
- }
data = _parse_base64_uri(uri);
- data_ptr = data.ptr();
- data_size = data.size();
// mimeType is optional, but if we have it defined in the URI, let's use it.
- if (mimetype.is_empty()) {
- if (uri.begins_with("data:image/png;base64")) {
- mimetype = "image/png";
- } else if (uri.begins_with("data:image/jpeg;base64")) {
- mimetype = "image/jpeg";
- }
+ if (mime_type.is_empty() && uri.contains(";")) {
+ // Trim "data:" prefix which is 5 characters long, and end at ";base64".
+ mime_type = uri.substr(5, uri.find(";base64") - 5);
}
} else { // Relative path to an external image file.
ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
@@ -3148,161 +3254,53 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
// The spec says that if mimeType is defined, it should take precedence (e.g.
// there could be a `.png` image which is actually JPEG), but there's no easy
// API for that in Godot, so we'd have to load as a buffer (i.e. embedded in
- // the material), so we do this only as fallback.
+ // the material), so we only do that only as fallback.
Ref<Texture2D> texture = ResourceLoader::load(uri);
- String extension = uri.get_extension().to_lower();
if (texture.is_valid()) {
p_state->images.push_back(texture);
p_state->source_images.push_back(texture->get_image());
continue;
- } else if (mimetype == "image/png" || mimetype == "image/jpeg" || extension == "png" || extension == "jpg" || extension == "jpeg") {
- // Fallback to loading as byte array.
- // This enables us to support the spec's requirement that we honor mimetype
- // regardless of file URI.
- data = FileAccess::get_file_as_bytes(uri);
- if (data.size() == 0) {
- WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s. Skipping it.", i, mimetype, uri));
- p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
- continue;
- }
- data_ptr = data.ptr();
- data_size = data.size();
- } else {
- WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded from URI: %s. Skipping it.", i, uri));
+ }
+ // mimeType is optional, but if we have it in the file extension, let's use it.
+ // If the mimeType does not match with the file extension, either it should be
+ // specified in the file, or the GLTFDocumentExtension should handle it.
+ if (mime_type.is_empty()) {
+ mime_type = "image/" + uri.get_extension();
+ }
+ // Fallback to loading as byte array. This enables us to support the
+ // spec's requirement that we honor mimetype regardless of file URI.
+ data = FileAccess::get_file_as_bytes(uri);
+ if (data.size() == 0) {
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s because there was no data to load. Skipping it.", i, mime_type, uri));
p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
+ p_state->source_images.push_back(Ref<Image>());
continue;
}
}
- } else if (d.has("bufferView")) {
+ } else if (dict.has("bufferView")) {
// Handles the third bullet point from the spec (bufferView).
- ERR_FAIL_COND_V_MSG(mimetype.is_empty(), ERR_FILE_CORRUPT,
- vformat("glTF: Image index '%d' specifies 'bufferView' but no 'mimeType', which is invalid.", i));
-
- const GLTFBufferViewIndex bvi = d["bufferView"];
-
+ ERR_FAIL_COND_V_MSG(mime_type.is_empty(), ERR_FILE_CORRUPT, vformat("glTF: Image index '%d' specifies 'bufferView' but no 'mimeType', which is invalid.", i));
+ const GLTFBufferViewIndex bvi = dict["bufferView"];
ERR_FAIL_INDEX_V(bvi, p_state->buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
-
Ref<GLTFBufferView> bv = p_state->buffer_views[bvi];
-
const GLTFBufferIndex bi = bv->buffer;
ERR_FAIL_INDEX_V(bi, p_state->buffers.size(), ERR_PARAMETER_RANGE_ERROR);
-
ERR_FAIL_COND_V(bv->byte_offset + bv->byte_length > p_state->buffers[bi].size(), ERR_FILE_CORRUPT);
-
- data_ptr = &p_state->buffers[bi][bv->byte_offset];
- data_size = bv->byte_length;
- }
-
- Ref<Image> img;
-
- // First we honor the mime types if they were defined.
- if (mimetype == "image/png") { // Load buffer as PNG.
- ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE);
- img = Image::_png_mem_loader_func(data_ptr, data_size);
- } else if (mimetype == "image/jpeg") { // Loader buffer as JPEG.
- ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE);
- img = Image::_jpg_mem_loader_func(data_ptr, data_size);
- }
-
- // If we didn't pass the above tests, we attempt loading as PNG and then
- // JPEG directly.
- // This covers URIs with base64-encoded data with application/* type but
- // no optional mimeType property, or bufferViews with a bogus mimeType
- // (e.g. `image/jpeg` but the data is actually PNG).
- // That's not *exactly* what the spec mandates but this lets us be
- // lenient with bogus glb files which do exist in production.
- if (img.is_null()) { // Try PNG first.
- ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE);
- img = Image::_png_mem_loader_func(data_ptr, data_size);
- }
- if (img.is_null()) { // And then JPEG.
- ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE);
- img = Image::_jpg_mem_loader_func(data_ptr, data_size);
- }
- // Now we've done our best, fix your scenes.
- if (img.is_null()) {
- ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype));
- p_state->images.push_back(Ref<Texture2D>());
+ const PackedByteArray &buffer = p_state->buffers[bi];
+ data = buffer.slice(bv->byte_offset, bv->byte_offset + bv->byte_length);
+ }
+ // Done loading the image data bytes. Check that we actually got data to parse.
+ // Note: There are paths above that return early, so this point might not be reached.
+ if (data.is_empty()) {
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded, no data found. Skipping it.", i));
+ p_state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
p_state->source_images.push_back(Ref<Image>());
continue;
}
+ // Parse the image data from bytes into an Image resource and save if needed.
+ Ref<Image> img = _parse_image_bytes_into_image(p_state, data, mime_type, i);
img->set_name(image_name);
- if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_DISCARD_TEXTURES) {
- p_state->images.push_back(Ref<Texture2D>());
- p_state->source_images.push_back(Ref<Image>());
-#ifdef TOOLS_ENABLED
- } else if (Engine::get_singleton()->is_editor_hint() && GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
- if (p_state->base_path.is_empty()) {
- p_state->images.push_back(Ref<Texture2D>());
- p_state->source_images.push_back(Ref<Image>());
- } else if (img->get_name().is_empty()) {
- WARN_PRINT(vformat("glTF: Image index '%d' couldn't be named. Skipping it.", i));
- p_state->images.push_back(Ref<Texture2D>());
- p_state->source_images.push_back(Ref<Image>());
- } else {
- Error err = OK;
- bool must_import = true;
- Vector<uint8_t> img_data = img->get_data();
- Dictionary generator_parameters;
- String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + img->get_name() + ".png";
- if (FileAccess::exists(file_path + ".import")) {
- Ref<ConfigFile> config;
- config.instantiate();
- config->load(file_path + ".import");
- if (config->has_section_key("remap", "generator_parameters")) {
- generator_parameters = (Dictionary)config->get_value("remap", "generator_parameters");
- }
- if (!generator_parameters.has("md5")) {
- must_import = false; // Didn't come form a gltf document; don't overwrite.
- }
- String existing_md5 = generator_parameters["md5"];
- unsigned char md5_hash[16];
- CryptoCore::md5(img_data.ptr(), img_data.size(), md5_hash);
- String new_md5 = String::hex_encode_buffer(md5_hash, 16);
- generator_parameters["md5"] = new_md5;
- if (new_md5 == existing_md5) {
- must_import = false;
- }
- }
- if (must_import) {
- err = img->save_png(file_path);
- ERR_FAIL_COND_V(err != OK, err);
- // ResourceLoader::import will crash if not is_editor_hint(), so this case is protected above and will fall through to uncompressed.
- HashMap<StringName, Variant> custom_options;
- custom_options[SNAME("mipmaps/generate")] = true;
- // Will only use project settings defaults if custom_importer is empty.
- EditorFileSystem::get_singleton()->update_file(file_path);
- EditorFileSystem::get_singleton()->reimport_append(file_path, custom_options, String(), generator_parameters);
- }
- Ref<Texture2D> saved_image = ResourceLoader::load(file_path, "Texture2D");
- if (saved_image.is_valid()) {
- p_state->images.push_back(saved_image);
- p_state->source_images.push_back(img);
- } else {
- WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded with the name: %s. Skipping it.", i, img->get_name()));
- // Placeholder to keep count.
- p_state->images.push_back(Ref<Texture2D>());
- p_state->source_images.push_back(Ref<Image>());
- }
- }
-#endif
- } else if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
- Ref<PortableCompressedTexture2D> tex;
- tex.instantiate();
- tex->set_name(img->get_name());
- tex->set_keep_compressed_buffer(true);
- tex->create_from_image(img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
- p_state->images.push_back(tex);
- p_state->source_images.push_back(img);
- } else {
- // This handles two cases: if editor hint and HANDLE_BINARY_EXTRACT_TEXTURES; or if HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
- Ref<ImageTexture> tex;
- tex.instantiate();
- tex->set_name(img->get_name());
- tex->set_image(img);
- p_state->images.push_back(tex);
- p_state->source_images.push_back(img);
- }
+ _parse_image_save_image(p_state, mime_type, i, img);
}
print_verbose("glTF: Total images: " + itos(p_state->images.size()));
@@ -3340,19 +3338,28 @@ Error GLTFDocument::_parse_textures(Ref<GLTFState> p_state) {
const Array &textures = p_state->json["textures"];
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
- const Dictionary &d = textures[i];
-
- ERR_FAIL_COND_V(!d.has("source"), ERR_PARSE_ERROR);
-
- Ref<GLTFTexture> t;
- t.instantiate();
- t->set_src_image(d["source"]);
- if (d.has("sampler")) {
- t->set_sampler(d["sampler"]);
- } else {
- t->set_sampler(-1);
+ const Dictionary &dict = textures[i];
+ Ref<GLTFTexture> texture;
+ texture.instantiate();
+ // Check if any GLTFDocumentExtensions want to handle this texture JSON.
+ for (Ref<GLTFDocumentExtension> ext : document_extensions) {
+ ERR_CONTINUE(ext.is_null());
+ Error err = ext->parse_texture_json(p_state, dict, texture);
+ ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing texture JSON " + String(Variant(dict)) + " in file " + p_state->filename + ". Continuing.");
+ if (texture->get_src_image() != -1) {
+ break;
+ }
+ }
+ if (texture->get_src_image() == -1) {
+ // No extensions handled it, so use the base GLTF source.
+ // This may be the fallback, or the only option anyway.
+ ERR_FAIL_COND_V(!dict.has("source"), ERR_PARSE_ERROR);
+ texture->set_src_image(dict["source"]);
+ }
+ if (texture->get_sampler() == -1 && dict.has("sampler")) {
+ texture->set_sampler(dict["sampler"]);
}
- p_state->textures.push_back(t);
+ p_state->textures.push_back(texture);
}
return OK;
@@ -3365,6 +3372,7 @@ GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> p_state, Ref<Texture2
ERR_FAIL_COND_V(p_texture->get_image().is_null(), -1);
GLTFImageIndex gltf_src_image_i = p_state->images.size();
p_state->images.push_back(p_texture);
+ p_state->source_images.push_back(p_texture->get_image());
gltf_texture->set_src_image(gltf_src_image_i);
gltf_texture->set_sampler(_set_sampler_for_mode(p_state, p_filter_mode, p_repeats));
GLTFTextureIndex gltf_texture_i = p_state->textures.size();
@@ -3389,6 +3397,7 @@ Ref<Texture2D> GLTFDocument::_get_texture(Ref<GLTFState> p_state, const GLTFText
portable_texture->create_from_image(new_img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL, false);
}
p_state->images.write[image] = portable_texture;
+ p_state->source_images.write[image] = new_img;
}
return p_state->images[image];
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index ae19f67390..718b05b959 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -151,6 +151,8 @@ private:
Error _serialize_texture_samplers(Ref<GLTFState> p_state);
Error _serialize_images(Ref<GLTFState> p_state, const String &p_path);
Error _serialize_lights(Ref<GLTFState> p_state);
+ Ref<Image> _parse_image_bytes_into_image(Ref<GLTFState> p_state, const Vector<uint8_t> &p_bytes, const String &p_mime_type, int p_index);
+ void _parse_image_save_image(Ref<GLTFState> p_state, const String &p_mime_type, int p_index, Ref<Image> p_image);
Error _parse_images(Ref<GLTFState> p_state, const String &p_base_path);
Error _parse_textures(Ref<GLTFState> p_state);
Error _parse_texture_samplers(Ref<GLTFState> p_state);
diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp
index b493e498f1..372348d90d 100644
--- a/modules/gltf/gltf_state.cpp
+++ b/modules/gltf/gltf_state.cpp
@@ -87,6 +87,7 @@ void GLTFState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_animations"), &GLTFState::get_animations);
ClassDB::bind_method(D_METHOD("set_animations", "animations"), &GLTFState::set_animations);
ClassDB::bind_method(D_METHOD("get_scene_node", "idx"), &GLTFState::get_scene_node);
+ ClassDB::bind_method(D_METHOD("get_node_index", "scene_node"), &GLTFState::get_node_index);
ClassDB::bind_method(D_METHOD("get_additional_data", "extension_name"), &GLTFState::get_additional_data);
ClassDB::bind_method(D_METHOD("set_additional_data", "extension_name", "additional_data"), &GLTFState::set_additional_data);
ClassDB::bind_method(D_METHOD("get_handle_binary_image"), &GLTFState::get_handle_binary_image);
@@ -335,6 +336,15 @@ Node *GLTFState::get_scene_node(GLTFNodeIndex idx) {
return scene_nodes[idx];
}
+GLTFNodeIndex GLTFState::get_node_index(Node *p_node) {
+ for (KeyValue<GLTFNodeIndex, Node *> x : scene_nodes) {
+ if (x.value == p_node) {
+ return x.key;
+ }
+ }
+ return -1;
+}
+
int GLTFState::get_animation_players_count(int idx) {
return animation_players.size();
}
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index f2036fca1e..a2371b8040 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -204,7 +204,7 @@ public:
void set_animations(TypedArray<GLTFAnimation> p_animations);
Node *get_scene_node(GLTFNodeIndex idx);
- ImporterMeshInstance3D *get_scene_mesh_instance(GLTFNodeIndex idx);
+ GLTFNodeIndex get_node_index(Node *p_node);
int get_animation_players_count(int idx);
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index 2f66e5c5a5..42e3476ff3 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -31,6 +31,7 @@
#include "register_types.h"
#include "extensions/gltf_document_extension_convert_importer_mesh.h"
+#include "extensions/gltf_document_extension_texture_webp.h"
#include "extensions/gltf_spec_gloss.h"
#include "extensions/physics/gltf_document_extension_physics.h"
#include "gltf_document.h"
@@ -131,6 +132,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(GLTFTextureSampler);
// Register GLTFDocumentExtension classes with GLTFDocument.
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionPhysics);
+ GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionTextureWebP);
bool is_editor = ::Engine::get_singleton()->is_editor_hint();
if (!is_editor) {
GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionConvertImporterMesh);
diff --git a/modules/gltf/structures/gltf_texture.h b/modules/gltf/structures/gltf_texture.h
index 8def62a9a1..a9e19e65ea 100644
--- a/modules/gltf/structures/gltf_texture.h
+++ b/modules/gltf/structures/gltf_texture.h
@@ -38,7 +38,7 @@ class GLTFTexture : public Resource {
GDCLASS(GLTFTexture, Resource);
private:
- GLTFImageIndex src_image = 0;
+ GLTFImageIndex src_image = -1;
GLTFTextureSamplerIndex sampler = -1;
protected:
diff --git a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
index f1f0d158a9..55dd9cade2 100644
--- a/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
+++ b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml
@@ -55,7 +55,7 @@
<return type="bool" />
<param index="0" name="path" type="NodePath" />
<description>
- Returns whether the property identified by the given [code]path[/code] is configured to be reliably synchronized when changes are detected on process.
+ Returns whether the property identified by the given [param path] is configured to be reliably synchronized when changes are detected on process.
</description>
</method>
<method name="property_set_spawn">
@@ -79,7 +79,7 @@
<param index="0" name="path" type="NodePath" />
<param index="1" name="enabled" type="bool" />
<description>
- Sets whether the property identified by the given [code]path[/code] is configured to be reliably synchronized when changes are detected on process.
+ Sets whether the property identified by the given [param path] is configured to be reliably synchronized when changes are detected on process.
</description>
</method>
<method name="remove_property">
diff --git a/modules/noise/icons/NoiseTexture.svg b/modules/noise/icons/NoiseTexture.svg
deleted file mode 100644
index 479684cde2..0000000000
--- a/modules/noise/icons/NoiseTexture.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v12c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-12c0-.55228-.44772-1-1-1zm1 2h10v8h-10zm3 1v2h2v-2zm2 2v2h2v2h2v-6h-2v2zm0 2h-2v-2h-2v4h4z" fill="#e0e0e0" fill-opacity=".99608"/></svg>
diff --git a/modules/noise/icons/NoiseTexture2D.svg b/modules/noise/icons/NoiseTexture2D.svg
new file mode 100644
index 0000000000..0c22cfdcc6
--- /dev/null
+++ b/modules/noise/icons/NoiseTexture2D.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm1 2h10v8H3zm3 1v2h2V4zm2 2v2h2v2h2V4h-2v2zm0 2H6V6H4v4h4z" fill="#e0e0e0"/></svg>
diff --git a/modules/text_server_adv/doc_classes/TextServerAdvanced.xml b/modules/text_server_adv/doc_classes/TextServerAdvanced.xml
index dca07b6d5f..3b2128b281 100644
--- a/modules/text_server_adv/doc_classes/TextServerAdvanced.xml
+++ b/modules/text_server_adv/doc_classes/TextServerAdvanced.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerAdvanced" inherits="TextServerExtension" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
- Text Server using HarfBuzz, ICU and SIL Graphite to support BiDi, complex text layouts and contextual OpenType features.
+ An advanced text server with support for BiDi, complex text layout, and contextual OpenType features. Used in Godot by default.
</brief_description>
<description>
+ An implementation of [TextServer] that uses HarfBuzz, ICU and SIL Graphite to support BiDi, complex text layouts and contextual OpenType features. This is Godot's default primary [TextServer] interface.
</description>
<tutorials>
</tutorials>
diff --git a/modules/text_server_fb/doc_classes/TextServerFallback.xml b/modules/text_server_fb/doc_classes/TextServerFallback.xml
index 6ca9c9462e..ddd05fa445 100644
--- a/modules/text_server_fb/doc_classes/TextServerFallback.xml
+++ b/modules/text_server_fb/doc_classes/TextServerFallback.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerFallback" inherits="TextServerExtension" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
- Fallback implementation of the Text Server, without BiDi and complex text layout support.
+ A fallback implementation of Godot's text server, without support for BiDi and complex text layout.
</brief_description>
<description>
+ A fallback implementation of Godot's text server. This fallback is faster than [TextServerAdvanced] for processing a lot of text, but it does not support BiDi and complex text layout.
+ [b]Note:[/b] This text server is not part of official Godot binaries. If you want to use it, compile the engine with the option [code]module_text_server_fb_enabled=yes[/code].
</description>
<tutorials>
</tutorials>
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 13a22b5d18..b8460fe387 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -40,10 +40,10 @@
#include <webp/decode.h>
#include <webp/encode.h>
-static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) {
+static Ref<Image> _webp_mem_loader_func(const uint8_t *p_webp_data, int p_size) {
Ref<Image> img;
img.instantiate();
- Error err = WebPCommon::webp_load_image_from_buffer(img.ptr(), p_png, p_size);
+ Error err = WebPCommon::webp_load_image_from_buffer(img.ptr(), p_webp_data, p_size);
ERR_FAIL_COND_V(err, Ref<Image>());
return img;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index bc7234e2ad..b465377743 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -166,8 +166,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
@Override
public void requestPointerCapture() {
- super.requestPointerCapture();
- inputHandler.onPointerCaptureChange(true);
+ if (canCapturePointer()) {
+ super.requestPointerCapture();
+ inputHandler.onPointerCaptureChange(true);
+ }
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 02c0d67fff..00243dab2a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -51,4 +51,8 @@ public interface GodotRenderView {
void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY);
void setPointerIcon(int pointerType);
+
+ default boolean canCapturePointer() {
+ return getInputHandler().canCapturePointer();
+ }
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 5439f55b25..681e182adb 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -134,8 +134,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
@Override
public void requestPointerCapture() {
- super.requestPointerCapture();
- mInputHandler.onPointerCaptureChange(true);
+ if (canCapturePointer()) {
+ super.requestPointerCapture();
+ mInputHandler.onPointerCaptureChange(true);
+ }
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
index 7dc5fb6f83..e9bc435689 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
@@ -227,16 +227,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
)
dragInProgress = false
}
- return true
}
- dragInProgress = true
-
val x = terminusEvent.x
val y = terminusEvent.y
if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress) {
GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f)
- } else {
+ } else if (!scaleInProgress){
+ dragInProgress = true
GodotInputHandler.handleMotionEvent(terminusEvent)
}
return true
@@ -246,11 +244,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
if (!panningAndScalingEnabled || pointerCaptureInProgress) {
return false
}
- GodotLib.magnify(
- detector.focusX,
- detector.focusY,
- detector.scaleFactor
- )
+
+ if (detector.scaleFactor >= 0.8f && detector.scaleFactor != 1f && detector.scaleFactor <= 1.2f) {
+ GodotLib.magnify(
+ detector.focusX,
+ detector.focusY,
+ detector.scaleFactor
+ )
+ }
return true
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index cedbbfb7c3..317344f2a5 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -66,6 +66,11 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
private final ScaleGestureDetector scaleGestureDetector;
private final GodotGestureHandler godotGestureHandler;
+ /**
+ * Used to decide whether mouse capture can be enabled.
+ */
+ private int lastSeenToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
+
public GodotInputHandler(GodotRenderView godotView) {
final Context context = godotView.getView().getContext();
mRenderView = godotView;
@@ -105,6 +110,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
return (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
}
+ public boolean canCapturePointer() {
+ return lastSeenToolType == MotionEvent.TOOL_TYPE_MOUSE;
+ }
+
public void onPointerCaptureChange(boolean hasCapture) {
godotGestureHandler.onPointerCaptureChange(hasCapture);
}
@@ -174,6 +183,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
public boolean onTouchEvent(final MotionEvent event) {
+ lastSeenToolType = event.getToolType(0);
+
this.scaleGestureDetector.onTouchEvent(event);
if (this.gestureDetector.onTouchEvent(event)) {
// The gesture detector has handled the event.
@@ -198,6 +209,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
public boolean onGenericMotionEvent(MotionEvent event) {
+ lastSeenToolType = event.getToolType(0);
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && gestureDetector.onGenericMotionEvent(event)) {
// The gesture detector has handled the event.
return true;
@@ -471,15 +484,27 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) {
+ // Fix the buttonsMask
+ switch (eventAction) {
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ // Zero-up the button state
+ buttonsMask = 0;
+ break;
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ if (buttonsMask == 0) {
+ buttonsMask = MotionEvent.BUTTON_PRIMARY;
+ }
+ break;
+ }
+
// We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically
// follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate
// stream of events to the engine.
switch (eventAction) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- // Zero-up the button state
- buttonsMask = 0;
- // FALL THROUGH
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_HOVER_ENTER:
case MotionEvent.ACTION_HOVER_EXIT:
diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp
index b50d4870bd..a95f762e01 100644
--- a/platform/android/java_godot_view_wrapper.cpp
+++ b/platform/android/java_godot_view_wrapper.cpp
@@ -49,6 +49,8 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
_request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V");
_release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V");
}
+
+ _can_capture_pointer = env->GetMethodID(_cls, "canCapturePointer", "()Z");
}
bool GodotJavaViewWrapper::can_update_pointer_icon() const {
@@ -56,7 +58,16 @@ bool GodotJavaViewWrapper::can_update_pointer_icon() const {
}
bool GodotJavaViewWrapper::can_capture_pointer() const {
- return _request_pointer_capture != nullptr && _release_pointer_capture != nullptr;
+ // We can capture the pointer if the other jni capture method ids are initialized,
+ // and GodotView#canCapturePointer() returns true.
+ if (_request_pointer_capture != nullptr && _release_pointer_capture != nullptr && _can_capture_pointer != nullptr) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_NULL_V(env, false);
+
+ return env->CallBooleanMethod(_godot_view, _can_capture_pointer);
+ }
+
+ return false;
}
void GodotJavaViewWrapper::request_pointer_capture() {
diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h
index 9b64ded29c..07742d6bb0 100644
--- a/platform/android/java_godot_view_wrapper.h
+++ b/platform/android/java_godot_view_wrapper.h
@@ -44,6 +44,7 @@ private:
jobject _godot_view;
+ jmethodID _can_capture_pointer = 0;
jmethodID _request_pointer_capture = 0;
jmethodID _release_pointer_capture = 0;
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 5c6c8454ec..a96dcca3b3 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -182,7 +182,7 @@ String OS_Android::get_name() const {
}
String OS_Android::get_system_property(const char *key) const {
- static String value;
+ String value;
char value_str[PROP_VALUE_MAX];
if (__system_property_get(key, value_str)) {
value = String(value_str);
@@ -230,20 +230,20 @@ String OS_Android::get_version() const {
"ro.potato.version", "ro.xtended.version", "org.evolution.version", "ro.corvus.version", "ro.pa.version",
"ro.crdroid.version", "ro.syberia.version", "ro.arrow.version", "ro.lineage.version" };
for (int i = 0; i < roms.size(); i++) {
- static String rom_version = get_system_property(roms[i]);
+ String rom_version = get_system_property(roms[i]);
if (!rom_version.is_empty()) {
return rom_version;
}
}
- static String mod_version = get_system_property("ro.modversion"); // Handles other Android custom ROMs.
+ String mod_version = get_system_property("ro.modversion"); // Handles other Android custom ROMs.
if (!mod_version.is_empty()) {
return mod_version;
}
// Handles stock Android.
- static String sdk_version = get_system_property("ro.build.version.sdk_int");
- static String build = get_system_property("ro.build.version.incremental");
+ String sdk_version = get_system_property("ro.build.version.sdk_int");
+ String build = get_system_property("ro.build.version.incremental");
if (!sdk_version.is_empty()) {
if (!build.is_empty()) {
return vformat("%s.%s", sdk_version, build);
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 8d8c8ce27b..2c093b00e7 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -215,39 +215,40 @@ String OS_LinuxBSD::get_name() const {
}
String OS_LinuxBSD::get_systemd_os_release_info_value(const String &key) const {
- static String info;
- if (info.is_empty()) {
- Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ);
- if (f.is_valid()) {
- while (!f->eof_reached()) {
- const String line = f->get_line();
- if (line.find(key) != -1) {
- return line.split("=")[1].strip_edges();
- }
+ Ref<FileAccess> f = FileAccess::open("/etc/os-release", FileAccess::READ);
+ if (f.is_valid()) {
+ while (!f->eof_reached()) {
+ const String line = f->get_line();
+ if (line.find(key) != -1) {
+ String value = line.split("=")[1].strip_edges();
+ value = value.trim_prefix("\"");
+ return value.trim_suffix("\"");
}
}
}
- return info;
+ return "";
}
String OS_LinuxBSD::get_distribution_name() const {
- static String systemd_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string.
- if (!systemd_name.is_empty()) {
- return systemd_name;
+ static String distribution_name = get_systemd_os_release_info_value("NAME"); // returns a value for systemd users, otherwise an empty string.
+ if (!distribution_name.is_empty()) {
+ return distribution_name;
}
struct utsname uts; // returns a decent value for BSD family.
uname(&uts);
- return uts.sysname;
+ distribution_name = uts.sysname;
+ return distribution_name;
}
String OS_LinuxBSD::get_version() const {
- static String systemd_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string.
- if (!systemd_version.is_empty()) {
- return systemd_version;
+ static String release_version = get_systemd_os_release_info_value("VERSION"); // returns a value for systemd users, otherwise an empty string.
+ if (!release_version.is_empty()) {
+ return release_version;
}
struct utsname uts; // returns a decent value for BSD family.
uname(&uts);
- return uts.version;
+ release_version = uts.version;
+ return release_version;
}
Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const {
@@ -255,6 +256,11 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const {
return Vector<String>();
}
+ static Vector<String> info;
+ if (!info.is_empty()) {
+ return info;
+ }
+
const String rendering_device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name(); // e.g. `NVIDIA GeForce GTX 970`
const String rendering_device_vendor = RenderingServer::get_singleton()->get_rendering_device()->get_device_vendor_name(); // e.g. `NVIDIA`
const String card_name = rendering_device_name.trim_prefix(rendering_device_vendor).strip_edges(); // -> `GeForce GTX 970`
@@ -320,8 +326,8 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const {
Vector<String> class_display_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_display_device_candidates, kernel_lit, dummys);
Vector<String> class_3d_device_drivers = OS_LinuxBSD::lspci_get_device_value(class_3d_device_candidates, kernel_lit, dummys);
- static String driver_name;
- static String driver_version;
+ String driver_name;
+ String driver_version;
// Use first valid value:
for (const String &driver : class_3d_device_drivers) {
@@ -341,7 +347,6 @@ Vector<String> OS_LinuxBSD::get_video_adapter_driver_info() const {
}
}
- Vector<String> info;
info.push_back(driver_name);
String modinfo;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 38df68c764..df7923660c 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -450,8 +450,7 @@ String OS_UWP::get_distribution_name() const {
String OS_UWP::get_version() const {
winrt::hstring df_version = VersionInfo().DeviceFamilyVersion();
- static String version = String(winrt::to_string(df_version).c_str());
- return version;
+ return String(winrt::to_string(df_version).c_str());
}
OS::DateTime OS_UWP::get_datetime(bool p_utc) const {
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index ae1649c75d..2653efed71 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -453,14 +453,19 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return Vector<String>();
}
+ static Vector<String> info;
+ if (!info.is_empty()) {
+ return info;
+ }
+
REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID
REFIID uuid = IID_IWbemLocator; // Interface UUID
IWbemLocator *wbemLocator = NULL; // to get the services
IWbemServices *wbemServices = NULL; // to get the class
IEnumWbemClassObject *iter = NULL;
IWbemClassObject *pnpSDriverObject[1]; // contains driver name, version, etc.
- static String driver_name;
- static String driver_version;
+ String driver_name;
+ String driver_version;
const String device_name = RenderingServer::get_singleton()->get_rendering_device()->get_device_name();
if (device_name.is_empty()) {
@@ -536,7 +541,6 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
SAFE_RELEASE(wbemServices)
SAFE_RELEASE(iter)
- Vector<String> info;
info.push_back(driver_name);
info.push_back(driver_version);
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 5936fbc2c0..c1b1e6c287 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -527,7 +527,7 @@ AnimationNodeOneShot::AnimationNodeOneShot() {
////////////////////////////////////////////////
void AnimationNodeAdd2::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01,or_less,or_greater"));
}
Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_parameter) const {
@@ -561,7 +561,7 @@ AnimationNodeAdd2::AnimationNodeAdd2() {
////////////////////////////////////////////////
void AnimationNodeAdd3::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01,or_less,or_greater"));
}
Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_parameter) const {
@@ -597,7 +597,7 @@ AnimationNodeAdd3::AnimationNodeAdd3() {
/////////////////////////////////////////////
void AnimationNodeBlend2::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01,or_less,or_greater"));
}
Variant AnimationNodeBlend2::get_parameter_default_value(const StringName &p_parameter) const {
@@ -632,7 +632,7 @@ AnimationNodeBlend2::AnimationNodeBlend2() {
//////////////////////////////////////
void AnimationNodeBlend3::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01,or_less,or_greater"));
}
Variant AnimationNodeBlend3::get_parameter_default_value(const StringName &p_parameter) const {
@@ -661,6 +661,39 @@ AnimationNodeBlend3::AnimationNodeBlend3() {
add_input("+blend");
}
+////////////////////////////////////////////////
+
+void AnimationNodeSub2::get_parameter_list(List<PropertyInfo> *r_list) const {
+ r_list->push_back(PropertyInfo(Variant::FLOAT, sub_amount, PROPERTY_HINT_RANGE, "0,1,0.01,or_less,or_greater"));
+}
+
+Variant AnimationNodeSub2::get_parameter_default_value(const StringName &p_parameter) const {
+ return 0;
+}
+
+String AnimationNodeSub2::get_caption() const {
+ return "Sub2";
+}
+
+bool AnimationNodeSub2::has_filter() const {
+ return true;
+}
+
+double AnimationNodeSub2::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
+ double amount = get_parameter(sub_amount);
+ // Out = Sub.Transform3D^(-1) * In.Transform3D
+ blend_input(1, p_time, p_seek, p_is_external_seeking, -amount, FILTER_PASS, sync, p_test_only);
+ return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
+}
+
+void AnimationNodeSub2::_bind_methods() {
+}
+
+AnimationNodeSub2::AnimationNodeSub2() {
+ add_input("in");
+ add_input("sub");
+}
+
/////////////////////////////////
void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const {
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 25b001e973..2139af8a96 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -246,6 +246,26 @@ public:
AnimationNodeBlend3();
};
+class AnimationNodeSub2 : public AnimationNodeSync {
+ GDCLASS(AnimationNodeSub2, AnimationNodeSync);
+
+ StringName sub_amount = PNAME("sub_amount");
+
+protected:
+ static void _bind_methods();
+
+public:
+ void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
+
+ virtual String get_caption() const override;
+
+ virtual bool has_filter() const override;
+ virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
+
+ AnimationNodeSub2();
+};
+
class AnimationNodeTimeScale : public AnimationNode {
GDCLASS(AnimationNodeTimeScale, AnimationNode);
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 9835e7a065..ebf5d03a76 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1766,7 +1766,7 @@ void AnimationPlayer::set_current_animation(const String &p_anim) {
} else if (!is_playing()) {
play(p_anim);
} else if (playback.assigned != p_anim) {
- float speed = get_playing_speed();
+ float speed = playback.current.speed_scale;
play(p_anim, -1.0, speed, signbit(speed));
} else {
// Same animation, do not replay from start
@@ -1779,7 +1779,7 @@ String AnimationPlayer::get_current_animation() const {
void AnimationPlayer::set_assigned_animation(const String &p_anim) {
if (is_playing()) {
- float speed = get_playing_speed();
+ float speed = playback.current.speed_scale;
play(p_anim, -1.0, speed, signbit(speed));
} else {
ERR_FAIL_COND_MSG(!animation_set.has(p_anim), vformat("Animation not found: %s.", p_anim));
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 5d4d58f283..3e62dbc1a5 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -281,7 +281,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
if (r_max) {
*r_max = 0;
for (int i = 0; i < blend_count; i++) {
- *r_max = MAX(*r_max, blendw[i]);
+ *r_max = MAX(*r_max, Math::abs(blendw[i]));
}
}
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index e34384dd6c..5804d3250d 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -30,6 +30,7 @@
#include "button.h"
+#include "core/core_string_names.h"
#include "core/string/translation.h"
#include "servers/rendering_server.h"
@@ -533,8 +534,26 @@ String Button::get_language() const {
}
void Button::set_icon(const Ref<Texture2D> &p_icon) {
- if (icon != p_icon) {
- icon = p_icon;
+ if (icon == p_icon) {
+ return;
+ }
+
+ if (icon.is_valid()) {
+ icon->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Button::_texture_changed));
+ }
+
+ icon = p_icon;
+
+ if (icon.is_valid()) {
+ icon->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Button::_texture_changed));
+ }
+
+ queue_redraw();
+ update_minimum_size();
+}
+
+void Button::_texture_changed() {
+ if (icon.is_valid()) {
queue_redraw();
update_minimum_size();
}
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 792e7e24da..4fefb9fb07 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -96,6 +96,7 @@ private:
Size2 _fit_icon_size(const Size2 &p_size) const;
void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = "");
+ void _texture_changed();
protected:
void _set_internal_margin(Side p_side, float p_value);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index d65f94340b..cf2bbcb0a1 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1776,8 +1776,8 @@ Size2 LineEdit::get_minimum_size() const {
min_size.width = theme_cache.minimum_character_width * em_space_size;
if (expand_to_text_length) {
- // Add a space because some fonts are too exact, and because caret needs a bit more when at the end.
- min_size.width = MAX(min_size.width, full_width + em_space_size);
+ // Ensure some space for the caret when placed at the end.
+ min_size.width = MAX(min_size.width, full_width + theme_cache.caret_width);
}
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y, font->get_height(font_size));
diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp
index 38fd616892..c61e10b6fd 100644
--- a/scene/gui/menu_bar.cpp
+++ b/scene/gui/menu_bar.cpp
@@ -399,13 +399,18 @@ void MenuBar::_notification(int p_what) {
int MenuBar::_get_index_at_point(const Point2 &p_point) const {
Ref<StyleBox> style = theme_cache.normal;
int offset = 0;
+ Point2 point = p_point;
+ if (is_layout_rtl()) {
+ point.x = get_size().x - point.x;
+ }
+
for (int i = 0; i < menu_cache.size(); i++) {
if (menu_cache[i].hidden) {
continue;
}
Size2 size = menu_cache[i].text_buf->get_size() + style->get_minimum_size();
- if (p_point.x > offset && p_point.x < offset + size.x) {
- if (p_point.y > 0 && p_point.y < size.y) {
+ if (point.x > offset && point.x < offset + size.x) {
+ if (point.y > 0 && point.y < size.y) {
return i;
}
}
@@ -428,7 +433,12 @@ Rect2 MenuBar::_get_menu_item_rect(int p_index) const {
offset += size.x + theme_cache.h_separation;
}
- return Rect2(Point2(offset, 0), menu_cache[p_index].text_buf->get_size() + style->get_minimum_size());
+ Size2 size = menu_cache[p_index].text_buf->get_size() + style->get_minimum_size();
+ if (is_layout_rtl()) {
+ return Rect2(Point2(get_size().x - offset - size.x, 0), size);
+ } else {
+ return Rect2(Point2(offset, 0), size);
+ }
}
void MenuBar::_draw_menu_item(int p_index) {
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 00ed457201..c0a2dc81d0 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -96,6 +96,7 @@ void Popup::_notification(int p_what) {
}
} break;
+ case NOTIFICATION_UNPARENTED:
case NOTIFICATION_EXIT_TREE: {
if (!is_in_edited_scene_root()) {
_deinitialize_visible_parents();
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 2e6c6dc4bd..e640d87c01 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -47,8 +47,8 @@ String PopupMenu::_get_accel_text(const Item &p_item) const {
return String();
}
-Size2 PopupMenu::_get_item_icon_size(int p_item) const {
- const PopupMenu::Item &item = items[p_item];
+Size2 PopupMenu::_get_item_icon_size(int p_idx) const {
+ const PopupMenu::Item &item = items[p_idx];
Size2 icon_size = item.get_icon_size();
int max_width = 0;
@@ -126,22 +126,22 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
return minsize;
}
-int PopupMenu::_get_item_height(int p_item) const {
- ERR_FAIL_INDEX_V(p_item, items.size(), 0);
+int PopupMenu::_get_item_height(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), 0);
- Size2 icon_size = _get_item_icon_size(p_item);
+ Size2 icon_size = _get_item_icon_size(p_idx);
int icon_height = icon_size.height;
- if (items[p_item].checkable_type && !items[p_item].separator) {
+ if (items[p_idx].checkable_type && !items[p_idx].separator) {
icon_height = MAX(icon_height, MAX(theme_cache.checked->get_height(), theme_cache.radio_checked->get_height()));
}
- int text_height = items[p_item].text_buf->get_size().height;
- if (text_height == 0 && !items[p_item].separator) {
+ int text_height = items[p_idx].text_buf->get_size().height;
+ if (text_height == 0 && !items[p_idx].separator) {
text_height = theme_cache.font->get_height(theme_cache.font_size);
}
int separator_height = 0;
- if (items[p_item].separator) {
+ if (items[p_idx].separator) {
separator_height = MAX(theme_cache.separator_style->get_minimum_size().height, MAX(theme_cache.labeled_separator_left->get_minimum_size().height, theme_cache.labeled_separator_right->get_minimum_size().height));
}
@@ -769,24 +769,24 @@ void PopupMenu::_close_pressed() {
}
}
-void PopupMenu::_shape_item(int p_item) {
- if (items.write[p_item].dirty) {
- items.write[p_item].text_buf->clear();
+void PopupMenu::_shape_item(int p_idx) {
+ if (items.write[p_idx].dirty) {
+ items.write[p_idx].text_buf->clear();
- Ref<Font> font = items[p_item].separator ? theme_cache.font_separator : theme_cache.font;
- int font_size = items[p_item].separator ? theme_cache.font_separator_size : theme_cache.font_size;
+ Ref<Font> font = items[p_idx].separator ? theme_cache.font_separator : theme_cache.font;
+ int font_size = items[p_idx].separator ? theme_cache.font_separator_size : theme_cache.font_size;
- if (items[p_item].text_direction == Control::TEXT_DIRECTION_INHERITED) {
- items.write[p_item].text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
+ if (items[p_idx].text_direction == Control::TEXT_DIRECTION_INHERITED) {
+ items.write[p_idx].text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
} else {
- items.write[p_item].text_buf->set_direction((TextServer::Direction)items[p_item].text_direction);
+ items.write[p_idx].text_buf->set_direction((TextServer::Direction)items[p_idx].text_direction);
}
- items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].language);
+ items.write[p_idx].text_buf->add_string(items.write[p_idx].xl_text, font, font_size, items[p_idx].language);
- items.write[p_item].accel_text_buf->clear();
- items.write[p_item].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
- items.write[p_item].accel_text_buf->add_string(_get_accel_text(items.write[p_item]), font, font_size);
- items.write[p_item].dirty = false;
+ items.write[p_idx].accel_text_buf->clear();
+ items.write[p_idx].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
+ items.write[p_idx].accel_text_buf->add_string(_get_accel_text(items.write[p_idx]), font, font_size);
+ items.write[p_idx].dirty = false;
}
}
@@ -1192,27 +1192,27 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
_menu_changed();
}
-void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_text_direction) {
- if (p_item < 0) {
- p_item += get_item_count();
+void PopupMenu::set_item_text_direction(int p_idx, Control::TextDirection p_text_direction) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
}
- ERR_FAIL_INDEX(p_item, items.size());
+ ERR_FAIL_INDEX(p_idx, items.size());
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
- if (items[p_item].text_direction != p_text_direction) {
- items.write[p_item].text_direction = p_text_direction;
- items.write[p_item].dirty = true;
+ if (items[p_idx].text_direction != p_text_direction) {
+ items.write[p_idx].text_direction = p_text_direction;
+ items.write[p_idx].dirty = true;
control->queue_redraw();
}
}
-void PopupMenu::set_item_language(int p_item, const String &p_language) {
- if (p_item < 0) {
- p_item += get_item_count();
+void PopupMenu::set_item_language(int p_idx, const String &p_language) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
}
- ERR_FAIL_INDEX(p_item, items.size());
- if (items[p_item].language != p_language) {
- items.write[p_item].language = p_language;
- items.write[p_item].dirty = true;
+ ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].language != p_language) {
+ items.write[p_idx].language = p_language;
+ items.write[p_idx].dirty = true;
control->queue_redraw();
}
}
@@ -1378,14 +1378,14 @@ String PopupMenu::get_item_text(int p_idx) const {
return items[p_idx].text;
}
-Control::TextDirection PopupMenu::get_item_text_direction(int p_item) const {
- ERR_FAIL_INDEX_V(p_item, items.size(), Control::TEXT_DIRECTION_INHERITED);
- return items[p_item].text_direction;
+Control::TextDirection PopupMenu::get_item_text_direction(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Control::TEXT_DIRECTION_INHERITED);
+ return items[p_idx].text_direction;
}
-String PopupMenu::get_item_language(int p_item) const {
- ERR_FAIL_INDEX_V(p_item, items.size(), "");
- return items[p_item].language;
+String PopupMenu::get_item_language(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), "");
+ return items[p_idx].language;
}
int PopupMenu::get_item_idx_from_text(const String &text) const {
@@ -1697,17 +1697,17 @@ int PopupMenu::get_item_count() const {
return items.size();
}
-void PopupMenu::scroll_to_item(int p_item) {
- ERR_FAIL_INDEX(p_item, items.size());
+void PopupMenu::scroll_to_item(int p_idx) {
+ ERR_FAIL_INDEX(p_idx, items.size());
// Scroll item into view (upwards).
- if (items[p_item]._ofs_cache - scroll_container->get_v_scroll() < -control->get_position().y) {
- scroll_container->set_v_scroll(items[p_item]._ofs_cache + control->get_position().y);
+ if (items[p_idx]._ofs_cache - scroll_container->get_v_scroll() < -control->get_position().y) {
+ scroll_container->set_v_scroll(items[p_idx]._ofs_cache + control->get_position().y);
}
// Scroll item into view (downwards).
- if (items[p_item]._ofs_cache + items[p_item]._height_cache - scroll_container->get_v_scroll() > -control->get_position().y + scroll_container->get_size().height) {
- scroll_container->set_v_scroll(items[p_item]._ofs_cache + items[p_item]._height_cache + control->get_position().y);
+ if (items[p_idx]._ofs_cache + items[p_idx]._height_cache - scroll_container->get_v_scroll() > -control->get_position().y + scroll_container->get_size().height) {
+ scroll_container->set_v_scroll(items[p_idx]._ofs_cache + items[p_idx]._height_cache + control->get_position().y);
}
}
@@ -1768,10 +1768,10 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
return false;
}
-void PopupMenu::activate_item(int p_item) {
- ERR_FAIL_INDEX(p_item, items.size());
- ERR_FAIL_COND(items[p_item].separator);
- int id = items[p_item].id >= 0 ? items[p_item].id : p_item;
+void PopupMenu::activate_item(int p_idx) {
+ ERR_FAIL_INDEX(p_idx, items.size());
+ ERR_FAIL_COND(items[p_idx].separator);
+ int id = items[p_idx].id >= 0 ? items[p_idx].id : p_idx;
//hide all parent PopupMenus
Node *next = get_parent();
@@ -1780,11 +1780,11 @@ void PopupMenu::activate_item(int p_item) {
// We close all parents that are chained together,
// with hide_on_item_selection enabled
- if (items[p_item].checkable_type) {
+ if (items[p_idx].checkable_type) {
if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection()) {
break;
}
- } else if (0 < items[p_item].max_states) {
+ } else if (0 < items[p_idx].max_states) {
if (!hide_on_multistate_item_selection || !pop->is_hide_on_multistate_item_selection()) {
break;
}
@@ -1802,11 +1802,11 @@ void PopupMenu::activate_item(int p_item) {
bool need_hide = true;
- if (items[p_item].checkable_type) {
+ if (items[p_idx].checkable_type) {
if (!hide_on_checkable_item_selection) {
need_hide = false;
}
- } else if (0 < items[p_item].max_states) {
+ } else if (0 < items[p_idx].max_states) {
if (!hide_on_multistate_item_selection) {
need_hide = false;
}
@@ -1819,7 +1819,7 @@ void PopupMenu::activate_item(int p_item) {
}
emit_signal(SNAME("id_pressed"), id);
- emit_signal(SNAME("index_pressed"), p_item);
+ emit_signal(SNAME("index_pressed"), p_idx);
}
void PopupMenu::remove_item(int p_idx) {
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 0926ee7e55..642fc7d7dc 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -103,11 +103,11 @@ class PopupMenu : public Popup {
int _get_mouse_over(const Point2 &p_over) const;
virtual Size2 _get_contents_minimum_size() const override;
- int _get_item_height(int p_item) const;
+ int _get_item_height(int p_idx) const;
int _get_items_total_height() const;
- Size2 _get_item_icon_size(int p_item) const;
+ Size2 _get_item_icon_size(int p_idx) const;
- void _shape_item(int p_item);
+ void _shape_item(int p_idx);
virtual void gui_input(const Ref<InputEvent> &p_event);
void _activate_submenu(int p_over, bool p_by_keyboard = false);
@@ -277,10 +277,10 @@ public:
void set_item_count(int p_count);
int get_item_count() const;
- void scroll_to_item(int p_item);
+ void scroll_to_item(int p_idx);
bool activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only = false);
- void activate_item(int p_item);
+ void activate_item(int p_idx);
void remove_item(int p_idx);
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index aa27a69538..b07a3d7669 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -30,6 +30,7 @@
#include "texture_button.h"
+#include "core/core_string_names.h"
#include "core/typedefs.h"
#include <stdlib.h>
@@ -294,42 +295,19 @@ void TextureButton::_bind_methods() {
}
void TextureButton::set_texture_normal(const Ref<Texture2D> &p_normal) {
- if (normal == p_normal) {
- return;
- }
-
- normal = p_normal;
- queue_redraw();
- update_minimum_size();
+ _set_texture(&normal, p_normal);
}
void TextureButton::set_texture_pressed(const Ref<Texture2D> &p_pressed) {
- if (pressed == p_pressed) {
- return;
- }
-
- pressed = p_pressed;
- queue_redraw();
- update_minimum_size();
+ _set_texture(&pressed, p_pressed);
}
void TextureButton::set_texture_hover(const Ref<Texture2D> &p_hover) {
- if (hover == p_hover) {
- return;
- }
-
- hover = p_hover;
- queue_redraw();
- update_minimum_size();
+ _set_texture(&hover, p_hover);
}
void TextureButton::set_texture_disabled(const Ref<Texture2D> &p_disabled) {
- if (disabled == p_disabled) {
- return;
- }
-
- disabled = p_disabled;
- queue_redraw();
+ _set_texture(&disabled, p_disabled);
}
void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
@@ -337,8 +315,7 @@ void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
return;
}
click_mask = p_click_mask;
- queue_redraw();
- update_minimum_size();
+ _texture_changed();
}
Ref<Texture2D> TextureButton::get_texture_normal() const {
@@ -369,6 +346,28 @@ void TextureButton::set_texture_focused(const Ref<Texture2D> &p_focused) {
focused = p_focused;
};
+void TextureButton::_set_texture(Ref<Texture2D> *p_destination, const Ref<Texture2D> &p_texture) {
+ DEV_ASSERT(p_destination);
+ Ref<Texture2D> &destination = *p_destination;
+ if (destination == p_texture) {
+ return;
+ }
+ if (destination.is_valid()) {
+ destination->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureButton::_texture_changed));
+ }
+ destination = p_texture;
+ if (destination.is_valid()) {
+ // Pass `CONNECT_REFERENCE_COUNTED` to avoid early disconnect in case the same texture is assigned to different "slots".
+ destination->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureButton::_texture_changed), CONNECT_REFERENCE_COUNTED);
+ }
+ _texture_changed();
+}
+
+void TextureButton::_texture_changed() {
+ queue_redraw();
+ update_minimum_size();
+}
+
bool TextureButton::get_ignore_texture_size() const {
return ignore_texture_size;
}
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index 2709546997..9d393d3c65 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -64,6 +64,9 @@ private:
bool hflip = false;
bool vflip = false;
+ void _set_texture(Ref<Texture2D> *p_destination, const Ref<Texture2D> &p_texture);
+ void _texture_changed();
+
protected:
virtual Size2 get_minimum_size() const override;
virtual bool has_point(const Point2 &p_point) const override;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 1cc4fbc635..532b431b06 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2837,7 +2837,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
title_bar.position.y -= title_height;
title_bar.size.y = title_height;
- if (title_bar.has_point(mb->get_position())) {
+ if (title_bar.size.y > 0 && title_bar.has_point(mb->get_position())) {
click_on_window = true;
int close_h_ofs = sw.window->get_theme_constant(SNAME("close_h_offset"));
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 175c2848b4..9f4ad88e64 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -524,8 +524,6 @@ void Window::set_ime_position(const Point2i &p_pos) {
bool Window::is_embedded() const {
ERR_READ_THREAD_GUARD_V(false);
- ERR_FAIL_COND_V(!is_inside_tree(), false);
-
return get_embedder() != nullptr;
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index e4e06a9a79..e204618954 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -465,6 +465,7 @@ void register_scene_types() {
GDREGISTER_CLASS(AnimationNodeAdd3);
GDREGISTER_CLASS(AnimationNodeBlend2);
GDREGISTER_CLASS(AnimationNodeBlend3);
+ GDREGISTER_CLASS(AnimationNodeSub2);
GDREGISTER_CLASS(AnimationNodeTimeScale);
GDREGISTER_CLASS(AnimationNodeTimeSeek);
GDREGISTER_CLASS(AnimationNodeTransition);
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 64e466cf75..5aaa41d518 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -114,6 +114,13 @@ int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_t
return ret;
}
+// TODO: Needed to make the curve editor function properly until https://github.com/godotengine/godot/issues/76985 is fixed.
+int Curve::add_point_no_update(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) {
+ int ret = _add_point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode);
+
+ return ret;
+}
+
int Curve::get_index(real_t p_offset) const {
// Lower-bound float binary search
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 19af200ba7..005d42610b 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -83,6 +83,11 @@ public:
real_t right_tangent = 0,
TangentMode left_mode = TANGENT_FREE,
TangentMode right_mode = TANGENT_FREE);
+ int add_point_no_update(Vector2 p_position,
+ real_t left_tangent = 0,
+ real_t right_tangent = 0,
+ TangentMode left_mode = TANGENT_FREE,
+ TangentMode right_mode = TANGENT_FREE);
void remove_point(int p_index);
void clear_points();
@@ -100,6 +105,8 @@ public:
real_t get_max_value() const { return _max_value; }
void set_max_value(real_t p_max);
+ real_t get_range() const { return _max_value - _min_value; }
+
real_t sample(real_t p_offset) const;
real_t sample_local_nocheck(int p_index, real_t p_local_offset) const;
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index eafc4bec7d..ec4b756a85 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -69,7 +69,12 @@ void Gradient::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_interpolation_mode", "interpolation_mode"), &Gradient::set_interpolation_mode);
ClassDB::bind_method(D_METHOD("get_interpolation_mode"), &Gradient::get_interpolation_mode);
+ ClassDB::bind_method(D_METHOD("set_interpolation_color_space", "interpolation_color_space"), &Gradient::set_interpolation_color_space);
+ ClassDB::bind_method(D_METHOD("get_interpolation_color_space"), &Gradient::get_interpolation_color_space);
+
+ ADD_GROUP("Interpolation", "interpolation_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "interpolation_mode", PROPERTY_HINT_ENUM, "Linear,Constant,Cubic"), "set_interpolation_mode", "get_interpolation_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "interpolation_color_space", PROPERTY_HINT_ENUM, "sRGB,Linear sRGB,Oklab"), "set_interpolation_color_space", "get_interpolation_color_space");
ADD_GROUP("Raw Data", "");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "offsets"), "set_offsets", "get_offsets");
@@ -78,6 +83,16 @@ void Gradient::_bind_methods() {
BIND_ENUM_CONSTANT(GRADIENT_INTERPOLATE_LINEAR);
BIND_ENUM_CONSTANT(GRADIENT_INTERPOLATE_CONSTANT);
BIND_ENUM_CONSTANT(GRADIENT_INTERPOLATE_CUBIC);
+
+ BIND_ENUM_CONSTANT(GRADIENT_COLOR_SPACE_SRGB);
+ BIND_ENUM_CONSTANT(GRADIENT_COLOR_SPACE_LINEAR_SRGB);
+ BIND_ENUM_CONSTANT(GRADIENT_COLOR_SPACE_OKLAB);
+}
+
+void Gradient::_validate_property(PropertyInfo &p_property) const {
+ if (p_property.name == "interpolation_color_space" && interpolation_mode == GRADIENT_INTERPOLATE_CONSTANT) {
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
}
Vector<float> Gradient::get_offsets() const {
@@ -101,12 +116,22 @@ Vector<Color> Gradient::get_colors() const {
void Gradient::set_interpolation_mode(Gradient::InterpolationMode p_interp_mode) {
interpolation_mode = p_interp_mode;
emit_signal(CoreStringNames::get_singleton()->changed);
+ notify_property_list_changed();
}
Gradient::InterpolationMode Gradient::get_interpolation_mode() {
return interpolation_mode;
}
+void Gradient::set_interpolation_color_space(Gradient::ColorSpace p_color_space) {
+ interpolation_color_space = p_color_space;
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+Gradient::ColorSpace Gradient::get_interpolation_color_space() {
+ return interpolation_color_space;
+}
+
void Gradient::set_offsets(const Vector<float> &p_offsets) {
points.resize(p_offsets.size());
for (int i = 0; i < points.size(); i++) {
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index 9e3267f37b..b88399117d 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -33,6 +33,8 @@
#include "core/io/resource.h"
+#include "thirdparty/misc/ok_color.h"
+
class Gradient : public Resource {
GDCLASS(Gradient, Resource);
OBJ_SAVE_TYPE(Gradient);
@@ -44,6 +46,12 @@ public:
GRADIENT_INTERPOLATE_CUBIC,
};
+ enum ColorSpace {
+ GRADIENT_COLOR_SPACE_SRGB,
+ GRADIENT_COLOR_SPACE_LINEAR_SRGB,
+ GRADIENT_COLOR_SPACE_OKLAB,
+ };
+
struct Point {
float offset = 0.0;
Color color;
@@ -56,6 +64,7 @@ private:
Vector<Point> points;
bool is_sorted = true;
InterpolationMode interpolation_mode = GRADIENT_INTERPOLATE_LINEAR;
+ ColorSpace interpolation_color_space = GRADIENT_COLOR_SPACE_SRGB;
_FORCE_INLINE_ void _update_sorting() {
if (!is_sorted) {
@@ -64,8 +73,55 @@ private:
}
}
+ _FORCE_INLINE_ Color transform_color_space(const Color p_color) const {
+ switch (interpolation_color_space) {
+ case GRADIENT_COLOR_SPACE_SRGB:
+ default:
+ return p_color;
+
+ case GRADIENT_COLOR_SPACE_LINEAR_SRGB:
+ return p_color.srgb_to_linear();
+
+ case GRADIENT_COLOR_SPACE_OKLAB:
+ Color linear_color = p_color.srgb_to_linear();
+ ok_color::RGB rgb{};
+ rgb.r = linear_color.r;
+ rgb.g = linear_color.g;
+ rgb.b = linear_color.b;
+
+ ok_color ok_color;
+ ok_color::Lab lab_color = ok_color.linear_srgb_to_oklab(rgb);
+
+ // Constructs an RGB color using the Lab values directly. This allows reusing the interpolation code.
+ return { lab_color.L, lab_color.a, lab_color.b, linear_color.a };
+ }
+ }
+
+ _FORCE_INLINE_ Color inv_transform_color_space(const Color p_color) const {
+ switch (interpolation_color_space) {
+ case GRADIENT_COLOR_SPACE_SRGB:
+ default:
+ return p_color;
+
+ case GRADIENT_COLOR_SPACE_LINEAR_SRGB:
+ return p_color.linear_to_srgb();
+
+ case GRADIENT_COLOR_SPACE_OKLAB:
+ ok_color::Lab lab{};
+ lab.L = p_color.r;
+ lab.a = p_color.g;
+ lab.b = p_color.b;
+
+ ok_color new_ok_color;
+ ok_color::RGB ok_rgb = new_ok_color.oklab_to_linear_srgb(lab);
+ Color linear{ ok_rgb.r, ok_rgb.g, ok_rgb.b, p_color.a };
+ return linear.linear_to_srgb();
+ }
+ }
+
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &p_property) const;
public:
Gradient();
@@ -92,6 +148,9 @@ public:
void set_interpolation_mode(InterpolationMode p_interp_mode);
InterpolationMode get_interpolation_mode();
+ void set_interpolation_color_space(Gradient::ColorSpace p_color_space);
+ ColorSpace get_interpolation_color_space();
+
_FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
if (points.is_empty()) {
return Color(0, 0, 0, 1);
@@ -134,16 +193,22 @@ public:
if (first < 0) {
return points[0].color;
}
- const Point &pointFirst = points[first];
- const Point &pointSecond = points[second];
+ const Point &point1 = points[first];
+ const Point &point2 = points[second];
+ float weight = (p_offset - point1.offset) / (point2.offset - point1.offset);
switch (interpolation_mode) {
- case GRADIENT_INTERPOLATE_LINEAR: {
- return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
- } break;
case GRADIENT_INTERPOLATE_CONSTANT: {
- return pointFirst.color;
- } break;
+ return point1.color;
+ }
+ case GRADIENT_INTERPOLATE_LINEAR:
+ default: { // Fallback to linear interpolation.
+ Color color1 = transform_color_space(point1.color);
+ Color color2 = transform_color_space(point2.color);
+
+ Color interpolated = color1.lerp(color2, weight);
+ return inv_transform_color_space(interpolated);
+ }
case GRADIENT_INTERPOLATE_CUBIC: {
int p0 = first - 1;
int p3 = second + 1;
@@ -153,20 +218,21 @@ public:
if (p0 < 0) {
p0 = first;
}
- const Point &pointP0 = points[p0];
- const Point &pointP3 = points[p3];
-
- float x = (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset);
- float r = Math::cubic_interpolate(pointFirst.color.r, pointSecond.color.r, pointP0.color.r, pointP3.color.r, x);
- float g = Math::cubic_interpolate(pointFirst.color.g, pointSecond.color.g, pointP0.color.g, pointP3.color.g, x);
- float b = Math::cubic_interpolate(pointFirst.color.b, pointSecond.color.b, pointP0.color.b, pointP3.color.b, x);
- float a = Math::cubic_interpolate(pointFirst.color.a, pointSecond.color.a, pointP0.color.a, pointP3.color.a, x);
-
- return Color(r, g, b, a);
- } break;
- default: {
- // Fallback to linear interpolation.
- return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
+ const Point &point0 = points[p0];
+ const Point &point3 = points[p3];
+
+ Color color0 = transform_color_space(point0.color);
+ Color color1 = transform_color_space(point1.color);
+ Color color2 = transform_color_space(point2.color);
+ Color color3 = transform_color_space(point3.color);
+
+ Color interpolated;
+ interpolated[0] = Math::cubic_interpolate(color1[0], color2[0], color0[0], color3[0], weight);
+ interpolated[1] = Math::cubic_interpolate(color1[1], color2[1], color0[1], color3[1], weight);
+ interpolated[2] = Math::cubic_interpolate(color1[2], color2[2], color0[2], color3[2], weight);
+ interpolated[3] = Math::cubic_interpolate(color1[3], color2[3], color0[3], color3[3], weight);
+
+ return inv_transform_color_space(interpolated);
}
}
}
@@ -175,5 +241,6 @@ public:
};
VARIANT_ENUM_CAST(Gradient::InterpolationMode);
+VARIANT_ENUM_CAST(Gradient::ColorSpace);
#endif // GRADIENT_H
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 7de10149db..bc084e7dbb 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2428,6 +2428,8 @@ float GradientTexture2D::_get_gradient_offset_at(int x, int y) const {
}
} else if (fill == Fill::FILL_RADIAL) {
ofs = (pos - fill_from).length() / (fill_to - fill_from).length();
+ } else if (fill == Fill::FILL_SQUARE) {
+ ofs = MAX(Math::abs(pos.x - fill_from.x), Math::abs(pos.y - fill_from.y)) / MAX(Math::abs(fill_to.x - fill_from.x), Math::abs(fill_to.y - fill_from.y));
}
if (repeat == Repeat::REPEAT_NONE) {
ofs = CLAMP(ofs, 0.0, 1.0);
@@ -2556,7 +2558,7 @@ void GradientTexture2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
ADD_GROUP("Fill", "fill_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "fill", PROPERTY_HINT_ENUM, "Linear,Radial"), "set_fill", "get_fill");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fill", PROPERTY_HINT_ENUM, "Linear,Radial,Square"), "set_fill", "get_fill");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fill_from"), "set_fill_from", "get_fill_from");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fill_to"), "set_fill_to", "get_fill_to");
@@ -2565,6 +2567,7 @@ void GradientTexture2D::_bind_methods() {
BIND_ENUM_CONSTANT(FILL_LINEAR);
BIND_ENUM_CONSTANT(FILL_RADIAL);
+ BIND_ENUM_CONSTANT(FILL_SQUARE);
BIND_ENUM_CONSTANT(REPEAT_NONE);
BIND_ENUM_CONSTANT(REPEAT);
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 50bcec58f6..6b5e87ae21 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -829,6 +829,7 @@ public:
enum Fill {
FILL_LINEAR,
FILL_RADIAL,
+ FILL_SQUARE,
};
enum Repeat {
REPEAT_NONE,
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 38b9367cbd..df455b27d9 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -207,8 +207,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_SUB: {
blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
- blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
+ blend_attachment.color_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 0cc08975a5..23714c1091 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -218,8 +218,8 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_SUB: {
blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
- blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
+ blend_attachment.color_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 5c6f630355..72a42265b3 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1202,7 +1202,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
state.light_uniforms[index].color[i] = l->color[i];
}
- state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate
+ state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
if (state.shadow_fb.is_valid()) {
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
@@ -1264,7 +1264,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
state.light_uniforms[index].color[i] = l->color[i];
}
- state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate
+ state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
if (state.shadow_fb.is_valid()) {
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
@@ -2121,8 +2121,8 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_SUB: {
attachment.enable_blend = true;
- attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
- attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
+ attachment.alpha_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
+ attachment.color_blend_op = RD::BLEND_OP_REVERSE_SUBTRACT;
attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index c96524b5c9..7deeacf86e 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -568,7 +568,7 @@ void main() {
}
#ifdef MODE_LIGHT_ONLY
- color = vec4(0.0);
+ float light_only_alpha = 0.0;
#elif !defined(MODE_UNSHADED)
color *= canvas_data.canvas_modulation;
#endif
@@ -611,6 +611,9 @@ void main() {
}
light_blend_compute(light_base, light_color, color.rgb);
+#ifdef MODE_LIGHT_ONLY
+ light_only_alpha += light_color.a;
+#endif
}
// Positional Lights
@@ -695,8 +698,15 @@ void main() {
}
light_blend_compute(light_base, light_color, color.rgb);
+#ifdef MODE_LIGHT_ONLY
+ light_only_alpha += light_color.a;
+#endif
}
#endif
+#ifdef MODE_LIGHT_ONLY
+ color.a *= light_only_alpha;
+#endif
+
frag_color = color;
}
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 929cbc9ec6..329344d4c4 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -714,6 +714,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
real_t width = 0.f;
int line_start = MAX(p_start, range.x);
+ int last_end = line_start;
int prev_safe_break = 0;
int last_safe_break = -1;
int word_count = 0;
@@ -739,12 +740,18 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count;
}
- lines.push_back(l_gl[start_pos].start);
- lines.push_back(l_gl[end_pos].end);
+ if (last_end <= l_gl[start_pos].start) {
+ lines.push_back(l_gl[start_pos].start);
+ lines.push_back(l_gl[end_pos].end);
+ last_end = l_gl[end_pos].end;
+ }
trim_next = true;
} else {
- lines.push_back(line_start);
- lines.push_back(l_gl[last_safe_break].end);
+ if (last_end <= line_start) {
+ lines.push_back(line_start);
+ lines.push_back(l_gl[last_safe_break].end);
+ last_end = l_gl[last_safe_break].end;
+ }
}
line_start = l_gl[last_safe_break].end;
prev_safe_break = last_safe_break + 1;
@@ -772,12 +779,18 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count;
}
- lines.push_back(l_gl[start_pos].start);
- lines.push_back(l_gl[end_pos].end);
+ if (last_end <= l_gl[start_pos].start) {
+ lines.push_back(l_gl[start_pos].start);
+ lines.push_back(l_gl[end_pos].end);
+ last_end = l_gl[end_pos].end;
+ }
trim_next = false;
} else {
- lines.push_back(line_start);
- lines.push_back(l_gl[i].end);
+ if (last_end <= line_start) {
+ lines.push_back(line_start);
+ lines.push_back(l_gl[i].end);
+ last_end = l_gl[i].end;
+ }
}
line_start = l_gl[i].end;
prev_safe_break = i + 1;
@@ -833,6 +846,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
double width = 0.f;
int line_start = MAX(p_start, range.x);
+ int last_end = line_start;
int prev_safe_break = 0;
int last_safe_break = -1;
int word_count = 0;
@@ -857,12 +871,18 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count;
}
- lines.push_back(l_gl[start_pos].start);
- lines.push_back(l_gl[end_pos].end);
+ if (last_end <= l_gl[start_pos].start) {
+ lines.push_back(l_gl[start_pos].start);
+ lines.push_back(l_gl[end_pos].end);
+ last_end = l_gl[end_pos].end;
+ }
trim_next = true;
} else {
- lines.push_back(line_start);
- lines.push_back(l_gl[last_safe_break].end);
+ if (last_end <= line_start) {
+ lines.push_back(line_start);
+ lines.push_back(l_gl[last_safe_break].end);
+ last_end = l_gl[last_safe_break].end;
+ }
}
line_start = l_gl[last_safe_break].end;
prev_safe_break = last_safe_break + 1;
@@ -884,11 +904,17 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
end_pos -= l_gl[end_pos].count;
}
trim_next = false;
- lines.push_back(l_gl[start_pos].start);
- lines.push_back(l_gl[end_pos].end);
+ if (last_end <= l_gl[start_pos].start) {
+ lines.push_back(l_gl[start_pos].start);
+ lines.push_back(l_gl[end_pos].end);
+ last_end = l_gl[end_pos].end;
+ }
} else {
- lines.push_back(line_start);
- lines.push_back(l_gl[i].end);
+ if (last_end <= line_start) {
+ lines.push_back(line_start);
+ lines.push_back(l_gl[i].end);
+ last_end = l_gl[i].end;
+ }
}
line_start = l_gl[i].end;
prev_safe_break = i + 1;
diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h
index 763eaed2f8..d6eaa8bd77 100644
--- a/tests/core/io/test_image.h
+++ b/tests/core/io/test_image.h
@@ -303,6 +303,27 @@ TEST_CASE("[Image] Modifying pixels of an image") {
CHECK_MESSAGE(
image3->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 0)),
"flip_y() should not leave old pixels behind.");
+
+ // Pre-multiply Alpha then Convert from RGBA to L8, checking alpha
+ {
+ Ref<Image> gray_image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
+ CHECK_NOTHROW_MESSAGE(gray_image->fill_rect(Rect2i(0, 0, 3, 3), Color(1, 1, 1, 0)), "fill_rect() shouldn't throw for any rect.");
+ gray_image->set_pixel(1, 1, Color(1, 1, 1, 1));
+ gray_image->set_pixel(1, 2, Color(0.5, 0.5, 0.5, 0.5));
+ gray_image->set_pixel(2, 1, Color(0.25, 0.05, 0.5, 1.0));
+ gray_image->set_pixel(2, 2, Color(0.5, 0.25, 0.95, 0.75));
+ gray_image->premultiply_alpha();
+ gray_image->convert(Image::FORMAT_L8);
+ CHECK_MESSAGE(gray_image->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
+ CHECK_MESSAGE(gray_image->get_pixel(0, 1).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
+ CHECK_MESSAGE(gray_image->get_pixel(0, 2).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
+ CHECK_MESSAGE(gray_image->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
+ CHECK_MESSAGE(gray_image->get_pixel(1, 1).is_equal_approx(Color(1, 1, 1, 1)), "convert() RGBA to L8 should be white.");
+ CHECK_MESSAGE(gray_image->get_pixel(1, 2).is_equal_approx(Color(0.250980407, 0.250980407, 0.250980407, 1)), "convert() RGBA to L8 should be around 0.250980407 (64).");
+ CHECK_MESSAGE(gray_image->get_pixel(2, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
+ CHECK_MESSAGE(gray_image->get_pixel(2, 1).is_equal_approx(Color(0.121568628, 0.121568628, 0.121568628, 1)), "convert() RGBA to L8 should be around 0.121568628 (31).");
+ CHECK_MESSAGE(gray_image->get_pixel(2, 2).is_equal_approx(Color(0.266666681, 0.266666681, 0.266666681, 1)), "convert() RGBA to L8 should be around 0.266666681 (68).");
+ }
}
} // namespace TestImage