diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dac9fa87d2c..028da18569c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: - name: Linter checks run: | bash _tools/format.sh - codespell -I _tools/codespell-ignore.txt -x _tools/codespell-ignore-lines.txt -S tutorials/i18n/locales.rst {about,community,development,getting_started,tutorials}/**/*.rst + codespell -I _tools/codespell-ignore.txt -x _tools/codespell-ignore-lines.txt -S tutorials/i18n/locales.rst {about,community,contributing,getting_started,tutorials}/**/*.rst # Use dummy builder to improve performance as we don't need the generated HTML in this workflow. - name: Sphinx build diff --git a/_extensions/gdscript.py b/_extensions/gdscript.py index b2f65261c73..5da987c462f 100644 --- a/_extensions/gdscript.py +++ b/_extensions/gdscript.py @@ -341,6 +341,8 @@ def innerstring_rules(ttype): "AABB", "Plane", "Quaternion", + "Vector4", + "Vector4i", "Basis", "Transform3D", "Color", @@ -355,9 +357,8 @@ def innerstring_rules(ttype): "PackedFloat64Array", "PackedStringArray", "PackedVector2Array", - "PackedVector2iArray", "PackedVector3Array", - "PackedVector3iArray", + "PackedVector4Array", "PackedColorArray", "null", "void", diff --git a/about/faq.rst b/about/faq.rst index 33f627a1c5f..a5864dba9b4 100644 --- a/about/faq.rst +++ b/about/faq.rst @@ -115,9 +115,8 @@ If you've ever written anything in a language like Python before, then you'll fe right at home. For examples and a complete overview of the power GDScript offers you, check out the :ref:`GDScript scripting guide `. -There are several reasons to use GDScript, especially when you are prototyping, in -alpha/beta stages of your project, or are not creating the next AAA title. The -most salient reason is the overall **reduction of complexity**. +There are several reasons to use GDScript, but the most salient reason is the overall +**reduction of complexity**. The original intent of creating a tightly integrated, custom scripting language for Godot was two-fold: first, it reduces the amount of time necessary to get up and running @@ -133,7 +132,7 @@ more familiar programming languages, especially when supporting those more famil languages would result in a worse experience. We understand if you would rather use another language in Godot (see the list of supported options above). That being said, if you haven't given GDScript a try, try it for **three days**. Just like Godot, -once you see how powerful it is and rapid your development becomes, we think GDScript +once you see how powerful it is and how rapid your development becomes, we think GDScript will grow on you. More information about getting comfortable with GDScript or dynamically typed diff --git a/about/introduction.rst b/about/introduction.rst index c3314f475bf..c7df54d5de3 100644 --- a/about/introduction.rst +++ b/about/introduction.rst @@ -28,8 +28,8 @@ consider checking them out. Otherwise, :ref:`Getting Started `, -especially the Godot `Discord`_ community and +you can find help on the various `Community channels `_, +especially the Godot `Discord `_ community and `Forum `_. About Godot Engine @@ -75,11 +75,10 @@ This documentation is organized into several sections: It also contains sections intended for advanced users and contributors, with information on compiling the engine, contributing to the editor, or developing C++ modules. -- **Community** is dedicated to the life of Godot's community. - It points to various community channels like the - `Godot Contributors Chat `_ and - `Discord`_ and contains a list of recommended third-party tutorials and - materials outside of this documentation. +- **Community** is dedicated to the life of Godot's community and contains a list of + recommended third-party tutorials and materials outside of this documentation. + It also provides details on the Asset Library. It also used to list Godot + communities, which are now listed on the `Godot website `_. - Finally, the **Class reference** documents the full Godot API, also available directly within the engine's script editor. You can find information on all classes, functions, signals and so on here. @@ -104,5 +103,3 @@ with attribution to "*Juan Linietsky, Ariel Manzur, and the Godot Engine communi unless otherwise noted. *Have fun reading and making games with Godot Engine!* - -.. _Discord: https://discord.gg/4JBkykG diff --git a/about/system_requirements.rst b/about/system_requirements.rst index 528e1056c3e..f5a96f9b0d9 100644 --- a/about/system_requirements.rst +++ b/about/system_requirements.rst @@ -100,8 +100,7 @@ Mobile device (smartphone/tablet) - Minimum | | Exporting projects requires downloading export templates separately | | | (1.3 GB after installation). | +----------------------+-----------------------------------------------------------------------------------------+ -| **Operating system** | - **Native editor:** Android 6.0 (Compatibility) or Android 9.0 (Forward+/Mobile), | -| | iOS 11.0 | +| **Operating system** | - **Native editor:** Android 6.0 (Compatibility) or Android 9.0 (Forward+/Mobile) | | | - **Web editor:** Firefox 79, Chrome 88, Edge 79, Safari 15.2, Opera 64, | | | Samsung Internet 15 | +----------------------+-----------------------------------------------------------------------------------------+ @@ -174,7 +173,7 @@ Mobile device (smartphone/tablet) - Recommended +----------------------+-----------------------------------------------------------------------------------------+ | **Storage** | 1.5 GB (used for the executable, project files, all export templates and cache) | +----------------------+-----------------------------------------------------------------------------------------+ -| **Operating system** | - **Native editor:** Android 9.0 or iOS 11.0 | +| **Operating system** | - **Native editor:** Android 9.0 | | | - **Web editor:** Latest version of Firefox, Chrome, Edge, Safari, Opera, | | | Samsung Internet | +----------------------+-----------------------------------------------------------------------------------------+ @@ -268,15 +267,15 @@ Mobile device (smartphone/tablet) - Minimum +----------------------+-----------------------------------------------------------------------------------------+ | **GPU** | - **Forward+ rendering method:** SoC featuring GPU with full Vulkan 1.0 support | | | | -| | - *Example: Qualcomm Adreno 505, Mali-G71 MP2, PowerVR G6430 (iPhone 6S/iPhone SE 1)* | +| | - *Example: Qualcomm Adreno 505, Mali-G71 MP2, Apple A12 (iPhone XR/XS)* | | | | | | - **Mobile rendering method:** SoC featuring GPU with full Vulkan 1.0 support | | | | -| | - *Example: Qualcomm Adreno 505, Mali-G71 MP2, PowerVR G6430 (iPhone 6S/iPhone SE 1)* | +| | - *Example: Qualcomm Adreno 505, Mali-G71 MP2, Apple A12 (iPhone XR/XS)* | | | | | | - **Compatibility rendering method:** SoC featuring GPU with full OpenGL ES 3.0 support | | | | -| | - *Example: Qualcomm Adreno 306, Mali-T628 MP6, PowerVR G6430 (iPhone 5S)* | +| | - *Example: Qualcomm Adreno 306, Mali-T628 MP6, Apple A7 (iPhone 5S)* | +----------------------+-----------------------------------------------------------------------------------------+ | **RAM** | - **For native exports:** 1 GB | | | - **For web exports:** 2 GB | @@ -284,7 +283,7 @@ Mobile device (smartphone/tablet) - Minimum | **Storage** | 150 MB (used for the executable, project files and cache) | +----------------------+-----------------------------------------------------------------------------------------+ | **Operating system** | - **For native exports:** Android 6.0 (Compatibility) or Android 9.0 (Forward+/Mobile), | -| | iOS 11.0 | +| | iOS 12.0 | | | - **For web exports:** Firefox 79, Chrome 88, Edge 79, Safari 15.2, Opera 64, | | | Samsung Internet 15 | +----------------------+-----------------------------------------------------------------------------------------+ @@ -340,26 +339,26 @@ Mobile device (smartphone/tablet) - Recommended | | | | | - **iOS:** SoC with 64-bit ARM CPU | | | | -| | - *Example: Apple A11 (iPhone XS/XR)* | +| | - *Example: Apple A14 (iPhone 12)* | +----------------------+-----------------------------------------------------------------------------------------+ | **GPU** | - **Forward+ rendering method:** SoC featuring GPU with full Vulkan 1.2 support | | | | -| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple G11P (iPhone XR/XS)* | +| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple A14 (iPhone 12)* | | | | | | - **Mobile rendering method:** SoC featuring GPU with full Vulkan 1.2 support | | | | -| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple G11P (iPhone XR/XS)* | +| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple A14 (iPhone 12)* | | | | | | - **Compatibility rendering method:** SoC featuring GPU with full OpenGL ES 3.2 support | | | | -| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple G11P (iPhone XR/XS)* | +| | - *Example: Qualcomm Adreno 630, Mali-G72 MP18, Apple A14 (iPhone 12)* | +----------------------+-----------------------------------------------------------------------------------------+ | **RAM** | - **For native exports:** 2 GB | | | - **For web exports:** 4 GB | +----------------------+-----------------------------------------------------------------------------------------+ | **Storage** | 150 MB (used for the executable, project files and cache) | +----------------------+-----------------------------------------------------------------------------------------+ -| **Operating system** | - **For native exports:** Android 9.0 or iOS 11.0 | +| **Operating system** | - **For native exports:** Android 9.0 or iOS 14.1 | | | - **For web exports:** Latest version of Firefox, Chrome, Edge, Safari, Opera, | | | Samsung Internet | +----------------------+-----------------------------------------------------------------------------------------+ diff --git a/community/channels.rst b/community/channels.rst index 584b1d3acd2..0af6ac166a8 100644 --- a/community/channels.rst +++ b/community/channels.rst @@ -5,42 +5,8 @@ Community channels So, where is the Godot community and where can you ask questions and get help? -Note that some of these channels are run and moderated by members of the Godot community or third parties. - -A brief overview over these and other channels is also available on the `Godot website `_. - -Forums ------- - -- `Official Godot Forum `_ -- `Community Forum `_ - -Chats ------ - -- `Godot Contributors Chat `_ -- `Discord `_ -- `Matrix (IRC compatible) `_ -- `IRC (#godotengine on Libera.Chat) `_ - -.. note:: - - As of January 2021, core developer chat has moved to the Godot Contributors Chat platform listed above. - IRC is less active. Please stick around to get an answer, - as it may take several hours for someone to see and answer your questions. - -Social networks and other sites -------------------------------- - -- `GitHub `_ -- `Facebook group `_ -- `Twitter `_ - (see also the `#GodotEngine `_ hashtag) -- `Reddit `_ -- `YouTube `_ -- `Steam `_ -- `itch.io `_ -- `Links `_ +This page used to list the various official and user-supported Godot communities. +That list is now available on the `Godot website `_. Language-based communities -------------------------- diff --git a/community/tutorials.rst b/community/tutorials.rst index 118e8853769..8a8467a43b6 100644 --- a/community/tutorials.rst +++ b/community/tutorials.rst @@ -14,31 +14,13 @@ The Godot video tutorials by `GDQuest `_ or `in the browser `_. -Some tutorials mentioned below provide more advanced tutorials, e.g. on 3D or shaders. +Some tutorials mentioned below cover more advanced subjects, e.g. on 3D or shaders. Video tutorials --------------- -- `Bastiaan Olij `_ (3D, AR and VR, GDScript) -- `BornCG `_ (2D and 3D, GDScript) -- `Clear Code `_ (2D, GDScript, Programming Basics) -- `FencerDevLog `_ (2D, 3D, GDScript, Shaders) -- `FinePointCGI `_ (2D, 3D, GDScript and C#) -- `GDQuest `_ (2D and 3D, GDScript and C#) -- `Game Dev Artisan `_ (2D, GDScript) -- `Game Development Center `_ (2D, networked multiplayer, GDScript) -- `Game Endeavor `_ (2D, GDScript) -- `Gwizz `_ (2D, GDScript) -- `Godotneers `_ (2D, Shaders, GDScript) -- `HeartBeast `_ (2D, GDScript) -- `Malcolm Nixon `_ (AR and VR, GDScript) -- `Muddy Wolf `_ (2D, 3D and VR, GDSCript) -- `KidsCanCode `__ (2D and 3D, GDScript) -- `Maker Tech `_ (2D, GDScript) -- `Pigdev `_ (2D, GDScript) -- `Queble `_ (2D, GDScript) -- `Quiver `_ (2D, GDScript) -- `Snopek Games `_ (3D, networked multiplayer, AR and VR, GDScript) +For video tutorials we recommend looking on `YouTube `_. There's many great +channels covering a wide array of subjects. Text tutorials -------------- diff --git a/contributing/development/compiling/compiling_for_ios.rst b/contributing/development/compiling/compiling_for_ios.rst index 0f87c331409..6cd9686f73c 100644 --- a/contributing/development/compiling/compiling_for_ios.rst +++ b/contributing/development/compiling/compiling_for_ios.rst @@ -53,13 +53,13 @@ Open a Terminal, go to the root dir of the engine source code and type: :: - $ scons p=ios target=template_debug + scons platform=ios target=template_debug for a debug build, or: :: - $ scons p=ios target=template_release + scons platform=ios target=template_release for a release build (check ``platform/ios/detect.py`` for the compiler flags used for each configuration). @@ -68,8 +68,8 @@ Alternatively, you can run :: - $ scons p=ios target=template_debug ios_simulator=yes arch=x86_64 - $ scons p=ios target=template_debug ios_simulator=yes arch=arm64 + scons platform=ios target=template_debug ios_simulator=yes arch=x86_64 + scons platform=ios target=template_debug ios_simulator=yes arch=arm64 for a Simulator libraries. @@ -79,13 +79,13 @@ should be placed in ``libgodot.ios.debug.xcframework`` and ``libgodot.ios.releas :: - $ cp -r misc/dist/ios_xcode . + cp -r misc/dist/ios_xcode . - $ cp libgodot.ios.template_debug.arm64.a ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a - $ lipo -create libgodot.ios.template_debug.arm64.simulator.a libgodot.ios.template_debug.x86_64.simulator.a -output ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a + cp libgodot.ios.template_debug.arm64.a ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a + lipo -create libgodot.ios.template_debug.arm64.simulator.a libgodot.ios.template_debug.x86_64.simulator.a -output ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a - $ cp libgodot.ios.template_release.arm64.a ios_xcode/libgodot.ios.release.xcframework/ios-arm64/libgodot.a - $ lipo -create libgodot.ios.template_release.arm64.simulator.a libgodot.ios.template_release.x86_64.simulator.a -output ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a + cp libgodot.ios.template_release.arm64.a ios_xcode/libgodot.ios.release.xcframework/ios-arm64/libgodot.a + lipo -create libgodot.ios.template_release.arm64.simulator.a libgodot.ios.template_release.x86_64.simulator.a -output ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a The MoltenVK static ``.xcframework`` folder must also be placed in the ``ios_xcode`` folder once it has been created. diff --git a/contributing/development/compiling/compiling_for_linuxbsd.rst b/contributing/development/compiling/compiling_for_linuxbsd.rst index 942b5dff642..f3fcbc3f368 100644 --- a/contributing/development/compiling/compiling_for_linuxbsd.rst +++ b/contributing/development/compiling/compiling_for_linuxbsd.rst @@ -363,6 +363,72 @@ You don't even need to copy them, you can just reference the resulting files in the ``bin/`` directory of your Godot source folder, so the next time you build, you automatically have the custom templates referenced. +Cross-compiling for RISC-V devices +---------------------------------- + +To cross-compile Godot for RISC-V devices, we need to setup the following items: + +- `riscv-gnu-toolchain `__. + While we are not going to use this directly, it provides us with a sysroot, as well + as header and libraries files that we will need. There are many versions to choose + from, however, the older the toolchain, the more compatible our final binaries will be. + If in doubt, `use this version `__, + and download ``riscv64-glibc-ubuntu-18.04-nightly-2021.12.22-nightly.tar.gz``. Extract + it somewhere and remember its path. +- Clang. RISC-V GCC has + `bugs with its atomic operations `__ + which prevent it from compiling Godot correctly. Any version of Clang from 16.0.0 upwards + will suffice. Download it from the package manager of your distro, and make sure that + it *can* compile to RISC-V. You can verify by executing this command ``clang -print-targets``, + make sure you see ``riscv64`` on the list of targets. +- `mold `__. This fast linker, + is the only one that correctly links the resulting binary. Download it, extract it, + and make sure to add its ``bin`` folder to your PATH. Run + ``mold --help | grep support`` to check if your version of Mold supports RISC-V. + If you don't see RISC-V, your Mold may need to be updated. + +To make referencing our toolchain easier, we can set an environment +variable like this: + +:: + + export RISCV_TOOLCHAIN_PATH="path to toolchain here" + +This way, we won't have to manually set the directory location +each time we want to reference it. + +With all the above setup, we are now ready to build Godot. + +Go to the root of the source code, and execute the following build command: + +:: + + scons arch=rv64 use_llvm=yes linker=mold lto=none target=editor \ + ccflags="--sysroot=$RISCV_TOOLCHAIN_PATH/sysroot --gcc-toolchain=$RISCV_TOOLCHAIN_PATH -target riscv64-unknown-linux-gnu" \ + linkflags="--sysroot=$RISCV_TOOLCHAIN_PATH/sysroot --gcc-toolchain=$RISCV_TOOLCHAIN_PATH -target riscv64-unknown-linux-gnu" + +The command is similar in nature, but with some key changes. ``ccflags`` and +``linkflags`` append additional flags to the build. ``--sysroot`` points to +a folder simulating a Linux system, it contains all the headers, libraries, +and ``.so`` files Clang will use. ``--gcc-toolchain`` tells Clang where +the complete toolchain is, and ``-target riscv64-unknown-linux-gnu`` +indicates to Clang the target architecture, and OS we want to build for. + +If all went well, you should now see a ``bin`` directory, and within it, +a binary similar to the following: + +:: + + godot.linuxbsd.editor.rv64.llvm + +You can now copy this executable to your favorite RISC-V device, +then launch it there by double-clicking, which should bring up +the project manager. + +If you later decide to compile the export templates, copy the above +build command but change the value of ``target`` to ``template_debug`` for +a debug build, or ``template_release`` for a release build. + Using Clang and LLD for faster development ------------------------------------------ diff --git a/contributing/development/compiling/compiling_for_windows.rst b/contributing/development/compiling/compiling_for_windows.rst index adea4528c71..d212027a75e 100644 --- a/contributing/development/compiling/compiling_for_windows.rst +++ b/contributing/development/compiling/compiling_for_windows.rst @@ -15,21 +15,24 @@ Requirements For compiling under Windows, the following is required: -- `Visual Studio Community `_, - version 2019 or later. Visual Studio 2022 is recommended. - **Make sure to enable C++ in the list of workflows to install.** - If you've already installed Visual Studio without C++ support, run the installer - again; it should present you a **Modify** button. - Supports ``x86_64``, ``x86_32``, and ``arm64``. -- `MinGW-w64 `_ with GCC can be used as an alternative to - Visual Studio. Be sure to install/configure it to use the ``posix`` thread model. - **Important:** When using MinGW to compile the ``master`` branch, you need GCC 9 or later. - Supports ``x86_64`` and ``x86_32`` only. -- `MinGW-LLVM `_ with clang can be used as - an alternative to Visual Studio and MinGW-w64. - Supports ``x86_64``, ``x86_32``, and ``arm64``. -- `Python 3.6+ `_. - **Make sure to enable the option to add Python to the ``PATH`` in the installer.** + +- A C++ compiler. Use one of the following: + + - `Visual Studio Community `_, + version 2019 or later. Visual Studio 2022 is recommended. + **Make sure to enable C++ in the list of workflows to install.** + If you've already installed Visual Studio without C++ support, run the installer + again; it should present you a **Modify** button. + Supports ``x86_64``, ``x86_32``, and ``arm64``. + - `MinGW-w64 `_ with GCC can be used as an alternative to + Visual Studio. Be sure to install/configure it to use the ``posix`` thread model. + **Important:** When using MinGW to compile the ``master`` branch, you need GCC 9 or later. + Supports ``x86_64`` and ``x86_32`` only. + - `MinGW-LLVM `_ with clang can be used as + an alternative to Visual Studio and MinGW-w64. + Supports ``x86_64``, ``x86_32``, and ``arm64``. +- `Python 3.6+ `_. + **Make sure to enable the option to add Python to the** ``PATH`` **in the installer.** - `SCons 3.1.2+ `_ build system. Using the latest release is recommended, especially for proper support of recent Visual Studio releases. @@ -314,7 +317,7 @@ codebase. To edit projects with Visual Studio they need to be set up as a soluti You can create a Visual Studio solution via SCons by running SCons with the ``vsproj=yes`` parameter, like this:: - scons p=windows vsproj=yes + scons platform=windows vsproj=yes You will be able to open Godot's source in a Visual Studio solution now, and able to build Godot using Visual Studio's **Build** button. diff --git a/contributing/development/compiling/compiling_with_dotnet.rst b/contributing/development/compiling/compiling_with_dotnet.rst index a544f97b5a2..342dddb404b 100644 --- a/contributing/development/compiling/compiling_with_dotnet.rst +++ b/contributing/development/compiling/compiling_with_dotnet.rst @@ -46,7 +46,7 @@ the desired targets without having to repeat this process. ```` refers to the editor binary you compiled with the .NET module enabled. Its exact name will differ based on your system and configuration, but should be of the form ``bin/godot..editor..mono``, e.g. -``bin/godot.linuxbsd.editor.x86_64.mono`` or +``bin/godot.linuxbsd.editor.x86_64.mono`` or ``bin/godot.windows.editor.x86_32.mono.exe``. Be especially aware of the **.mono** suffix! If you've previously compiled Godot without .NET support, you might have similarly named binaries without this suffix. These binaries can't be @@ -149,11 +149,11 @@ Example (Windows) :: # Build editor binary - scons p=windows target=editor module_mono_enabled=yes + scons platform=windows target=editor module_mono_enabled=yes # Build export templates - scons p=windows target=template_debug module_mono_enabled=yes - scons p=windows target=template_release module_mono_enabled=yes - + scons platform=windows target=template_debug module_mono_enabled=yes + scons platform=windows target=template_release module_mono_enabled=yes + # Generate glue sources bin/godot.windows.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue # Build .NET assemblies @@ -166,10 +166,10 @@ Example (Linux, \*BSD) :: # Build editor binary - scons p=linuxbsd target=editor module_mono_enabled=yes + scons platform=linuxbsd target=editor module_mono_enabled=yes # Build export templates - scons p=linuxbsd target=template_debug module_mono_enabled=yes - scons p=linuxbsd target=template_release module_mono_enabled=yes + scons platform=linuxbsd target=template_debug module_mono_enabled=yes + scons platform=linuxbsd target=template_release module_mono_enabled=yes # Generate glue sources bin/godot.linuxbsd.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue diff --git a/contributing/development/compiling/index.rst b/contributing/development/compiling/index.rst index 84742cb00e9..cba84bb22d2 100644 --- a/contributing/development/compiling/index.rst +++ b/contributing/development/compiling/index.rst @@ -18,8 +18,7 @@ stripped of extra modules, or an executable targeting engine development. The articles below should help you navigate configuration options available, as well as prerequisites required to compile Godot exactly the way you need. -Basics of building Godot ------------------------- +.. rubric:: Basics of building Godot Let's start with basics, and learn how to get Godot's source code, and then which options to use to compile it regardless of your target platform. @@ -31,8 +30,7 @@ to use to compile it regardless of your target platform. getting_source introduction_to_the_buildsystem -Building for target platforms ------------------------------ +.. rubric:: Building for target platforms Below you can find instructions for compiling the engine for your specific target platform. Note that Godot supports cross-compilation, which means you can compile it for a target platform @@ -51,8 +49,7 @@ will try their best to cover all possible situations. cross-compiling_for_ios_on_linux compiling_for_web -Other compilation targets and options -------------------------------------- +.. rubric:: Other compilation targets and options Some additional universal compilation options require further setup. Namely, while Godot does have C#/.NET support as a part of its main codebase, it does not get compiled by diff --git a/contributing/development/configuring_an_ide/visual_studio_code.rst b/contributing/development/configuring_an_ide/visual_studio_code.rst index 919f7e04273..165b2a14b2e 100644 --- a/contributing/development/configuring_an_ide/visual_studio_code.rst +++ b/contributing/development/configuring_an_ide/visual_studio_code.rst @@ -115,7 +115,7 @@ To run and debug the project you need to create a new configuration in the ``lau }, { "description": "Load custom pretty-printers for Godot types.", - "text": "source ${workspaceRoot}/misc/scripts/godot_gdb_pretty_print.py" + "text": "source ${workspaceRoot}/misc/utility/godot_gdb_pretty_print.py" } ], "preLaunchTask": "build" diff --git a/contributing/development/core_and_modules/custom_godot_servers.rst b/contributing/development/core_and_modules/custom_godot_servers.rst index 798c3b8d4bc..0158092b0be 100644 --- a/contributing/development/core_and_modules/custom_godot_servers.rst +++ b/contributing/development/core_and_modules/custom_godot_servers.rst @@ -483,7 +483,7 @@ Here is the GDScript sample code: func _ready(): print("Start debugging") - HilbertHotel.connect("occupy_room", self, "_print_occupy_room") + HilbertHotel.occupy_room.connect(_print_occupy_room) var rid = HilbertHotel.create_bus() OS.delay_msec(2000) HilbertHotel.create_bus() diff --git a/contributing/development/core_and_modules/custom_modules_in_cpp.rst b/contributing/development/core_and_modules/custom_modules_in_cpp.rst index b77c5d8c922..3d3362e33a0 100644 --- a/contributing/development/core_and_modules/custom_modules_in_cpp.rst +++ b/contributing/development/core_and_modules/custom_modules_in_cpp.rst @@ -547,7 +547,7 @@ main ``doc/classes`` directory. You can use Git to check if you have missed some of your classes by checking the untracked files with ``git status``. For example:: - user@host:~/godot$ git status + git status Example output:: @@ -573,7 +573,7 @@ Run command: :: - user@host:~/godot$ ./bin/ --doctool . + bin/ --doctool . Now if you go to the ``godot/modules/summator/doc_classes`` folder, you will see that it contains a ``Summator.xml`` file, or any other classes, that you referenced diff --git a/contributing/development/core_and_modules/index.rst b/contributing/development/core_and_modules/index.rst index 336cdb55502..a9727d8758d 100644 --- a/contributing/development/core_and_modules/index.rst +++ b/contributing/development/core_and_modules/index.rst @@ -6,8 +6,7 @@ Engine core and modules The following pages are meant to introduce the global organization of Godot Engine's source code, and give useful tips for extending and fixing the engine on the C++ side. -Getting started with Godot's source code ----------------------------------------- +.. rubric:: Getting started with Godot's source code This section covers the basics that you will encounter in (almost) every source file. @@ -25,8 +24,7 @@ This section covers the basics that you will encounter in (almost) every source 2d_coordinate_systems scripting_development -Extending Godot by modifying its source code --------------------------------------------- +.. rubric:: Extending Godot by modifying its source code This section covers what you can do by modifying Godot's C++ source code. diff --git a/contributing/development/core_and_modules/unit_testing.rst b/contributing/development/core_and_modules/unit_testing.rst index ebf2d2c008b..0f705693d62 100644 --- a/contributing/development/core_and_modules/unit_testing.rst +++ b/contributing/development/core_and_modules/unit_testing.rst @@ -129,6 +129,12 @@ Here's a minimal working test suite with a single test case written: #endif // TEST_STRING_H +.. note:: + You can quickly generate new tests using the ``create_test.py`` script found in the ``tests/`` directory. + This script automatically creates a new test file with the required boilerplate code in the appropriate location. + It's also able to automatically include the new header in ``tests/test_main.cpp`` using invasive mode (``-i`` flag). + To view usage instructions, run the script with the ``-h`` flag. + The ``tests/test_macros.h`` header encapsulates everything which is needed for writing C++ unit tests in Godot. It includes doctest assertion and logging macros such as ``CHECK`` as seen above, and of course the definitions for @@ -279,6 +285,48 @@ These tags can be added to the test case name to modify or extend the test envir You can use them together to combine multiple test environment extensions. +Testing signals +~~~~~~~~~~~~~~~ + +The following macros can be use to test signals: + +.. list-table:: + :header-rows: 1 + :widths: auto + + * - Macro + - Description + * - ``SIGNAL_WATCH(object, "signal_name")`` + - Starts watching the specified signal on the given object. + * - ``SIGNAL_UNWATCH(object, "signal_name")`` + - Stops watching the specified signal on the given object. + * - ``SIGNAL_CHECK("signal_name", Vector>)`` + - Checks the arguments of all fired signals. The outer vector contains each fired signal, while the inner vector contains the list of arguments for that signal. The order of signals is significant. + * - ``SIGNAL_CHECK_FALSE("signal_name")`` + - Checks if the specified signal was not fired. + * - ``SIGNAL_DISCARD("signal_name")`` + - Discards all records of the specified signal. + +Below is an example demonstrating the use of these macros: + +.. code-block:: cpp + + //... + SUBCASE("[Timer] Timer process timeout signal must be emitted") { + SIGNAL_WATCH(test_timer, SNAME("timeout")); + test_timer->start(0.1); + + SceneTree::get_singleton()->process(0.2); + + Array signal_args; + signal_args.push_back(Array()); + + SIGNAL_CHECK(SNAME("timeout"), signal_args); + + SIGNAL_UNWATCH(test_timer, SNAME("timeout")); + } + //... + Test tools ---------- diff --git a/contributing/development/debugging/index.rst b/contributing/development/debugging/index.rst index e72ba360fa2..4a5e82fe541 100644 --- a/contributing/development/debugging/index.rst +++ b/contributing/development/debugging/index.rst @@ -28,7 +28,7 @@ For example, using ``gdb`` directly, you may do this: .. code-block:: none - $ gdb godot + gdb godot > run -e --path ~/myproject You can also run the editor directly from your project's folder. In that case, @@ -36,8 +36,8 @@ only the ``-e`` option is required. .. code-block:: none - $ cd ~/myproject - $ gdb godot + cd ~/myproject + gdb godot > run -e You can learn more about these launch options and other command line arguments diff --git a/contributing/how_to_contribute.rst b/contributing/how_to_contribute.rst index fd8c61f3083..47733956731 100644 --- a/contributing/how_to_contribute.rst +++ b/contributing/how_to_contribute.rst @@ -3,7 +3,7 @@ How to contribute ================= -The Godot Engine is free and open-source. Like any community-driven project, we rely on volunteer contributions. +The Godot Engine is free and open-source. Like any community-driven project, we rely on volunteer contributions. On this page we want to showcase the various ways you as users can participate - to help you find the right starting place with the skillset you have. Because contrary to popular opinion, we need more than just programmers on the project! @@ -13,18 +13,18 @@ Fundraising - **Donate** - We created the non-profit `Godot Foundation `_ to be able to support the Godot Engine in both matters of finance and administration. - In practice, this means the Foundation hires people to work part-time or full-time on the project. + We created the non-profit `Godot Foundation `_ to be able to support the Godot Engine in both matters of finance and administration. + In practice, this means the Foundation hires people to work part-time or full-time on the project. These jobs include engine development as well as related tasks like code reviews, production management, community & marketing efforts, and more. - With as little as 5 EUR per month, you can help us keep going strong. + With as little as 5 EUR per month, you can help us keep going strong. Currently, we are intending to hire more core developers, as to cover more ground with full-time specialists that supplement and guide volunteer work. `Join the Development Fund `_ - **Donation Drives** Think about your followers on social media, or other communities you are active in. - Use that reach to remind your social environment that even small contributions can make a difference, especially when done by a great number of people at the same time. + Use that reach to remind your social environment that even small contributions can make a difference, especially when done by a great number of people at the same time. Are you a content creator? Consider adding a link to the `Godot Development Fund `_ to your descriptions. If you do live streams, perhaps think about organizing a stream with donation incentives. @@ -32,8 +32,8 @@ Fundraising .. - **Buy Official Merch** - **Publish Godot Games.** - You heard right, simply publishing a game #MadeWithGodot can positively impact the well-being of this project. - Your personal success elevates the engine to a viable alternative for other developers, growing the community further. + You heard right, simply publishing a game #MadeWithGodot can positively impact the well-being of this project. + Your personal success elevates the engine to a viable alternative for other developers, growing the community further. Additionally, it opens the doors for us to approach industry contacts about possible cooperations. @@ -49,62 +49,63 @@ Technical contributions - **Test Development Versions** While it is recommended to use the stable releases for your projects, you can help us test dev releases, betas, and release candidates - by opening a copy of your project in them and checking what problems this introduces or maybe even solves. + by opening a copy of your project in them and checking what problems this introduces or maybe even solves. Make sure to have a backup ready, since this can produce irreversible changes. Find recent `development versions `_ directly on our download page, or linked in their own blog posts. - + - **Contribute Engine Code (mainly C++)** - The engine development is mainly coordinated on our `Contributor RocketChat `_, + The engine development is mainly coordinated on our `Contributor RocketChat `_, so if you are serious about making PRs you should join us there! Read more about the **technical submission process**: :ref:`doc_first_steps` - For each subject area of the engine, there is a corresponding team to coordinate the work. - Join the linked chat to get more eyes on your related PR, learn about open todos, or partake in meetings. + For each subject area of the engine, there is a corresponding team to coordinate the work. + Join the linked chat to get more eyes on your related PR, learn about open todos, or partake in meetings. For some areas, specialists might even be encouraged to step up as maintainer! `List of teams `_ - **Review Code Contributions** All pull requests need to be thoroughly reviewed before they can be merged into the master branch. Help us get a headstart by participating in the code review process. - + To get started, chose any `open pull request `_ and reference our **style guide**: :ref:`doc_pr_review_guidelines` - **Write Plugins (GDScript, C#, & more)** Community addons are not directly included in the core engine download or repository, yet they provide essential quality of life upgrades for your fellow game developers. Upload your plugins to the `Godot Asset Library `_ to make them available to others. - .. update to talk about Asset Store later + .. + update to talk about Asset Store later - **Demo projects (GDScript, C#, and making Assets)** We provide new users with `demo projects `_ so they can quickly test new features or get familiar with the engine in the first place. - At industry events, we might even exhibit these demo projects to showcase what Godot can do! + At industry events, we might even exhibit these demo projects to showcase what Godot can do! Help improve existing projects or supply your own to be added to the pool, and join the `demo channel `_ in the Contributor RocketChat to talk about it. - **Documentation** - The documentation is one of the most essential parts of any tech project, yet the need to document new features and substantial changes often gets overlooked. + The documentation is one of the most essential parts of any tech project, yet the need to document new features and substantial changes often gets overlooked. Join the `documentation team `_ to improve the Godot Engine with your technical writing skills. - **Translations (spoken languages other than English)** - Are you interested in making the Godot Engine more accessible to non-English speakers? + Are you interested in making the Godot Engine more accessible to non-English speakers? Contribute to our `community-translations `_. Community support ----------------- - **Call for Moderators** - With a community of our size, we need people to step up as volunteer moderators in all kinds of places. + With a community of our size, we need people to step up as volunteer moderators in all kinds of places. These teams are organized by the Godot Foundation, but would not function without the dedication of active community members like you. - Have a look around your favorite community platform and you might come across open application calls. + Have a look around your favorite community platform and you might come across open application calls. - **Answer tech-support questions** - With many new people discovering the Godot Engine recently, the need for peer-to-peer tech-support has never been greater. - Be it on the `Forum `_, our `subreddit `_, or on `Discord `_, you can always brighten someone's day by helping them get their personal projects back on track. + With many new people discovering the Godot Engine recently, the need for peer-to-peer tech-support has never been greater. + See the `Godot website `_ for a list of official and user-supported Godot communities. - **Create tutorials & more** - How did you get started with the Godot Engine? + How did you get started with the Godot Engine? Chances are you looked for learning materials outside of what the documentation provides. Without content creators covering the game development process, there would not be this big of a community today. Therefore it seemed only right to mention them in a page about important contributions to the project. - + diff --git a/contributing/workflow/bisecting_regressions.rst b/contributing/workflow/bisecting_regressions.rst index 5e55a1598ba..6ccbfb1ff80 100644 --- a/contributing/workflow/bisecting_regressions.rst +++ b/contributing/workflow/bisecting_regressions.rst @@ -131,7 +131,7 @@ Example usage: .. code-block:: shell - $ gd_snapshot_commit 4.0 beta4 + gd_snapshot_commit 4.0 beta4 To refer to the latest state of the master branch, you can use ``master`` instead of a commit hash. Note that unlike tagged releases or snapshot commit @@ -148,15 +148,15 @@ folder and enter the following command: # is hash of the build that works as expected. # is hash of the build exhibiting the bug. - $ git bisect start - $ git bisect good - $ git bisect bad + git bisect start + git bisect good + git bisect bad Compile Godot. This assumes you've set up a build environment: .. code-block:: shell - $ scons + scons Run the engine ^^^^^^^^^^^^^^ @@ -173,13 +173,13 @@ If the build **still** exhibits the bug, run the following command: .. code-block:: shell - $ git bisect bad + git bisect bad If the build **does not** exhibit the bug, run the following command: .. code-block:: shell - $ git bisect good + git bisect good After entering one of the commands above, Git will switch to a different commit. You should now build Godot again, try to reproduce the bug, then enter ``git diff --git a/contributing/workflow/pr_workflow.rst b/contributing/workflow/pr_workflow.rst index b11b30d3415..0f373d3676f 100644 --- a/contributing/workflow/pr_workflow.rst +++ b/contributing/workflow/pr_workflow.rst @@ -95,7 +95,7 @@ To clone your fork from GitHub, use the following command: :: - $ git clone https://github.com/USERNAME/godot + git clone https://github.com/USERNAME/godot .. note:: In our examples, the "$" character denotes the command line prompt on typical UNIX shells. It is not part of the command and should @@ -106,14 +106,14 @@ working directory. Move into it using the ``cd`` command: :: - $ cd godot + cd godot We will start by setting up a reference to the original repository that we forked: :: - $ git remote add upstream https://github.com/godotengine/godot - $ git fetch upstream + git remote add upstream https://github.com/godotengine/godot + git fetch upstream This will create a reference named ``upstream`` pointing to the original ``godotengine/godot`` repository. This will be useful when you want to pull new @@ -149,30 +149,30 @@ a feature branch: :: # Create the branch based on the current branch (master) - $ git branch better-project-manager + git branch better-project-manager # Change the current branch to the new one - $ git checkout better-project-manager + git checkout better-project-manager This command is equivalent: :: # Change the current branch to a new named one, based on the current branch - $ git checkout -b better-project-manager + git checkout -b better-project-manager If you want to go back to the ``master`` branch, you'd use: :: - $ git checkout master + git checkout master You can see which branch you are currently on with the ``git branch`` command: :: - $ git branch + git branch 2.1 * better-project-manager master @@ -183,7 +183,7 @@ you can specify a custom base branch after the new branch's name: :: - $ git checkout -b my-new-feature master + git checkout -b my-new-feature master Updating your branch -------------------- @@ -200,7 +200,7 @@ current upstream ``master`` branch, you will have to update your branch by :: - $ git pull --rebase upstream master + git pull --rebase upstream master The ``--rebase`` argument will ensure that any local changes that you committed will be re-applied *on top* of the pulled branch, which is usually what we want @@ -296,32 +296,32 @@ Here's how the shell history could look like on our example: :: # It's nice to know where you're starting from - $ git log + git log # Do changes to the Project Manager with the nano text editor - $ nano editor/project_manager.cpp + nano editor/project_manager.cpp # Find an unrelated bug in Control and fix it - $ nano scene/gui/control.cpp + nano scene/gui/control.cpp # Review changes - $ git status - $ git diff + git status + git diff # We'll do two commits for our unrelated changes, # starting by the Control changes necessary for the PM enhancements - $ git add scene/gui/control.cpp - $ git commit -m "Fix handling of margins in Control" + git add scene/gui/control.cpp + git commit -m "Fix handling of margins in Control" # Check we did good - $ git log - $ git show - $ git status + git log + git show + git status # Make our second commit - $ git add editor/project_manager.cpp - $ git commit -m "Add a pretty banner to the Project Manager" - $ git log + git add editor/project_manager.cpp + git commit -m "Add a pretty banner to the Project Manager" + git log With this, we should have two new commits in our ``better-project-manager`` branch which were not in the ``master`` branch. They are still only local @@ -337,7 +337,7 @@ remote branch to share them with the world. The syntax for this is: :: - $ git push [:] + git push [:] The part about the remote branch can be omitted if you want it to have the same name as the local branch, which is our case in this example, so we will @@ -345,7 +345,7 @@ do: :: - $ git push origin better-project-manager + git push origin better-project-manager Git will ask you for your username and password. For your password, enter your GitHub Personal Access Token (PAT). If you do not have a GitHub Personal Access @@ -394,13 +394,13 @@ branch, push it to your fork, and the PR will be updated automatically: :: # Check out your branch again if you had changed in the meantime - $ git checkout better-project-manager + git checkout better-project-manager # Fix a mistake - $ nano editor/project_manager.cpp - $ git add editor/project_manager.cpp - $ git commit -m "Fix a typo in the banner's title" - $ git push origin better-project-manager + nano editor/project_manager.cpp + git add editor/project_manager.cpp + git commit -m "Fix a typo in the banner's title" + git push origin better-project-manager However, be aware that in our PR workflow, we favor commits that bring the codebase from one functional state to another functional state, without having @@ -413,17 +413,17 @@ fixes. The above example would then become: :: # Check out your branch again if you had changed in the meantime - $ git checkout better-project-manager + git checkout better-project-manager # Fix a mistake - $ nano editor/project_manager.cpp - $ git add editor/project_manager.cpp + nano editor/project_manager.cpp + git add editor/project_manager.cpp # --amend will change the previous commit, so you will have the opportunity # to edit its commit message if relevant. - $ git commit --amend + git commit --amend # As we modified the last commit, it no longer matches the one from your # remote branch, so we need to force push to overwrite that branch. - $ git push --force origin better-project-manager + git push --force origin better-project-manager .. Kept for compatibility with the previous title, linked in many PRs. @@ -460,7 +460,7 @@ upstream ``master`` branch, which you can do with: :: - $ git rebase -i upstream/master + git rebase -i upstream/master .. note:: Referencing branches in Git is a bit tricky due to the distinction between remote and local branches. Here, ``upstream/master`` (with a @@ -511,7 +511,7 @@ will raise an error: :: - $ git push origin better-project-manager + git push origin better-project-manager To https://github.com/akien-mga/godot ! [rejected] better-project-manager -> better-project-manager (non-fast-forward) error: failed to push some refs to 'https://akien-mga@github.com/akien-mga/godot' @@ -524,7 +524,7 @@ will have to *force* it: :: - $ git push --force origin better-project-manager + git push --force origin better-project-manager And tadaa! Git will happily *replace* your remote branch with what you had locally (so make sure that's what you wanted, using ``git log``). This will @@ -543,7 +543,7 @@ the following steps *should* fix this in one step: .. code-block:: text - $ git rebase -i --onto master 4.2 + git rebase -i --onto master 4.2 This will take all the commits on your branch *after* the ``4.2`` branch, and then splice them on top of ``master``, ignoring any commits from the ``4.2`` branch not on the ``master`` branch. You may still need to do some fixing, but @@ -553,7 +553,7 @@ Just like above for the interactive rebase you need to force push your branch to :: - $ git push --force origin better-project-manager + git push --force origin better-project-manager Deleting a Git branch --------------------- @@ -567,7 +567,7 @@ To delete our better Project Manager branch locally, use this command: :: - $ git branch -d better-project-manager + git branch -d better-project-manager Alternatively, if the branch hadn't been merged yet and we wanted to delete it anyway, instead of ``-d`` you would use ``-D``. @@ -576,7 +576,7 @@ Next, to delete the remote branch on GitHub use this command: :: - $ git push origin -d better-project-manager + git push origin -d better-project-manager You can also delete the remote branch from the GitHub PR itself, a button should appear once it has been merged or closed. diff --git a/contributing/workflow/testing_pull_requests.rst b/contributing/workflow/testing_pull_requests.rst index b016698b76f..7f96ff6bd41 100644 --- a/contributing/workflow/testing_pull_requests.rst +++ b/contributing/workflow/testing_pull_requests.rst @@ -119,19 +119,19 @@ Alternatively, you can checkout the pull request directly with git: :: - $ git fetch upstream pull/PR_NUMBER/head:BRANCH_NAME + git fetch upstream pull/PR_NUMBER/head:BRANCH_NAME So for the pull request above, the actual command will be: :: # Fetch PR branch locally - $ git fetch upstream pull/48734/head:editor_file_dialog_filter_sort + git fetch upstream pull/48734/head:editor_file_dialog_filter_sort - Once the pull request finishes downloading, checkout its branch: :: - $ git checkout editor_file_dialog_filter_sort + git checkout editor_file_dialog_filter_sort - And follow the :ref:`compiling ` instructions for your operating system. diff --git a/getting_started/first_2d_game/02.player_scene.rst b/getting_started/first_2d_game/02.player_scene.rst index acefaa5aa69..20799618811 100644 --- a/getting_started/first_2d_game/02.player_scene.rst +++ b/getting_started/first_2d_game/02.player_scene.rst @@ -30,7 +30,7 @@ functionality. Before we add any children to the ``Player`` node, we want to make sure we don't accidentally move or resize them by clicking on them. Select the node and click -the icon to the right of the lock. Its tooltip says "Groups the selected node +the icon to the right of the lock. Its tooltip says "Groups the selected node with its children. This causes the parent to be selected when any child node is clicked in 2D and 3D view." @@ -61,17 +61,19 @@ appearance and animations for our player. Notice that there is a warning symbol next to the node. An ``AnimatedSprite2D`` requires a :ref:`SpriteFrames ` resource, which is a list of the animations it can display. To create one, find the ``Sprite Frames`` property under the ``Animation`` tab in the Inspector and click -"[empty]" -> "New SpriteFrames". Click on the ``SpriteFrames`` you just -created to open the "SpriteFrames" panel: +"[empty]" -> "New SpriteFrames": -.. image:: img/spriteframes_panel.webp +.. image:: img/new_spriteframes.webp + +Click on the ``SpriteFrames`` you just created to open the "SpriteFrames" panel: +.. image:: img/spriteframes_panel.webp On the left is a list of animations. Click the "default" one and rename it to "walk". Then click the "Add Animation" button to create a second animation named "up". Find the player images in the "FileSystem" tab - they're in the ``art`` folder you unzipped earlier. Drag the two images for each animation, named -``playerGrey_up[1/2]`` and ``playerGrey_walk[1/2]``, into the "Animation Frames" +``playerGrey_walk[1/2]`` and ``playerGrey_walk[2/2]``, into the "Animation Frames" side of the panel for the corresponding animation: .. image:: img/spriteframes_panel2.webp diff --git a/getting_started/first_2d_game/06.heads_up_display.rst b/getting_started/first_2d_game/06.heads_up_display.rst index f02f3ae7258..78556702250 100644 --- a/getting_started/first_2d_game/06.heads_up_display.rst +++ b/getting_started/first_2d_game/06.heads_up_display.rst @@ -285,12 +285,20 @@ mobs to remove themselves. We can do this with the "group" feature. In the ``Mob`` scene, select the root node and click the "Node" tab next to the Inspector (the same place where you find the node's signals). Next to "Signals", -click "Groups" and you can type a new group name and click "Add". +click "Groups" to open the group overview +and the "+" button to open the "Create New Group" dialog. .. image:: img/group_tab.webp -Now all mobs will be in the "mobs" group. We can then add the following line to -the ``new_game()`` function in ``Main``: +Name the group ``mobs`` and click "ok" to add a new scene group. + +.. image:: img/add_group_dialog.webp + +Now all mobs will be in the "mobs" group. + +.. image:: img/scene_group_mobs.webp + +We can then add the following line to the ``new_game()`` function in ``Main``: .. tabs:: .. code-tab:: gdscript GDScript diff --git a/getting_started/first_2d_game/07.finishing-up.rst b/getting_started/first_2d_game/07.finishing-up.rst index 8ca8d5fd7a8..4fb29d4f776 100644 --- a/getting_started/first_2d_game/07.finishing-up.rst +++ b/getting_started/first_2d_game/07.finishing-up.rst @@ -37,6 +37,8 @@ All audio is automatically imported with the ``Loop`` setting disabled. If you want the music to loop seamlessly, click on the Stream file arrow, select ``Make Unique``, then click on the Stream file and check the ``Loop`` box. +.. image:: img/unique_resource_music.webp + To play the music, add ``$Music.play()`` in the ``new_game()`` function and ``$Music.stop()`` in the ``game_over()`` function. @@ -119,3 +121,14 @@ achieved. And when you're ready, you can move on to :ref:`doc_your_first_3d_game` to learn to create a complete 3D game from scratch, in Godot. + +Sharing the finished game with others +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want people to try out your game without having to install Godot, you'll +need to export the project for each operating system you want the game to be +playable on. See :ref:`doc_exporting_projects` for instructions. + +After exporting the project, compress the exported executable and PCK file (not +the raw project files) to a ZIP file, then upload this ZIP file to a file +sharing website. diff --git a/getting_started/first_2d_game/img/add_group_dialog.webp b/getting_started/first_2d_game/img/add_group_dialog.webp new file mode 100644 index 00000000000..f1775d217db Binary files /dev/null and b/getting_started/first_2d_game/img/add_group_dialog.webp differ diff --git a/getting_started/first_2d_game/img/attach_node_window.webp b/getting_started/first_2d_game/img/attach_node_window.webp index 211f9608202..43f5b4e6706 100644 Binary files a/getting_started/first_2d_game/img/attach_node_window.webp and b/getting_started/first_2d_game/img/attach_node_window.webp differ diff --git a/getting_started/first_2d_game/img/group_tab.webp b/getting_started/first_2d_game/img/group_tab.webp index 7efcbab0e4e..abc430c42e8 100644 Binary files a/getting_started/first_2d_game/img/group_tab.webp and b/getting_started/first_2d_game/img/group_tab.webp differ diff --git a/getting_started/first_2d_game/img/input-mapping-add-action.webp b/getting_started/first_2d_game/img/input-mapping-add-action.webp index 73a99dfb6f7..a19ba89e300 100644 Binary files a/getting_started/first_2d_game/img/input-mapping-add-action.webp and b/getting_started/first_2d_game/img/input-mapping-add-action.webp differ diff --git a/getting_started/first_2d_game/img/input-mapping-add-key.webp b/getting_started/first_2d_game/img/input-mapping-add-key.webp index d13441349d1..c4447148dba 100644 Binary files a/getting_started/first_2d_game/img/input-mapping-add-key.webp and b/getting_started/first_2d_game/img/input-mapping-add-key.webp differ diff --git a/getting_started/first_2d_game/img/input-mapping-completed.webp b/getting_started/first_2d_game/img/input-mapping-completed.webp index 60fc11041ba..4516de9cf33 100644 Binary files a/getting_started/first_2d_game/img/input-mapping-completed.webp and b/getting_started/first_2d_game/img/input-mapping-completed.webp differ diff --git a/getting_started/first_2d_game/img/input-mapping-event-configuration.webp b/getting_started/first_2d_game/img/input-mapping-event-configuration.webp index fe61bb00e7e..2cb85b8b85c 100644 Binary files a/getting_started/first_2d_game/img/input-mapping-event-configuration.webp and b/getting_started/first_2d_game/img/input-mapping-event-configuration.webp differ diff --git a/getting_started/first_2d_game/img/new_spriteframes.webp b/getting_started/first_2d_game/img/new_spriteframes.webp new file mode 100644 index 00000000000..2b0b052a492 Binary files /dev/null and b/getting_started/first_2d_game/img/new_spriteframes.webp differ diff --git a/getting_started/first_2d_game/img/scene_group_mobs.webp b/getting_started/first_2d_game/img/scene_group_mobs.webp new file mode 100644 index 00000000000..89033ffb1f9 Binary files /dev/null and b/getting_started/first_2d_game/img/scene_group_mobs.webp differ diff --git a/getting_started/first_2d_game/img/setting-project-width-and-height.webp b/getting_started/first_2d_game/img/setting-project-width-and-height.webp index 2ba8412d616..573a18f5148 100644 Binary files a/getting_started/first_2d_game/img/setting-project-width-and-height.webp and b/getting_started/first_2d_game/img/setting-project-width-and-height.webp differ diff --git a/getting_started/first_2d_game/img/setting-stretch-mode.webp b/getting_started/first_2d_game/img/setting-stretch-mode.webp index df316bce7f8..3be5a6ae740 100644 Binary files a/getting_started/first_2d_game/img/setting-stretch-mode.webp and b/getting_started/first_2d_game/img/setting-stretch-mode.webp differ diff --git a/getting_started/first_2d_game/img/unique_resource_music.webp b/getting_started/first_2d_game/img/unique_resource_music.webp new file mode 100644 index 00000000000..eb1cbd0f6b6 Binary files /dev/null and b/getting_started/first_2d_game/img/unique_resource_music.webp differ diff --git a/getting_started/first_3d_game/02.player_input.rst b/getting_started/first_3d_game/02.player_input.rst index 282b722cab3..a9d49650ec7 100644 --- a/getting_started/first_3d_game/02.player_input.rst +++ b/getting_started/first_3d_game/02.player_input.rst @@ -51,10 +51,10 @@ You can rename it to ``Character``. .. note:: - The ``.glb`` files contain 3D scene data based on the open source GLTF 2.0 + The ``.glb`` files contain 3D scene data based on the open source glTF 2.0 specification. They're a modern and powerful alternative to a proprietary format like FBX, which Godot also supports. To produce these files, we designed the - model in `Blender 3D `__ and exported it to GLTF. + model in `Blender 3D `__ and exported it to glTF. As with all kinds of physics nodes, we need a collision shape for our character to collide with the environment. Select the ``Player`` node again and add a child node diff --git a/getting_started/first_3d_game/07.killing_player.rst b/getting_started/first_3d_game/07.killing_player.rst index 74b22d246b1..92a0a65b88e 100644 --- a/getting_started/first_3d_game/07.killing_player.rst +++ b/getting_started/first_3d_game/07.killing_player.rst @@ -138,7 +138,7 @@ Also note that the enemy colliding with the player and dying depends on the size ``Player`` and the ``Mob``\ 's collision shapes. You may need to move them and resize them to achieve a tight game feel. -You can pat yourself in the back: you prototyped a complete 3D game, +You can pat yourself on the back: you prototyped a complete 3D game, even if it's still a bit rough. From there, we'll add a score, the option to retry the game, and you'll diff --git a/getting_started/first_3d_game/08.score_and_replay.rst b/getting_started/first_3d_game/08.score_and_replay.rst index 7c97ddfec3f..66152fc44d0 100644 --- a/getting_started/first_3d_game/08.score_and_replay.rst +++ b/getting_started/first_3d_game/08.score_and_replay.rst @@ -324,7 +324,7 @@ game. Save the scene as ``music_player.tscn``. We have to register it as an autoload. Head to the *Project -> Project -Settings…* menu and click on the *Autoload* tab. +Settings…* menu and click on the *Globals -> Autoload* tab. In the *Path* field, you want to enter the path to your scene. Click the folder icon to open the file browser and double-click on ``music_player.tscn``. Then, diff --git a/getting_started/first_3d_game/img/08.score_and_replay/18_register_autoload.webp b/getting_started/first_3d_game/img/08.score_and_replay/18_register_autoload.webp index 6d5fa1b784c..4687d36e884 100644 Binary files a/getting_started/first_3d_game/img/08.score_and_replay/18_register_autoload.webp and b/getting_started/first_3d_game/img/08.score_and_replay/18_register_autoload.webp differ diff --git a/getting_started/step_by_step/instancing.rst b/getting_started/step_by_step/instancing.rst index fce49061d1a..f766a32155e 100644 --- a/getting_started/step_by_step/instancing.rst +++ b/getting_started/step_by_step/instancing.rst @@ -121,7 +121,7 @@ Let's try this. Double-click ``ball.tscn`` in the FileSystem to open it. .. image:: img/instancing_ball_scene_open.webp -Select the Ball node. In the Inspector on the right, click on the PhysicsMaterial +Select the Ball node. In the Inspector on the right, click on the PhysicsMaterial property to expand it. .. image:: img/instancing_physics_material_expand.webp @@ -156,14 +156,17 @@ property to the value in the saved scene. Rerun the game and notice how this ball now falls much faster than the others. -.. note:: You may notice you are unable to change the values of the ``PhysicsMaterial`` - of the ball. This is because ``PhysicsMaterial`` is a resource, and needs - to be made unique before you can edit it in a scene that is linking to its - original scene. To make a resource unique for one instance, right-click on - it in the Inspector and click Make Unique in the contextual menu. +.. note:: - Resources are another essential building block of Godot games we will - cover in a later lesson. + You may notice you are unable to change the values of the PhysicsMaterial + of the ball. This is because PhysicsMaterial is a *resource*, and needs + to be made unique before you can edit it in a scene that is linking to its + original scene. To make a resource unique for one instance, right-click on + the **Physics Material** property in the Inspector and click **Make Unique** + in the context menu. + + Resources are another essential building block of Godot games we will cover + in a later lesson. Scene instances as a design language ------------------------------------ diff --git a/tutorials/2d/2d_movement.rst b/tutorials/2d/2d_movement.rst index 76c0f73ecd1..1f5da929bec 100644 --- a/tutorials/2d/2d_movement.rst +++ b/tutorials/2d/2d_movement.rst @@ -231,9 +231,9 @@ on the screen will cause the player to move to the target location. var target = position func _input(event): - if event is InputEventMouseButton: - if event.button_index == MOUSE_BUTTON_LEFT and event.pressed: - target = get_global_mouse_position() + # Use is_action_pressed to only accept single taps as input instead of mouse drags. + if event.is_action_pressed(&"click"): + target = get_global_mouse_position() func _physics_process(delta): velocity = position.direction_to(target) * speed @@ -254,12 +254,10 @@ on the screen will cause the player to move to the target location. public override void _Input(InputEvent @event) { - if (@event is InputEventMouseButton eventMouseButton) + // Use IsActionPressed to only accept single taps as input instead of mouse drags. + if (@event.IsActionPressed("click")) { - if (eventMouseButton.ButtonIndex == MouseButton.Left && eventMouseButton.Pressed) - { - _target = GetGlobalMousePosition(); - } + _target = GetGlobalMousePosition(); } } diff --git a/tutorials/2d/2d_parallax.rst b/tutorials/2d/2d_parallax.rst index 5702a89f1cb..ca8fea699d8 100644 --- a/tutorials/2d/2d_parallax.rst +++ b/tutorials/2d/2d_parallax.rst @@ -201,21 +201,23 @@ The parallax effect fakes a perspective by moving the positions of different tex understandably problematic if you have multiple cameras, because your textures can't be in two places at once! This is still achievable by cloning the parallax nodes into the second (or third or fourth) -:ref:`SubViewport`. Here's how it looks for a two player game: +:ref:`SubViewport`. Here's how a setup looks for a two player game: .. image:: img/2d_parallax_splitscreen.webp -Of course, now both backgrounds show in both SubViewports. What we want is for some nodes to be visible in one viewport -but not another. While technically possible, this is not a feature officially supported by Godot at the moment. There is -currently a proposal to make this much simpler, so please stay tuned. +Of course, now both backgrounds show in both SubViewports. What we want is for each parallax to only show in their +corresponding viewport. We can achieve this by doing the following: -As a workaround, you can do the following: +- Leave all parallax nodes at their default :ref:`visibility_layer` of 1. +- Set the first SubViewport's :ref:`canvas_cull_mask` to only layers 1 and 2. +- Do the same for the second SubViewport but use layers 1 and 3. +- Give your parallax nodes in the first SubViewport a common parent and set its :ref:`visibility_layer` to 2. +- Do the same for the second SubViewport's parallax nodes, but use a layer of 3. -- Set the first SubViewport's :ref:`canvas_cull_mask` to only layer 1, so it displays all nodes with a :ref:`visibility_layer` of layer 1. -- Set the second SubViewport's :ref:`canvas_cull_mask` to only layer 2, so it displays all nodes with a :ref:`visibility_layer` of layer 2. -- Set the :ref:`visibility_layer` of every node you want to display in both viewports to both layers 1 and 2. -- Set the :ref:`visibility_layer` of the :ref:`Parallax2D` node and all its descendants in the first :ref:`SubViewport` to layer 1. -- Set the :ref:`visibility_layer` of the :ref:`Parallax2D` node and all its descendants in the second :ref:`SubViewport` to layer 2. +How does this work? If a canvas item has a :ref:`visibility_layer` that +doesn't match the SubViewport's :ref:`canvas_cull_mask`, it will hide all +children, even if they do. We use this to our advantage, letting the SubViewports cut off rendering of parallax nodes +whose parent doesn't have a supported :ref:`visibility_layer`. Previewing in the editor ------------------------ diff --git a/tutorials/2d/img/2d_parallax_splitscreen.webp b/tutorials/2d/img/2d_parallax_splitscreen.webp index 7544bcf5303..3cecaf4d8e5 100644 Binary files a/tutorials/2d/img/2d_parallax_splitscreen.webp and b/tutorials/2d/img/2d_parallax_splitscreen.webp differ diff --git a/tutorials/2d/img/using_tilesets_edit_custom_data.webp b/tutorials/2d/img/using_tilesets_edit_custom_data.webp index aa7e7b5f042..eb47402c0ba 100644 Binary files a/tutorials/2d/img/using_tilesets_edit_custom_data.webp and b/tutorials/2d/img/using_tilesets_edit_custom_data.webp differ diff --git a/tutorials/2d/particle_systems_2d.rst b/tutorials/2d/particle_systems_2d.rst index 14fc22776cf..e2f815b250c 100644 --- a/tutorials/2d/particle_systems_2d.rst +++ b/tutorials/2d/particle_systems_2d.rst @@ -199,6 +199,12 @@ This setting can be used to set the particle system to render at a fixed FPS. For instance, changing the value to ``2`` will make the particles render at 2 frames per second. Note this does not slow down the particle system itself. +.. note:: + + Godot 4.3 does not currently support physics interpolation for 2D particles. + As a workaround, disable physics interpolation for the particles node by setting + **Node > Physics Interpolation > Mode** at the bottom of the inspector. + Fract Delta ~~~~~~~~~~~ diff --git a/tutorials/2d/using_tilemaps.rst b/tutorials/2d/using_tilemaps.rst index 41a0373eb52..a9a29b9347e 100644 --- a/tutorials/2d/using_tilemaps.rst +++ b/tutorials/2d/using_tilemaps.rst @@ -39,7 +39,7 @@ resource and choose **Save**: Saving the built-in TileSet resource to an external resource file -Multiple TileMaplayers and settings +Multiple TileMapLayers and settings ----------------------------------- When working with tilemaps it's generally advised that you use multiple TileMapLayer @@ -90,6 +90,9 @@ Navigation .. warning:: 2D navigation meshes can not be "layered" or stacked on top of each other like visuals or physic shapes. Attempting to stack navigation meshes on the same navigation map will result in merge and logical errors that break the pathfinding. +Reordering layers +^^^^^^^^^^^^^^^^^ + You can reorder layers by drag-and-dropping their node in the Scene tab. You can also switch between which TileMapLayer node you're working on by using the buttons in the top right corner of the TileMap editor. @@ -108,9 +111,9 @@ of the editor: .. figure:: img/using_tilemaps_open_tilemap_editor.webp :align: center - :alt: Opening the TileMap panel at the bottom of the editor. The TileMap node must be selected first. + :alt: Opening the TileMap panel at the bottom of the editor. The TileMapLayer node must be selected first. - Opening the TileMap panel at the bottom of the editor. The TileMap node must be selected first. + Opening the TileMap panel at the bottom of the editor. The TileMapLayer node must be selected first. Selecting tiles to use for painting ----------------------------------- @@ -127,7 +130,7 @@ layer you wish to paint on: .. tip:: In the 2D editor, the layers you aren't currently editing from the same - TileMap node will appear grayed out while in the TileMap editor. You can + TileMapLayer node will appear grayed out while in the TileMap editor. You can disable this behavior by clicking the icon next to the layer selection menu (**Highlight Selected TileMap Layer** tooltip). @@ -404,7 +407,7 @@ Rectangle or Bucket Fill painting modes. Handling tile connections automatically using terrains ------------------------------------------------------ -To use terrains, the TileMap node must feature at least one terrain set and a +To use terrains, the TileMapLayer node must feature at least one terrain set and a terrain within this terrain set. See :ref:`doc_using_tilesets_creating_terrain_sets` if you haven't created a terrain set for the TileSet yet. diff --git a/tutorials/2d/using_tilesets.rst b/tutorials/2d/using_tilesets.rst index 8dbc0e39272..b8afbc116b0 100644 --- a/tutorials/2d/using_tilesets.rst +++ b/tutorials/2d/using_tilesets.rst @@ -394,9 +394,7 @@ the custom data for the alternative tile only. You can reorder custom data without breaking existing metadata: the TileSet editor will update automatically after reordering custom data properties. -Note that in the editor, property names do not appear (only their index, which -matches the order in which they are defined). For example, with the custom data -layers example shown above, we're assigning a tile to have the +With the custom data layers example shown above, we're assigning a tile to have the ``damage_per_second`` metadata set to ``25`` and the ``destructible`` metadata to ``false``: @@ -526,7 +524,7 @@ Depending on your use cases, one method may be faster than the other: Using multiple tile selection ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you wish to configure various properties on several times at once, +If you wish to configure various properties on several tiles at once, choose the **Select** mode at the top of the TileSet editor: After doing this, you can select multiple tiles on the right column by holding diff --git a/tutorials/3d/global_illumination/reflection_probes.rst b/tutorials/3d/global_illumination/reflection_probes.rst index b7ef32dff0a..8f3eb1f8de7 100644 --- a/tutorials/3d/global_illumination/reflection_probes.rst +++ b/tutorials/3d/global_illumination/reflection_probes.rst @@ -194,3 +194,7 @@ advanced project setting. When using the Forward Mobile backend, only 8 reflection probes can be applied on each individual Mesh *resource*. If there are more reflection probes affecting a single mesh, not all of them will be rendered on the mesh. + +Similarly, when using the Compatibility backend, up to 2 reflection probes can be applied +per mesh. If more than 2 reflection probes affect a single mesh, additional probes will +not be rendered. diff --git a/tutorials/3d/img/next_pass.webp b/tutorials/3d/img/next_pass.webp new file mode 100644 index 00000000000..c8719361573 Binary files /dev/null and b/tutorials/3d/img/next_pass.webp differ diff --git a/tutorials/3d/mesh_lod.rst b/tutorials/3d/mesh_lod.rst index d073dbffd3e..f8aedec5578 100644 --- a/tutorials/3d/mesh_lod.rst +++ b/tutorials/3d/mesh_lod.rst @@ -138,10 +138,15 @@ by changing the **Rendering > Mesh LOD > LOD Change > Threshold Pixels** project setting. To change this value at run-time, set ``mesh_lod_threshold`` on the root viewport as follows: -:: +.. tabs:: + .. code-tab:: gdscript get_tree().root.mesh_lod_threshold = 4.0 + .. code-tab:: csharp + + GetTree().Root.MeshLodThreshold = 4.0f; + Each viewport has its own ``mesh_lod_threshold`` property, which can be set independently from other viewports. diff --git a/tutorials/3d/occlusion_culling.rst b/tutorials/3d/occlusion_culling.rst index f6b984b5bea..d5e97098fb5 100644 --- a/tutorials/3d/occlusion_culling.rst +++ b/tutorials/3d/occlusion_culling.rst @@ -195,10 +195,16 @@ occluders in front of the camera. To toggle occlusion culling at run-time, set ``use_occlusion_culling`` on the root viewport as follows: -:: +.. tabs:: + .. code-tab:: gdscript get_tree().root.use_occlusion_culling = true + .. code-tab:: csharp + + GetTree().Root.UseOcclusionCulling = true; + + Toggling occlusion culling at run-time is useful to compare performance on a running project. diff --git a/tutorials/3d/standard_material_3d.rst b/tutorials/3d/standard_material_3d.rst index b9eeb8acdbd..963e6184d44 100644 --- a/tutorials/3d/standard_material_3d.rst +++ b/tutorials/3d/standard_material_3d.rst @@ -738,8 +738,21 @@ The rendering order of objects can be changed, although this is mostly useful for transparent objects (or opaque objects that perform depth draw but no color draw, such as cracks on the floor). +Objects are sorted by an opaque/transparent queue, then :ref:`render_priority`, +with higher priority being drawn later. Transparent objects are also sorted by depth. + +Depth testing overrules priority. Priority alone cannot force opaque objects to be drawn over each other. + Next Pass --------- -Sets the material to be used for the next pass. This renders the object -again with a different material. +Setting :ref:`next_pass` on a material +will cause an object to be rendered again with that next material. + +Materials are sorted by an opaque/transparent queue, then :ref:`render_priority`, +with higher priority being drawn later. + +.. image:: img/next_pass.webp + +Depth will test equal between both materials unless the grow setting or other vertex transformations are used. +Multiple transparent passes should use :ref:`render_priority` to ensure correct ordering. diff --git a/tutorials/3d/using_decals.rst b/tutorials/3d/using_decals.rst index 9998865d5a5..2d39e40c57a 100644 --- a/tutorials/3d/using_decals.rst +++ b/tutorials/3d/using_decals.rst @@ -29,7 +29,7 @@ On this page, you'll learn: .. seealso:: The Godot demo projects repository contains a - `3D decals demo `__. + `3D decals demo `__. If you're looking to write arbitrary 3D text on top of a surface, use :ref:`doc_3d_text` placed close to a surface instead of a Decal node. diff --git a/tutorials/animation/creating_movies.rst b/tutorials/animation/creating_movies.rst index b27d211245e..f7f5178b978 100644 --- a/tutorials/animation/creating_movies.rst +++ b/tutorials/animation/creating_movies.rst @@ -285,7 +285,8 @@ This feature tag can also be queried in a script to increase quality settings that are set in the Environment resource. For example, to further improve SDFGI detail and reduce light leaking: -:: +.. tabs:: + .. code-tab:: gdscript extends Node3D @@ -296,6 +297,24 @@ detail and reduce light leaking: get_viewport().world_3d.environment.sdfgi_min_cell_size *= 0.25 get_viewport().world_3d.environment.sdfgi_cascades = 8 + .. code-tab:: csharp + + using Godot; + + public partial class MyNode3D : Node3D + { + public override void _Ready() + { + if (OS.HasFeature("movie")) + { + // When recording a movie, improve SDFGI cell density + // without decreasing its maximum distance. + GetViewport().World3D.Environment.SdfgiMinCellSize *= 0.25f; + GetViewport().World3D.Environment.SdfgiCascades = 8; + } + } + } + .. _doc_creating_movies_recording_at_higher_resolution: Rendering at a higher resolution than the screen resolution diff --git a/tutorials/animation/introduction.rst b/tutorials/animation/introduction.rst index 2c13fc60a92..dc8b0e7acdb 100644 --- a/tutorials/animation/introduction.rst +++ b/tutorials/animation/introduction.rst @@ -140,8 +140,8 @@ animation. Enter a name for the animation in the dialog box. Add a new animation -Manage an animation libraries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Managing animation libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For reusability, the animation is registered in a list in the animation library resource. If you add an animation to AnimationPlayer without specifying any particular settings, the animation will be registered in the [Global] animation library that AnimationPlayer has by default. @@ -373,10 +373,10 @@ If you want to reset the tracks in the editor, select the AnimationPlayer node, open the **Animation** bottom panel then choose **Apply Reset** in the animation editor's **Edit** dropdown menu. -when using the keyframe icon next to a property in the inspector the editor will +When using the keyframe icon next to a property in the inspector the editor will ask you to automatically create a RESET track. -.. note:: RESET tracks is also used as a reference value for blending. See also `For better blending <../animation/animation_tree.html#for-better-blending>`__. +.. note:: RESET tracks are also used as reference values for blending. See also `For better blending <../animation/animation_tree.html#for-better-blending>`__. Onion Skinning -------------- diff --git a/tutorials/animation/playing_videos.rst b/tutorials/animation/playing_videos.rst index 9862d8e4282..d2ec01b50dc 100644 --- a/tutorials/animation/playing_videos.rst +++ b/tutorials/animation/playing_videos.rst @@ -268,32 +268,32 @@ To implement the chroma key effect, follow these steps: 2. In the "ChromaKeyShader.gdshader" file, write the custom shader code as shown below: -.. code-block:: gd +.. code-block:: glsl shader_type canvas_item; - # Uniform variables for chroma key effect + // Uniform variables for chroma key effect uniform vec3 chroma_key_color : source_color = vec3(0.0, 1.0, 0.0); uniform float pickup_range : hint_range(0.0, 1.0) = 0.1; uniform float fade_amount : hint_range(0.0, 1.0) = 0.1; void fragment() { - # Get the color from the texture at the given UV coordinates + // Get the color from the texture at the given UV coordinates vec4 color = texture(TEXTURE, UV); - # Calculate the distance between the current color and the chroma key color + // Calculate the distance between the current color and the chroma key color float distance = length(color.rgb - chroma_key_color); - # If the distance is within the pickup range, discard the pixel - # the lesser the distance more likely the colors are + // If the distance is within the pickup range, discard the pixel + // the lesser the distance more likely the colors are if (distance <= pickup_range) { discard; } - # Calculate the fade factor based on the pickup range and fade amount + // Calculate the fade factor based on the pickup range and fade amount float fade_factor = smoothstep(pickup_range, pickup_range + fade_amount, distance); - # Set the output color with the original RGB values and the calculated fade factor + // Set the output color with the original RGB values and the calculated fade factor COLOR = vec4(color.rgb, fade_factor); } @@ -311,25 +311,64 @@ UI Controls To allow users to manipulate the chroma key effect in real-time, we created sliders in the `Control` node. The `Control` node's script contains the following functions: -.. code-block:: gd +.. tabs:: + .. code-tab:: gdscript - extends Control + extends Control - func _on_color_picker_button_color_changed(color): - # Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material - $VideoStreamPlayer.material.set("shader_parameter/chroma_key_color", color) + func _on_color_picker_button_color_changed(color): + # Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material. + $VideoStreamPlayer.material.set("shader_parameter/chroma_key_color", color) - func _on_h_slider_value_changed(value): - # Update the "pickup_range" shader parameter of the VideoStreamPlayer's material - $VideoStreamPlayer.material.set("shader_parameter/pickup_range", value) + func _on_h_slider_value_changed(value): + # Update the "pickup_range" shader parameter of the VideoStreamPlayer's material. + $VideoStreamPlayer.material.set("shader_parameter/pickup_range", value) - func _on_h_slider_2_value_changed(value): - # Update the "fade_amount" shader parameter of the VideoStreamPlayer's material - $VideoStreamPlayer.material.set("shader_parameter/fade_amount", value) + func _on_h_slider_2_value_changed(value): + # Update the "fade_amount" shader parameter of the VideoStreamPlayer's material. + $VideoStreamPlayer.material.set("shader_parameter/fade_amount", value) func _on_video_stream_player_finished(): - # Restart the video playback when it's finished - $VideoStreamPlayer.play() + # Restart the video playback when it's finished. + $VideoStreamPlayer.play() + + .. code-tab:: csharp + + using Godot; + + public partial class MyControl : Control + { + private VideoStreamPlayer _videoStreamPlayer; + + public override void _Ready() + { + _videoStreamPlayer = GetNode("VideoStreamPlayer"); + } + + private void OnColorPickerButtonColorChanged(Color color) + { + // Update the "chroma_key_color" shader parameter of the VideoStreamPlayer's material. + _videoStreamPlayer.Material.Set("shader_parameter/chroma_key_color", color); + } + + private void OnHSliderValueChanged(double value) + { + // Update the "pickup_range" shader parameter of the VideoStreamPlayer's material. + _videoStreamPlayer.Material.Set("shader_parameter/pickup_range", value); + } + + private void OnHSlider2ValueChanged(double value) + { + // Update the "fade_amount" shader parameter of the VideoStreamPlayer's material. + _videoStreamPlayer.Material.Set("shader_parameter/fade_amount", value); + } + + private void OnVideoStreamPlayerFinished() + { + // Restart the video playback when it's finished. + _videoStreamPlayer.Play(); + } + } also make sure that the range of the sliders are appropriate, our settings are : diff --git a/tutorials/assets_pipeline/import_process.rst b/tutorials/assets_pipeline/import_process.rst index 21c492cac7a..f3e23002853 100644 --- a/tutorials/assets_pipeline/import_process.rst +++ b/tutorials/assets_pipeline/import_process.rst @@ -84,7 +84,7 @@ files contain important metadata. :: - $ ls + ls example.png example.png.import project.godot @@ -94,7 +94,7 @@ Additionally, extra assets will be present in the hidden :: - $ ls .godot/imported + ls .godot/imported example.png-218a8f2b3041327d8a5756f3a245f83b.ctex example.png-218a8f2b3041327d8a5756f3a245f83b.md5 diff --git a/tutorials/assets_pipeline/importing_3d_scenes/import_configuration.rst b/tutorials/assets_pipeline/importing_3d_scenes/import_configuration.rst index f852a432b0c..8d7a2be0a45 100644 --- a/tutorials/assets_pipeline/importing_3d_scenes/import_configuration.rst +++ b/tutorials/assets_pipeline/importing_3d_scenes/import_configuration.rst @@ -160,7 +160,7 @@ exported from other tools such as Maya. **FBX** - **Importer** Which import method is used. ubfx handles fbx files as fbx files. - FBX2glTF converts FBX files to glTF on import and requires additonal setup. + FBX2glTF converts FBX files to glTF on import and requires additional setup. FBX2glTF is not recommended unless you have a specific rason to use it over ufbx or working with a different file format. - **Allow Geometry Helper Nodes** enables or disables geometry helper nodes diff --git a/tutorials/assets_pipeline/importing_audio_samples.rst b/tutorials/assets_pipeline/importing_audio_samples.rst index 5874283849b..aeb54641e80 100644 --- a/tutorials/assets_pipeline/importing_audio_samples.rst +++ b/tutorials/assets_pipeline/importing_audio_samples.rst @@ -212,7 +212,7 @@ BPM The Beats Per Minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to -make use of interactive music functionality (not implemented yet), not sound +make use of interactive music functionality, not sound effects. A more convenient editor for **BPM** is provided in the @@ -223,7 +223,7 @@ Beat Count ^^^^^^^^^^ The beat count of the audio track. This is only relevant for music that wishes -to make use of interactive music functionality (not implemented yet), not sound +to make use of interactive music functionality, not sound effects. A more convenient editor for **Beat Count** is provided in the @@ -235,7 +235,7 @@ Bar Beats The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality -(not implemented yet), not sound effects. +, not sound effects. A more convenient editor for **Bar Beats** is provided in the :ref:`Advanced import settings ` diff --git a/tutorials/best_practices/autoloads_versus_internal_nodes.rst b/tutorials/best_practices/autoloads_versus_internal_nodes.rst index 48664a26a59..2f8b10a92a9 100644 --- a/tutorials/best_practices/autoloads_versus_internal_nodes.rst +++ b/tutorials/best_practices/autoloads_versus_internal_nodes.rst @@ -87,7 +87,7 @@ limitation of static functions is that they can't reference member variables, non-static functions or ``self``. Since Godot 4.1, GDScript also supports ``static`` variables using ``static var``. -This means you can now share a variables across instances of a class without +This means you can now share variables across instances of a class without having to create a separate autoload. Still, autoloaded nodes can simplify your code for systems with a wide scope. If diff --git a/tutorials/best_practices/data_preferences.rst b/tutorials/best_practices/data_preferences.rst index 7bd718267c0..994d3d45e98 100644 --- a/tutorials/best_practices/data_preferences.rst +++ b/tutorials/best_practices/data_preferences.rst @@ -332,15 +332,15 @@ in a :ref:`TileSet ` and integrate it with a :ref:`TileMapLayer ` for many auto-animating backgrounds that all render in a single batched draw call. -The AnimatedSprite2D node, in combination with the +The :ref:`AnimatedSprite2D ` node, in combination with the :ref:`SpriteFrames ` resource, allows one to create a variety of animation sequences through spritesheets, flip between animations, and control their speed, regional offset, and orientation. This makes them well-suited to controlling 2D frame-based animations. -If one needs trigger other effects in relation to animation changes (for +If one needs to trigger other effects in relation to animation changes (for example, create particle effects, call functions, or manipulate other -peripheral elements besides the frame-based animation), then will need to use +peripheral elements besides the frame-based animation), then one will need to use an :ref:`AnimationPlayer ` node in conjunction with the AnimatedSprite2D. diff --git a/tutorials/best_practices/godot_notifications.rst b/tutorials/best_practices/godot_notifications.rst index e388ecaec62..75a0d237816 100644 --- a/tutorials/best_practices/godot_notifications.rst +++ b/tutorials/best_practices/godot_notifications.rst @@ -279,7 +279,7 @@ nodes that one might create at runtime. { private Node _parentCache; - public void ConnectionCheck() + public bool ConnectionCheck() { return _parentCache.HasUserSignal("InteractedWith"); } diff --git a/tutorials/export/index.rst b/tutorials/export/index.rst index 6bf26611bdc..6a46dabd7dc 100644 --- a/tutorials/export/index.rst +++ b/tutorials/export/index.rst @@ -3,6 +3,12 @@ Export ====== +.. seealso:: + + This section is about exporting a build of your project. If you're trying + to export properties from a script, see :ref:`doc_gdscript_exports` or + :ref:`doc_c_sharp_exports`. + .. toctree:: :maxdepth: 1 :name: toc-learn-workflow-export diff --git a/tutorials/inputs/mouse_and_input_coordinates.rst b/tutorials/inputs/mouse_and_input_coordinates.rst index ac0dadce762..fd3be77ca5b 100644 --- a/tutorials/inputs/mouse_and_input_coordinates.rst +++ b/tutorials/inputs/mouse_and_input_coordinates.rst @@ -29,14 +29,14 @@ for example: .. code-tab:: gdscript GDScript func _input(event): - # Mouse in viewport coordinates. - if event is InputEventMouseButton: - print("Mouse Click/Unclick at: ", event.position) - elif event is InputEventMouseMotion: - print("Mouse Motion at: ", event.position) - - # Print the size of the viewport. - print("Viewport Resolution is: ", get_viewport().get_visible_rect().size) + # Mouse in viewport coordinates. + if event is InputEventMouseButton: + print("Mouse Click/Unclick at: ", event.position) + elif event is InputEventMouseMotion: + print("Mouse Motion at: ", event.position) + + # Print the size of the viewport. + print("Viewport Resolution is: ", get_viewport().get_visible_rect().size) .. code-tab:: csharp diff --git a/tutorials/io/background_loading.rst b/tutorials/io/background_loading.rst index 9384be4c890..8f484333e6f 100644 --- a/tutorials/io/background_loading.rst +++ b/tutorials/io/background_loading.rst @@ -48,7 +48,8 @@ The path will be ``"Enemy.tscn"`` which is located at ``res://Enemy.tscn``. First, we will start a request to load the resource and connect the button: -:: +.. tabs:: + .. code-tab:: gdscript const ENEMY_SCENE_PATH : String = "Enemy.tscn" @@ -56,14 +57,41 @@ First, we will start a request to load the resource and connect the button: ResourceLoader.load_threaded_request(ENEMY_SCENE_PATH) self.pressed.connect(_on_button_pressed) + .. code-tab:: csharp + + using Godot; + + public partial class MyButton : Button + { + private const string EnemyScenePath = "Enemy.tscn"; + + public override void _Ready() + { + ResourceLoader.LoadThreadedRequest(EnemyScenePath); + Pressed += OnButtonPressed; + } + } + Now ``_on_button_pressed`` will be called when the button is pressed. This method will be used to spawn an enemy. -:: +.. tabs:: + .. code-tab:: gdscript - func _on_button_pressed(): # Button was pressed - # Obtain the resource now that we need it + func _on_button_pressed(): # Button was pressed. + # Obtain the resource now that we need it. var enemy_scene = ResourceLoader.load_threaded_get(ENEMY_SCENE_PATH) - # Instantiate the enemy scene and add it to the current scene + # Instantiate the enemy scene and add it to the current scene. var enemy = enemy_scene.instantiate() add_child(enemy) + + .. code-tab:: csharp + + private void OnButtonPressed() // Button was pressed. + { + // Obtain the resource now that we need it. + var enemyScene = (PackedScene)ResourceLoader.LoadThreadedGet(EnemyScenePath); + // Instantiate the enemy scene and add it to the current scene. + var enemy = enemyScene.Instantiate(); + AddChild(enemy); + } diff --git a/tutorials/io/data_paths.rst b/tutorials/io/data_paths.rst index 119352fb9d9..6f9db534325 100644 --- a/tutorials/io/data_paths.rst +++ b/tutorials/io/data_paths.rst @@ -25,6 +25,23 @@ This makes it possible to work with paths returned by other Windows applications. We still recommend using only forward slashes in your own code to guarantee that everything will work as intended. +.. tip:: + + The String class offers over a dozen methods to work with strings that represent file paths: + + - :ref:`String.filecasecmp_to() ` + - :ref:`String.filenocasecmp_to() ` + - :ref:`String.get_base_dir() ` + - :ref:`String.get_basename() ` + - :ref:`String.get_extension() ` + - :ref:`String.get_file() ` + - :ref:`String.is_absolute_path() ` + - :ref:`String.is_relative_path() ` + - :ref:`String.is_valid_filename() ` + - :ref:`String.path_join() ` + - :ref:`String.simplify_path() ` + - :ref:`String.validate_filename() ` + Accessing files in the project folder (``res://``) -------------------------------------------------- @@ -142,8 +159,9 @@ depending on the platform. By default, these paths are: Godot complies with the `XDG Base Directory Specification `__ -on all platforms. You can override environment variables following the -specification to change the editor and project data paths. +on Linux/\*BSD. You can override the ``XDG_DATA_HOME``, ``XDG_CONFIG_HOME`` and +``XDG_CACHE_HOME`` environment variables to change the editor and project data +paths. .. note:: If you use `Godot packaged as a Flatpak `__, the diff --git a/tutorials/io/saving_games.rst b/tutorials/io/saving_games.rst index afa7ad1c987..27347278dcd 100644 --- a/tutorials/io/saving_games.rst +++ b/tutorials/io/saving_games.rst @@ -232,17 +232,17 @@ load function: while save_file.get_position() < save_file.get_length(): var json_string = save_file.get_line() - # Creates the helper class to interact with JSON + # Creates the helper class to interact with JSON. var json = JSON.new() - # Check if there is any error while parsing the JSON string, skip in case of failure + # Check if there is any error while parsing the JSON string, skip in case of failure. var parse_result = json.parse(json_string) if not parse_result == OK: print("JSON Parse Error: ", json.get_error_message(), " in ", json_string, " at line ", json.get_error_line()) continue - # Get the data from the JSON object - var node_data = json.get_data() + # Get the data from the JSON object. + var node_data = json.data # Firstly, we need to create the object and add it to the tree and set its position. var new_object = load(node_data["filename"]).instantiate() @@ -284,7 +284,7 @@ load function: { var jsonString = saveFile.GetLine(); - // Creates the helper class to interact with JSON + // Creates the helper class to interact with JSON. var json = new Json(); var parseResult = json.Parse(jsonString); if (parseResult != Error.Ok) @@ -293,7 +293,7 @@ load function: continue; } - // Get the data from the JSON object + // Get the data from the JSON object. var nodeData = new Godot.Collections.Dictionary((Godot.Collections.Dictionary)json.Data); // Firstly, we need to create the object and add it to the tree and set its position. diff --git a/tutorials/math/interpolation.rst b/tutorials/math/interpolation.rst index febdb8fe86a..bddc26481ce 100644 --- a/tutorials/math/interpolation.rst +++ b/tutorials/math/interpolation.rst @@ -138,4 +138,4 @@ Here is how it looks: .. image:: img/interpolation_follow.gif -This useful for smoothing camera movement, allies following you (ensuring they stay within a certain range), and many other common game patterns. +This is useful for smoothing camera movement, allies following you (ensuring they stay within a certain range), and many other common game patterns. diff --git a/tutorials/math/vectors_advanced.rst b/tutorials/math/vectors_advanced.rst index f524fa9fbb0..1d0b80ed302 100644 --- a/tutorials/math/vectors_advanced.rst +++ b/tutorials/math/vectors_advanced.rst @@ -171,7 +171,7 @@ the normal and the point. For two points in space, there are actually two planes that pass through them, sharing the same space but with normal pointing to the opposite directions. To compute the normal from the two points, the direction -vector must be obtained first, and then it needs to be rotated 90° +vector must be obtained first, and then it needs to be rotated 90 degrees to either side: .. tabs:: diff --git a/tutorials/navigation/navigation_introduction_2d.rst b/tutorials/navigation/navigation_introduction_2d.rst index 3831a88feee..cd7eabf42f0 100644 --- a/tutorials/navigation/navigation_introduction_2d.rst +++ b/tutorials/navigation/navigation_introduction_2d.rst @@ -131,7 +131,7 @@ It uses the NavigationServer2D and a NavigationAgent2D for path movement. navigation_agent.target_desired_distance = 4.0 # Make sure to not await during _ready. - call_deferred("actor_setup") + actor_setup.call_deferred() func actor_setup(): # Wait for the first physics frame so the NavigationServer can sync. diff --git a/tutorials/navigation/navigation_introduction_3d.rst b/tutorials/navigation/navigation_introduction_3d.rst index a09e19e522d..032a22769a3 100644 --- a/tutorials/navigation/navigation_introduction_3d.rst +++ b/tutorials/navigation/navigation_introduction_3d.rst @@ -132,7 +132,7 @@ It uses the NavigationServer3D and a NavigationAgent3D for path movement. navigation_agent.target_desired_distance = 0.5 # Make sure to not await during _ready. - call_deferred("actor_setup") + actor_setup.call_deferred() func actor_setup(): # Wait for the first physics frame so the NavigationServer can sync. diff --git a/tutorials/navigation/navigation_using_navigationmaps.rst b/tutorials/navigation/navigation_using_navigationmaps.rst index 66c90162558..078250d4d7e 100644 --- a/tutorials/navigation/navigation_using_navigationmaps.rst +++ b/tutorials/navigation/navigation_using_navigationmaps.rst @@ -33,6 +33,16 @@ The 3D default navigation map RID can be obtained with ``get_world_3d().get_navi func _ready() -> void: var default_navigation_map_rid: RID = get_world_2d().get_navigation_map() + .. code-tab:: csharp 2D C# + + public partial class MyNode2D : Node2D + { + public override void _Ready() + { + Rid defaultNavigationMapRid = GetWorld2D().NavigationMap; + } + } + .. code-tab:: gdscript 3D GDScript extends Node3D @@ -40,6 +50,16 @@ The 3D default navigation map RID can be obtained with ``get_world_3d().get_navi func _ready() -> void: var default_navigation_map_rid: RID = get_world_3d().get_navigation_map() + .. code-tab:: csharp 3D C# + + public partial class MyNode3D : Node3D + { + public override void _Ready() + { + Rid defaultNavigationMapRid = GetWorld3D().NavigationMap; + } + } + Creating new navigation maps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -66,6 +86,17 @@ Navigation regions and avoidance agents can only be part of a single navigation var new_navigation_map: RID = NavigationServer2D.map_create() NavigationServer2D.map_set_active(new_navigation_map, true) + .. code-tab:: csharp 2D C# + + public partial class MyNode2D : Node2D + { + public override void _Ready() + { + Rid newNavigationMap = NavigationServer2D.MapCreate(); + NavigationServer2D.MapSetActive(newNavigationMap, true); + } + } + .. code-tab:: gdscript 3D GDScript extends Node3D @@ -74,6 +105,17 @@ Navigation regions and avoidance agents can only be part of a single navigation var new_navigation_map: RID = NavigationServer3D.map_create() NavigationServer3D.map_set_active(new_navigation_map, true) + .. code-tab:: csharp 3D C# + + public partial class MyNode3D : Node3D + { + public override void _Ready() + { + Rid newNavigationMap = NavigationServer3D.MapCreate(); + NavigationServer3D.MapSetActive(newNavigationMap, true); + } + } + .. note:: There is no difference between navigation maps created with the NavigationServer2D API or the NavigationServer3D API. diff --git a/tutorials/navigation/navigation_using_navigationmeshes.rst b/tutorials/navigation/navigation_using_navigationmeshes.rst index ec435f4d82c..38926c46ff3 100644 --- a/tutorials/navigation/navigation_using_navigationmeshes.rst +++ b/tutorials/navigation/navigation_using_navigationmeshes.rst @@ -49,6 +49,10 @@ node, the individual parsing, baking, and region update steps are all combined i The nodes are available in 2D and 3D as :ref:`NavigationRegion2D` and :ref:`NavigationRegion3D` respectively. +.. tip:: + + The navigation mesh ``source_geometry_mode`` can be switched to parse specific node group names so nodes that should be baked can be placed anywhere in the scene. + .. tabs:: .. tab:: Baking with a NavigationRegion2D diff --git a/tutorials/navigation/navigation_using_navigationobstacles.rst b/tutorials/navigation/navigation_using_navigationobstacles.rst index a8e7e7f22a4..f9a437863ce 100644 --- a/tutorials/navigation/navigation_using_navigationobstacles.rst +++ b/tutorials/navigation/navigation_using_navigationobstacles.rst @@ -25,7 +25,7 @@ Obstacles and navigation mesh Navigation obstacles affecting navigation mesh baking. -For navigation mesh baking obstacles can be used to discard parts of all other source geometry inside the obstacle shape. +For navigation mesh baking, obstacles can be used to discard parts of all other source geometry inside the obstacle shape. This can be used to stop navigation meshes being baked in unwanted places, e.g. inside "solid" geometry like thick walls or on top of other geometry that should not be included for gameplay like roofs. diff --git a/tutorials/navigation/navigation_using_navigationregions.rst b/tutorials/navigation/navigation_using_navigationregions.rst index 97a7d3afbdd..a2ff94cd98b 100644 --- a/tutorials/navigation/navigation_using_navigationregions.rst +++ b/tutorials/navigation/navigation_using_navigationregions.rst @@ -45,12 +45,32 @@ The region RID can then be obtained from NavigationRegion Nodes with ``get_rid() var navigationserver_region_rid: RID = get_rid() + .. code-tab:: csharp 2D C# + + public partial class MyNavigationRegion2D : NavigationRegion2D + { + public override void _Ready() + { + Rid navigationServerRegionRid = GetRid(); + } + } + .. code-tab:: gdscript 3D GDScript extends NavigationRegion3D var navigationserver_region_rid: RID = get_rid() + .. code-tab:: csharp 3D C# + + public partial class MyNavigationRegion3D : NavigationRegion3D + { + public override void _Ready() + { + Rid navigationServerRegionRid = GetRid(); + } + } + New regions can also be created with the NavigationServer API and added to any existing map. If regions are created with the NavigationServer API directly they need to be assigned a navigation map manually. @@ -65,6 +85,18 @@ If regions are created with the NavigationServer API directly they need to be as var default_map_rid: RID = get_world_2d().get_navigation_map() NavigationServer2D.region_set_map(new_region_rid, default_map_rid) + .. code-tab:: csharp 2D C# + + public partial class MyNode2D : Node2D + { + public override void _Ready() + { + Rid newRegionRid = NavigationServer2D.RegionCreate(); + Rid defaultMapRid = GetWorld2D().NavigationMap; + NavigationServer2D.RegionSetMap(newRegionRid, defaultMapRid); + } + } + .. code-tab:: gdscript 3D GDScript extends Node3D @@ -74,6 +106,18 @@ If regions are created with the NavigationServer API directly they need to be as var default_map_rid: RID = get_world_3d().get_navigation_map() NavigationServer3D.region_set_map(new_region_rid, default_map_rid) + .. code-tab:: csharp 3D C# + + public partial class MyNode3D : Node3D + { + public override void _Ready() + { + Rid newRegionRid = NavigationServer3D.RegionCreate(); + Rid defaultMapRid = GetWorld3D().NavigationMap; + NavigationServer3D.RegionSetMap(newRegionRid, defaultMapRid); + } + } + .. note:: Navigation regions can only be assigned to a single navigation map. diff --git a/tutorials/navigation/navigation_using_navigationservers.rst b/tutorials/navigation/navigation_using_navigationservers.rst index d8da6791a0e..2599ab8eb22 100644 --- a/tutorials/navigation/navigation_using_navigationservers.rst +++ b/tutorials/navigation/navigation_using_navigationservers.rst @@ -97,7 +97,7 @@ Afterwards the function waits for the next physics frame before continuing with func _ready(): # Use call deferred to make sure the entire scene tree nodes are setup # else await on 'physics_frame' in a _ready() might get stuck. - call_deferred("custom_setup") + custom_setup.call_deferred() func custom_setup(): diff --git a/tutorials/networking/high_level_multiplayer.rst b/tutorials/networking/high_level_multiplayer.rst index 45e7e8557d7..00dcd395c9a 100644 --- a/tutorials/networking/high_level_multiplayer.rst +++ b/tutorials/networking/high_level_multiplayer.rst @@ -107,16 +107,24 @@ which will override ``multiplayer`` for the node at that path and all of its des This allows sibling nodes to be configured with different peers, which makes it possible to run a server and a client simultaneously in one instance of Godot. -:: +.. tabs:: + .. code-tab:: gdscript GDScript # By default, these expressions are interchangeable. multiplayer # Get the MultiplayerAPI object configured for this node. get_tree().get_multiplayer() # Get the default MultiplayerAPI object. + .. code-tab:: csharp + + // By default, these expressions are interchangeable. + Multiplayer; // Get the MultiplayerAPI object configured for this node. + GetTree().GetMultiplayer(); // Get the default MultiplayerAPI object. + To initialize networking, a ``MultiplayerPeer`` object must be created, initialized as a server or client, and passed to the ``MultiplayerAPI``. -:: +.. tabs:: + .. code-tab:: gdscript GDScript # Create client. var peer = ENetMultiplayerPeer.new() @@ -128,12 +136,29 @@ and passed to the ``MultiplayerAPI``. peer.create_server(PORT, MAX_CLIENTS) multiplayer.multiplayer_peer = peer + .. code-tab:: csharp + + // Create client. + var peer = new ENetMultiplayerPeer(); + peer.CreateClient(IPAddress, Port); + Multiplayer.MultiplayerPeer = peer; + + // Create server. + var peer = new ENetMultiplayerPeer(); + peer.CreateServer(Port, MaxClients); + Multiplayer.MultiplayerPeer = peer; + To terminate networking: -:: +.. tabs:: + .. code-tab:: gdscript GDScript multiplayer.multiplayer_peer = null + .. code-tab:: csharp + + Multiplayer.MultiplayerPeer = null; + .. warning:: When exporting to Android, make sure to enable the ``INTERNET`` @@ -159,16 +184,27 @@ The rest are only emitted on clients: To get the unique ID of the associated peer: -:: +.. tabs:: + .. code-tab:: gdscript GDScript multiplayer.get_unique_id() + .. code-tab:: csharp + + Multiplayer.GetUniqueId(); + + To check whether the peer is server or client: -:: +.. tabs:: + .. code-tab:: gdscript GDScript multiplayer.is_server() + .. code-tab:: csharp + + Multiplayer.IsServer(); + Remote procedure calls ---------------------- @@ -176,7 +212,8 @@ Remote procedure calls, or RPCs, are functions that can be called on other peers before a function definition. To call an RPC, use ``Callable``'s method ``rpc()`` to call in every peer, or ``rpc_id()`` to call in a specific peer. -:: +.. tabs:: + .. code-tab:: gdscript GDScript func _ready(): if multiplayer.is_server(): @@ -186,6 +223,23 @@ call in a specific peer. func print_once_per_client(): print("I will be printed to the console once per each connected client.") + .. code-tab:: csharp + + public override void _Ready() + { + if (Multiplayer.IsServer()) + { + Rpc(MethodName.PrintOncePerClient); + } + } + + [Rpc] + private void PrintOncePerClient() + { + GD.Print("I will be printed to the console once per each connected client."); + } + + RPCs will not serialize objects or callables. For a remote call to be successful, the sending and receiving node need to have the same ``NodePath``, which means they @@ -204,7 +258,7 @@ must have the same name. When using ``add_child()`` for nodes which are expected **and** the NodePath. If an RPC resides in a script attached to ``/root/Main/Node1``, then it must reside in precisely the same path and node on both the client script and the server script. Function arguments are not checked for matching between the server and client code - (example: ``func sendstuff():`` and ``func sendstuff(arg1, arg2):`` **will pass** signature + (example: ``func sendstuff():`` and ``func sendstuff(arg1, arg2):`` **will pass** signature matching). If these conditions are not met (if all RPCs do not pass signature matching), the script may print an @@ -215,15 +269,22 @@ must have the same name. When using ``add_child()`` for nodes which are expected The annotation can take a number of arguments, which have default values. ``@rpc`` is equivalent to: -:: +.. tabs:: + .. code-tab:: gdscript GDScript @rpc("authority", "call_remote", "unreliable", 0) + .. code-tab:: csharp + + [Rpc(MultiplayerApi.RpcMode.Authority, CallLocal = false, TransferMode = MultiplayerPeer.TransferModeEnum.Unreliable, TransferChannel = 0)] + The parameters and their functions are as follows: ``mode``: -- ``"authority"``: Only the multiplayer authority (the server) can call remotely. +- ``"authority"``: Only the multiplayer authority can call remotely. + The authority is the server by default, but can be changed per-node using + :ref:`Node.set_multiplayer_authority `. - ``"any_peer"``: Clients are allowed to call remotely. Useful for transferring user input. ``sync``: @@ -243,7 +304,8 @@ The first 3 can be passed in any order, but ``transfer_channel`` must always be The function ``multiplayer.get_remote_sender_id()`` can be used to get the unique id of an rpc sender, when used within the function called by rpc. -:: +.. tabs:: + .. code-tab:: gdscript GDScript func _on_some_input(): # Connected to some input. transfer_some_input.rpc_id(1) # Send the input only to the server. @@ -256,6 +318,22 @@ The function ``multiplayer.get_remote_sender_id()`` can be used to get the uniqu var sender_id = multiplayer.get_remote_sender_id() # Process the input and affect game logic. + .. code-tab:: csharp + + private void OnSomeInput() // Connected to some input. + { + RpcId(1, MethodName.TransferSomeInput); // Send the input only to the server. + } + + // Call local is required if the server is also a player. + [Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true, TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] + private void TransferSomeInput() + { + // The server knows who sent the input. + int senderId = Multiplayer.GetRemoteSenderId(); + // Process the input and affect game logic. + } + Channels -------- Modern networking protocols support channels, which are separate connections within the connection. This allows for multiple @@ -276,7 +354,8 @@ Example lobby implementation This is an example lobby that can handle peers joining and leaving, notify UI scenes through signals, and start the game after all clients have loaded the game scene. -:: +.. tabs:: + .. code-tab:: gdscript GDScript extends Node @@ -388,9 +467,159 @@ have loaded the game scene. players.clear() server_disconnected.emit() + .. code-tab:: csharp + + using Godot; + + public partial class Lobby : Node + { + public static Lobby Instance { get; private set; } + + // These signals can be connected to by a UI lobby scene or the game scene. + [Signal] + public delegate void PlayerConnectedEventHandler(int peerId, Godot.Collections.Dictionary playerInfo); + [Signal] + public delegate void PlayerDisconnectedEventHandler(int peerId); + [Signal] + public delegate void ServerDisconnectedEventHandler(); + + private const int Port = 7000; + private const string DefaultServerIP = "127.0.0.1"; // IPv4 localhost + private const int MaxConnections = 20; + + // This will contain player info for every player, + // with the keys being each player's unique IDs. + private Godot.Collections.Dictionary> _players = new Godot.Collections.Dictionary>(); + + // This is the local player info. This should be modified locally + // before the connection is made. It will be passed to every other peer. + // For example, the value of "name" can be set to something the player + // entered in a UI scene. + private Godot.Collections.Dictionary _playerInfo = new Godot.Collections.Dictionary() + { + { "Name", "PlayerName" }, + }; + + private int _playersLoaded = 0; + + public override void _Ready() + { + Instance = this; + Multiplayer.PeerConnected += OnPlayerConnected; + Multiplayer.PeerDisconnected += OnPlayerDisconnected; + Multiplayer.ConnectedToServer += OnConnectOk; + Multiplayer.ConnectionFailed += OnConnectionFail; + Multiplayer.ServerDisconnected += OnServerDisconnected; + } + + private Error JoinGame(string address = "") + { + if (string.IsNullOrEmpty(address)) + { + address = DefaultServerIP; + } + + var peer = new ENetMultiplayerPeer(); + Error error = peer.CreateClient(address, Port); + + if (error != Error.Ok) + { + return error; + } + + Multiplayer.MultiplayerPeer = peer; + return Error.Ok; + } + + private Error CreateGame() + { + var peer = new ENetMultiplayerPeer(); + Error error = peer.CreateServer(Port, MaxConnections); + + if (error != Error.Ok) + { + return error; + } + + Multiplayer.MultiplayerPeer = peer; + _players[1] = _playerInfo; + EmitSignal(SignalName.PlayerConnected, 1, _playerInfo); + return Error.Ok; + } + + private void RemoveMultiplayerPeer() + { + Multiplayer.MultiplayerPeer = null; + } + + // When the server decides to start the game from a UI scene, + // do Rpc(Lobby.MethodName.LoadGame, filePath); + [Rpc(CallLocal = true,TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] + private void LoadGame(string gameScenePath) + { + GetTree().ChangeSceneToFile(gameScenePath); + } + + // Every peer will call this when they have loaded the game scene. + [Rpc(MultiplayerApi.RpcMode.AnyPeer,CallLocal = true,TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] + private void PlayerLoaded() + { + if (Multiplayer.IsServer()) + { + _playersLoaded += 1; + if (_playersLoaded == _players.Count) + { + GetNode("/root/Game").StartGame(); + _playersLoaded = 0; + } + } + } + + // When a peer connects, send them my player info. + // This allows transfer of all desired data for each player, not only the unique ID. + private void OnPlayerConnected(long id) + { + RpcId(id, MethodName.RegisterPlayer, _playerInfo); + } + + [Rpc(MultiplayerApi.RpcMode.AnyPeer,TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] + private void RegisterPlayer(Godot.Collections.Dictionary newPlayerInfo) + { + int newPlayerId = Multiplayer.GetRemoteSenderId(); + _players[newPlayerId] = newPlayerInfo; + EmitSignal(SignalName.PlayerConnected, newPlayerId, newPlayerInfo); + } + + private void OnPlayerDisconnected(long id) + { + _players.Remove(id); + EmitSignal(SignalName.PlayerDisconnected, id); + } + + private void OnConnectOk() + { + int peerId = Multiplayer.GetUniqueId(); + _players[peerId] = _playerInfo; + EmitSignal(SignalName.PlayerConnected, peerId, _playerInfo); + } + + private void OnConnectionFail() + { + Multiplayer.MultiplayerPeer = null; + } + + private void OnServerDisconnected() + { + Multiplayer.MultiplayerPeer = null; + _players.Clear(); + EmitSignal(SignalName.ServerDisconnected); + } + } + The game scene's root node should be named Game. In the script attached to it: -:: +.. tabs:: + .. code-tab:: gdscript GDScript extends Node3D # Or Node2D. @@ -406,6 +635,26 @@ The game scene's root node should be named Game. In the script attached to it: func start_game(): # All peers are ready to receive RPCs in this scene. + .. code-tab:: csharp + + using Godot; + + public partial class Game : Node3D // Or Node2D. + { + public override void _Ready() + { + // Preconfigure game. + + Lobby.Instance.RpcId(1, Lobby.MethodName.PlayerLoaded); // Tell the server that this peer has loaded. + } + + // Called only on the server. + public void StartGame() + { + // All peers are ready to receive RPCs in this scene. + } + } + Exporting for dedicated servers ------------------------------- diff --git a/tutorials/networking/img/tls_certificates_export_filter.webp b/tutorials/networking/img/tls_certificates_export_filter.webp deleted file mode 100644 index ee83fa50436..00000000000 Binary files a/tutorials/networking/img/tls_certificates_export_filter.webp and /dev/null differ diff --git a/tutorials/networking/ssl_certificates.rst b/tutorials/networking/ssl_certificates.rst index bfa62d3471c..13905837d4c 100644 --- a/tutorials/networking/ssl_certificates.rst +++ b/tutorials/networking/ssl_certificates.rst @@ -1,22 +1,25 @@ .. _doc_ssl_certificates: -SSL/TLS certificates +TLS/SSL certificates ==================== Introduction ------------ -It is often desired to use :abbr:`SSL (Secure Sockets Layer)` connections (also -known as :abbr:`TLS (Transport Layer Security)` connections) for communications +It is often desired to use :abbr:`TLS (Transport Layer Security)` connections (also +known as :abbr:`SSL (Secure Sockets Layer)` connections) for communications to avoid "man in the middle" attacks. Godot has a connection wrapper, :ref:`StreamPeerTLS `, which can take a regular connection and add security around it. The :ref:`HTTPClient ` and :ref:`HTTPRequest ` classes also support HTTPS using this same wrapper. -Godot includes the -`SSL certificate bundle from Mozilla `__, -but you can provide your own with a CRT file in the Project Settings: +Godot will try to use the TLS certificate bundle provided by the operating system, +but also includes the +`TLS certificate bundle from Mozilla `__ +as a fallback. + +You can alternatively force your own certificate bundle in the Project Settings: .. figure:: img/tls_certificates_project_setting.webp :align: center @@ -24,23 +27,14 @@ but you can provide your own with a CRT file in the Project Settings: Setting the TLS certificate bundle override project setting -When set, this file *overrides* the Mozilla certificate bundle Godot uses -by default. This file should contain any number of public certificates in +When set, this file *overrides* the operating system provided bundle by default. +This file should contain any number of public certificates in `PEM format `__. -Remember to add ``*.crt`` as the non-resource export filter to your export -preset, so that the exporter recognizes this when exporting your project: - -.. figure:: img/tls_certificates_export_filter.webp - :align: center - :alt: Adding ``*.crt`` to non-resource export filter in the export preset - - Adding ``*.crt`` to non-resource export filter in the export preset - There are two ways to obtain certificates: -Acquire a certificate from a certificate authority --------------------------------------------------- +Obtain a certificate from a certificate authority +------------------------------------------------- The main approach to getting a certificate is to use a certificate authority (CA) such as `Let's Encrypt `__. This is a more @@ -73,7 +67,17 @@ Settings. access to it: otherwise, the security of the certificate will be compromised. -OpenSSL has `some documentation +.. warning:: + + When specifying a self-signed certificate as TLS bundle in the project + settings, normal domain name validation is enforced via the certificate + :abbr:`CN (common name)` and alternative names. See + :ref:`TLSOptions ` to customize domain name validation. + +For development purposes Godot can generate self-signed certificates via +:ref:`Crypto.generate_self_signed_certificate +`. + +Alternatively, OpenSSL has some documentation about `generating keys `__ -about this. For local development purposes **only**, `mkcert -`__ can be used as an alternative. +and `certificates `__. diff --git a/tutorials/performance/cpu_optimization.rst b/tutorials/performance/cpu_optimization.rst index ec927f017b6..7e03a209ce2 100644 --- a/tutorials/performance/cpu_optimization.rst +++ b/tutorials/performance/cpu_optimization.rst @@ -92,7 +92,8 @@ using a profiler, is to manually time the function or area under test. The specifics vary depending on the language, but in GDScript, you would do the following: -:: +.. tabs:: + .. code-tab:: gdscript GDScript var time_start = Time.get_ticks_usec() @@ -102,6 +103,16 @@ the following: var time_end = Time.get_ticks_usec() print("update_enemies() took %d microseconds" % time_end - time_start) + .. code-tab:: csharp + + var timeStart = Time.GetTicksUsec(); + + // Your function you want to time. + UpdateEnemies(); + + var timeEnd = Time.GetTicksUsec(); + GD.Print($"UpdateEnemies() took {timeEnd - timeStart} microseconds"); + When manually timing functions, it is usually a good idea to run the function many times (1,000 or more times), instead of just once (unless it is a very slow function). The reason for doing this is that timers often have limited accuracy. diff --git a/tutorials/performance/general_optimization.rst b/tutorials/performance/general_optimization.rst index 0506931fd9f..e8d25bffc97 100644 --- a/tutorials/performance/general_optimization.rst +++ b/tutorials/performance/general_optimization.rst @@ -59,8 +59,9 @@ There are several methods of measuring performance, including: - Using :ref:`external CPU profilers `. - Using external GPU profilers/debuggers such as `NVIDIA Nsight Graphics `__, - `Radeon GPU Profiler `__ or - `Intel Graphics Performance Analyzers `__. + `Radeon GPU Profiler `__, + `Intel Graphics Performance Analyzers `__, or + `Arm Performance Studio `__. - Checking the frame rate (with V-Sync disabled). Third-party utilities such as `RivaTuner Statistics Server `__ (Windows) or `MangoHud `__ diff --git a/tutorials/performance/thread_safe_apis.rst b/tutorials/performance/thread_safe_apis.rst index 26e1abebabb..174dfc3dbeb 100644 --- a/tutorials/performance/thread_safe_apis.rst +++ b/tutorials/performance/thread_safe_apis.rst @@ -30,7 +30,7 @@ Interacting with the active scene tree is **NOT** thread-safe. Make sure to use # Unsafe: node.add_child(child_node) # Safe: - node.call_deferred("add_child", child_node) + node.add_child.call_deferred(child_node) However, creating scene chunks (nodes in tree arrangement) outside the active tree is fine. This way, parts of a scene can be built or instantiated in a thread, then added in the main thread: @@ -39,7 +39,7 @@ However, creating scene chunks (nodes in tree arrangement) outside the active tr var enemy_scene = load("res://enemy_scene.scn") var enemy = enemy_scene.instantiate() enemy.add_child(weapon) # Set a weapon. - world.call_deferred("add_child", enemy) + world.add_child.call_deferred(enemy) Still, this is only really useful if you have **one** thread loading data. Attempting to load or create scene chunks from multiple threads may work, but you risk diff --git a/tutorials/performance/using_servers.rst b/tutorials/performance/using_servers.rst index 7a926f1eaa0..90f894d77e8 100644 --- a/tutorials/performance/using_servers.rst +++ b/tutorials/performance/using_servers.rst @@ -114,7 +114,7 @@ This is an example of how to create a sprite from code and move it using the low # Remember, keep this reference. texture = load("res://my_texture.png") # Add it, centered. - RenderingServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture) + RenderingServer.canvas_item_add_texture_rect(ci_rid, Rect2(-texture.get_size() / 2, texture.get_size()), texture) # Add the item, rotated 45 degrees and translated. var xform = Transform2D().rotated(deg_to_rad(45)).translated(Vector2(20, 30)) RenderingServer.canvas_item_set_transform(ci_rid, xform) @@ -136,7 +136,7 @@ This is an example of how to create a sprite from code and move it using the low // Remember, keep this reference. _texture = ResourceLoader.Load("res://MyTexture.png"); // Add it, centered. - RenderingServer.CanvasItemAddTextureRect(ciRid, new Rect2(_texture.GetSize() / 2, _texture.GetSize()), _texture.GetRid()); + RenderingServer.CanvasItemAddTextureRect(ciRid, new Rect2(-_texture.GetSize() / 2, _texture.GetSize()), _texture.GetRid()); // Add the item, rotated 45 degrees and translated. Transform2D xform = Transform2D.Identity.Rotated(Mathf.DegToRad(45)).Translated(new Vector2(20, 30)); RenderingServer.CanvasItemSetTransform(ciRid, xform); diff --git a/tutorials/platform/android/android_library.rst b/tutorials/platform/android/android_library.rst index a962e6fa481..634df4fc558 100644 --- a/tutorials/platform/android/android_library.rst +++ b/tutorials/platform/android/android_library.rst @@ -45,11 +45,11 @@ These APIs can also be used to provide bidirectional communication between the h Godot instance allowing for greater control over the desired experience. We showcase how this is done using a sample Android app that embeds the Godot Engine as an Android view, -and uses it to render 3D GLTF models. +and uses it to render 3D glTF models. The `GLTF Viewer `_ sample app uses an `Android RecyclerView component `_ to create -a list of GLTF items, populated from `Kenney's Food Kit pack `_. -When an item on the list is selected, the app's logic interacts with the embedded Godot Engine to render the selected GLTF item as a 3D model. +a list of glTF items, populated from `Kenney's Food Kit pack `_. +When an item on the list is selected, the app's logic interacts with the embedded Godot Engine to render the selected glTF item as a 3D model. .. image:: img/gltf_viewer_sample_app_screenshot.webp @@ -146,7 +146,7 @@ Below we break-down the steps used to create the GLTF Viewer app. - Add any additional logic that will be used by your application - - For the sample app, this includes adding the `ItemsSelectionFragment fragment `_ (and related classes), a fragment used to build and show the list of GLTF items + - For the sample app, this includes adding the `ItemsSelectionFragment fragment `_ (and related classes), a fragment used to build and show the list of glTF items - Open the ``AndroidManifest.xml`` file, and configure the orientation if needed using the `android:screenOrientation attribute `_ @@ -191,7 +191,7 @@ Below we break-down the steps used to create the GLTF Viewer app. - Update the Godot project script logic as needed - For the sample app, the `script logic `_ queries for the runtime ``GodotPlugin`` instance and uses it to register for signals fired by the app logic - - The app logic fires a signal every time an item is selected in the list. The signal contains the filepath of the GLTF model, which is used by the ``gdscript`` logic to render the model. + - The app logic fires a signal every time an item is selected in the list. The signal contains the filepath of the glTF model, which is used by the ``gdscript`` logic to render the model. .. code-block:: gdscript diff --git a/tutorials/plugins/running_code_in_the_editor.rst b/tutorials/plugins/running_code_in_the_editor.rst index 4609a3ba254..0f0914ef7a7 100644 --- a/tutorials/plugins/running_code_in_the_editor.rst +++ b/tutorials/plugins/running_code_in_the_editor.rst @@ -248,7 +248,7 @@ angle add a setter ``set(new_speed)`` which is executed with the input from the Getting notified when resources change -------------------------------------- -Some times you want your tool to use a resource. However, when you change a +Sometimes you want your tool to use a resource. However, when you change a property of that resource in the editor, the ``set()`` method of your tool will not be called. diff --git a/tutorials/rendering/compositor.rst b/tutorials/rendering/compositor.rst index bcebe3c1eb1..763a9a2abd4 100644 --- a/tutorials/rendering/compositor.rst +++ b/tutorials/rendering/compositor.rst @@ -152,7 +152,7 @@ We also need to clean up after ourselves, for this we react to the if what == NOTIFICATION_PREDELETE: if shader.is_valid(): # Freeing our shader will also free any dependents such as the pipeline! - RenderingServer.free_rid(shader) + rd.free_rid(shader) Note that we do not use our mutex here even though we create our shader inside of our render thread. diff --git a/tutorials/rendering/viewports.rst b/tutorials/rendering/viewports.rst index 9a108d759f0..19927a23ac9 100644 --- a/tutorials/rendering/viewports.rst +++ b/tutorials/rendering/viewports.rst @@ -76,10 +76,15 @@ There can only be one active camera per :ref:`Viewport `, so if than one, make sure that the desired one has the :ref:`current ` property set, or make it the current camera by calling: -:: +.. tabs:: + .. code-tab:: gdscript GDScript camera.make_current() + .. code-tab:: csharp + + camera.MakeCurrent(); + By default, cameras will render all objects in their world. In 3D, cameras can use their :ref:`cull_mask ` property combined with the :ref:`VisualInstance3D's ` :ref:`layer ` @@ -95,11 +100,17 @@ these values are overridden, but for all others, this sets their resolution. It is also possible to scale the 2D content and make the :ref:`SubViewport ` resolution different from the one specified in size, by calling: -:: +.. tabs:: + .. code-tab:: gdscript GDScript sub_viewport.set_size_2d_override(Vector2i(width, height)) # Custom size for 2D. sub_viewport.set_size_2d_override_stretch(true) # Enable stretch for custom size. + .. code-tab:: csharp + + subViewport.Size2DOverride = new Vector2I(width, height); // Custom size for 2D. + subViewport.Size2DOverrideStretch = true; // Enable stretch for custom size. + For information on scaling and stretching with the Root Viewport visit the :ref:`Multiple Resolutions Tutorial ` Worlds @@ -137,7 +148,8 @@ It is possible to query a capture of the :ref:`Viewport ` conten Viewport, this is effectively a screen capture. This is done with the following code: -:: +.. tabs:: + .. code-tab:: gdscript GDScript # Retrieve the captured Image using get_image(). var img = get_viewport().get_texture().get_image() @@ -146,16 +158,32 @@ following code: # Set sprite texture. sprite.texture = tex + .. code-tab:: csharp + + // Retrieve the captured Image using get_image(). + var img = GetViewport().GetTexture().GetImage(); + // Convert Image to ImageTexture. + var tex = ImageTexture.CreateFromImage(img); + // Set sprite texture. + sprite.Texture = tex; + But if you use this in ``_ready()`` or from the first frame of the :ref:`Viewport's ` initialization, you will get an empty texture because there is nothing to get as texture. You can deal with it using (for example): -:: +.. tabs:: + .. code-tab:: gdscript GDScript # Wait until the frame has finished before getting the texture. await RenderingServer.frame_post_draw # You can get the image after this. + .. code-tab:: csharp + + // Wait until the frame has finished before getting the texture. + await RenderingServer.Singleton.ToSignal(RenderingServer.SignalName.FramePostDraw); + // You can get the image after this. + Viewport Container ------------------ @@ -218,12 +246,19 @@ When rendering to a :ref:`SubViewport `, whatever is inside w visible in the scene editor. To display the contents, you have to draw the SubViewport's :ref:`ViewportTexture ` somewhere. This can be requested via code using (for example): -:: +.. tabs:: + .. code-tab:: gdscript GDScript # This gives us the ViewportTexture. var tex = viewport.get_texture() sprite.texture = tex + .. code-tab:: csharp + + // This gives us the ViewportTexture. + var tex = viewport.GetTexture(); + sprite.Texture = tex; + Or it can be assigned in the editor by selecting "New ViewportTexture" .. image:: img/texturemenu.webp @@ -245,6 +280,6 @@ This flexibility allows users to render an image once and then use the texture w .. note:: - Make sure to check the Viewport demos. They are available in the + Make sure to check the Viewport demos. They are available in the viewport folder of the demos archive, or at https://github.com/godotengine/godot-demo-projects/tree/master/viewport. diff --git a/tutorials/scripting/c_sharp/c_sharp_basics.rst b/tutorials/scripting/c_sharp/c_sharp_basics.rst index e406f69d925..224ec48a393 100644 --- a/tutorials/scripting/c_sharp/c_sharp_basics.rst +++ b/tutorials/scripting/c_sharp/c_sharp_basics.rst @@ -106,11 +106,6 @@ In Visual Studio Code: - Install the `C# `__ extension. -.. note:: - - If you are using Linux you need to install the `Mono SDK `__ - for the C# tools plugin to work. - To configure a project for debugging, you need a ``tasks.json`` and ``launch.json`` file in the ``.vscode`` folder with the necessary configuration. diff --git a/tutorials/scripting/c_sharp/c_sharp_collections.rst b/tutorials/scripting/c_sharp/c_sharp_collections.rst index 8c67eb4b169..141c4908af6 100644 --- a/tutorials/scripting/c_sharp/c_sharp_collections.rst +++ b/tutorials/scripting/c_sharp/c_sharp_collections.rst @@ -85,6 +85,7 @@ GDScript C# ``PackedStringArray`` ``string[]`` ``PackedVector2Array`` ``Vector2[]`` ``PackedVector3Array`` ``Vector3[]`` +``PackedVector4Array`` ``Vector4[]`` ``PackedColorArray`` ``Color[]`` ====================== ============================================================== diff --git a/tutorials/scripting/c_sharp/c_sharp_features.rst b/tutorials/scripting/c_sharp/c_sharp_features.rst index b3d8d1e8b43..94e9d539d77 100644 --- a/tutorials/scripting/c_sharp/c_sharp_features.rst +++ b/tutorials/scripting/c_sharp/c_sharp_features.rst @@ -102,10 +102,6 @@ Preprocessor defines Godot has a set of defines that allow you to change your C# code depending on the environment you are compiling to. -.. note:: If you created your project before Godot 3.2, you have to modify - or regenerate your `csproj` file to use this feature - (compare ```` with a new 3.2+ project). - Examples ~~~~~~~~ @@ -115,10 +111,7 @@ For example, you can change code based on the platform: public override void _Ready() { - #if GODOT_SERVER - // Don't try to load meshes or anything, this is a server! - LaunchServer(); - #elif GODOT_32 || GODOT_MOBILE || GODOT_WEB + #if (GODOT_32 || GODOT_MOBILE || GODOT_WEB) // Use simple objects when running on less powerful systems. SpawnSimpleObjects(); #else @@ -167,7 +160,7 @@ Full list of defines * One of ``GODOT_64`` or ``GODOT_32`` is defined depending on if the architecture is 64-bit or 32-bit. * One of ``GODOT_LINUXBSD``, ``GODOT_WINDOWS``, ``GODOT_OSX``, - ``GODOT_ANDROID``, ``GODOT_IOS``, ``GODOT_HTML5``, or ``GODOT_SERVER`` + ``GODOT_ANDROID``, ``GODOT_IOS``, ``GODOT_WEB`` depending on the OS. These names may change in the future. These are created from the ``get_name()`` method of the :ref:`OS ` singleton, but not every possible OS diff --git a/tutorials/scripting/c_sharp/c_sharp_global_classes.rst b/tutorials/scripting/c_sharp/c_sharp_global_classes.rst index 8336c4347c0..8bf12527e86 100644 --- a/tutorials/scripting/c_sharp/c_sharp_global_classes.rst +++ b/tutorials/scripting/c_sharp/c_sharp_global_classes.rst @@ -83,7 +83,7 @@ will let you create and load instances of this type easily. .. warning:: - The Godot editor will hide these custom classes with names that beging with the prefix + The Godot editor will hide these custom classes with names that begin with the prefix "Editor" in the 'Create New Node' or 'Create New Scene' dialog windows. The classes are available for instantiation at runtime via their class names, but are automatically hidden by the editor windows along with the built-in editor nodes used diff --git a/tutorials/scripting/c_sharp/c_sharp_variant.rst b/tutorials/scripting/c_sharp/c_sharp_variant.rst index 365056f6745..223e4122bd6 100644 --- a/tutorials/scripting/c_sharp/c_sharp_variant.rst +++ b/tutorials/scripting/c_sharp/c_sharp_variant.rst @@ -129,6 +129,7 @@ Variant.Type C# Type ``PackedStringArray`` ``string[]`` ``PackedVector2Array`` ``Godot.Vector2[]`` ``PackedVector3Array`` ``Godot.Vector3[]`` +``PackedVector4Array`` ``Godot.Vector4[]`` ``PackedColorArray`` ``Godot.Color[]`` ======================= =========================================================== diff --git a/tutorials/scripting/creating_script_templates.rst b/tutorials/scripting/creating_script_templates.rst index 6d5314f8c3c..d3b1a456239 100644 --- a/tutorials/scripting/creating_script_templates.rst +++ b/tutorials/scripting/creating_script_templates.rst @@ -61,22 +61,20 @@ Both editor and project defined templates are organized in the following way: where: -* ``template_path`` is one of the 2 locations discussed in the previous two sections +* ``template_path`` is one of the 2 locations discussed in the previous two sections. * ``node_type`` is the node it will apply to (for example, :ref:`Node `, or :ref:`CharacterBody3D `), - casing doesn't matter for the folder name, however adding a ``_`` to a name will not work, for example ``Mesh_Instance3D`` does not work. - if a script isn't in the proper ``node_type`` folder it will not be detected. + This is **case-sensitive**. If a script isn't in the proper ``node_type`` folder, it won't be detected. -* ``file`` is the custom name you can chose for the template (for example: ``platformer_movement`` or ``smooth_camera``) +* ``file`` is the custom name you can chose for the template (for example, ``platformer_movement`` or ``smooth_camera``). -* ``extension``: will indicate which language the template will apply to (it should be ``gd`` for GDScript or ``cs`` for C#) +* ``extension`` indicates which language the template will apply to (it should be ``gd`` for GDScript or ``cs`` for C#). For example: - ``template_scripts/Node/smooth_camera.gd`` - ``template_scripts/CharacterBody3D/platformer_movement.gd`` - Default behaviour and overriding it ----------------------------------- diff --git a/tutorials/scripting/debug/the_profiler.rst b/tutorials/scripting/debug/the_profiler.rst index 3a6fe3ba523..b55c27f8a76 100644 --- a/tutorials/scripting/debug/the_profiler.rst +++ b/tutorials/scripting/debug/the_profiler.rst @@ -26,9 +26,8 @@ Godot's profiler does not automatically run because profiling is performance-intensive. It has to continually measure everything happening in the game and report back to the debugger, so it's off by default. -To begin profiling, click on the **Start** button in the top-left. Run your game -and data will start appearing. You can also start profiling at any time before -or during gameplay, depending on if you want. +To begin profiling, run your game then focus back on the editor. Click on the +**Start** button in the top-left corner of the **Profiler** tab. .. note:: diff --git a/tutorials/scripting/gdextension/files/cpp_example/SConstruct b/tutorials/scripting/gdextension/files/cpp_example/SConstruct index 691f8131944..a1ce2492dff 100644 --- a/tutorials/scripting/gdextension/files/cpp_example/SConstruct +++ b/tutorials/scripting/gdextension/files/cpp_example/SConstruct @@ -23,6 +23,17 @@ if env["platform"] == "macos": ), source=sources, ) +elif env["platform"] == "ios": + if env["ios_simulator"]: + library = env.StaticLibrary( + "demo/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]), + source=sources, + ) + else: + library = env.StaticLibrary( + "demo/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]), + source=sources, + ) else: library = env.SharedLibrary( "demo/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]), diff --git a/tutorials/scripting/gdextension/gdextension_cpp_example.rst b/tutorials/scripting/gdextension/gdextension_cpp_example.rst index f89754b77bc..a16285185a7 100644 --- a/tutorials/scripting/gdextension/gdextension_cpp_example.rst +++ b/tutorials/scripting/gdextension/gdextension_cpp_example.rst @@ -295,7 +295,7 @@ The ``initialize_example_module`` and ``uninitialize_example_module`` functions called respectively when Godot loads our plugin and when it unloads it. All we're doing here is parse through the functions in our bindings module to initialize them, but you might have to set up more things depending on your -needs. We call the function ``register_class`` for each of our classes in our library. +needs. We call the ``GDREGISTER_CLASS`` macro for each of our classes in our library. The important function is the third function called ``example_library_init``. We first call a function in our bindings library that creates an initialization object. @@ -344,6 +344,19 @@ structure alongside ``godot-cpp``, ``src`` and ``demo``, then run: You should now be able to find the module in ``demo/bin/``. +When building for iOS, package the module as a static `.xcframework`, you can use +following commands to do so: + +:: + + # compile simulator and device modules + scons arch=universal ios_simulator=yes platform=ios target= + scons arch=arm64 ios_simulator=no platform=ios target= + + # assemble xcframeworks + xcodebuild -create-xcframework -library demo/bin/libgdexample.ios..a -library demo/bin/libgdexample.ios..simulator.a -output demo/bin/libgdexample.ios..xcframework + xcodebuild -create-xcframework -library godot-cpp/bin/libgodot-cpp.ios..arm64.a -library godot-cpp/bin/libgodot-cpp.ios..universal.simulator.a -output demo/bin/libgodot-cpp.ios..xcframework + .. note:: Here, we've compiled both godot-cpp and our gdexample library as debug @@ -371,6 +384,8 @@ loaded for each platform and the entry function for the module. It is called ``g macos.debug = "res://bin/libgdexample.macos.template_debug.framework" macos.release = "res://bin/libgdexample.macos.template_release.framework" + ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework" + ios.release = "res://bin/libgdexample.ios.template_release.xcframework" windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll" windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll" windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll" @@ -386,6 +401,14 @@ loaded for each platform and the entry function for the module. It is called ``g android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so" android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so" + [dependencies] + ios.debug = { + "res://bin/libgodot-cpp.ios.template_debug.xcframework": "" + } + ios.release = { + "res://bin/libgodot-cpp.ios.template_release.xcframework": "" + } + This file contains a ``configuration`` section that controls the entry function of the module. You should also set the minimum compatible Godot version with ``compatability_minimum``, which prevents older version of Godot from trying to load your extension. @@ -474,6 +497,7 @@ show the methods we end up changing, don't remove the lines we're omitting: void GDExample::_bind_methods() { ClassDB::bind_method(D_METHOD("get_amplitude"), &GDExample::get_amplitude); ClassDB::bind_method(D_METHOD("set_amplitude", "p_amplitude"), &GDExample::set_amplitude); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "amplitude"), "set_amplitude", "get_amplitude"); } @@ -531,7 +555,8 @@ showing the methods that have changed so don't remove anything we're omitting: ... ClassDB::bind_method(D_METHOD("get_speed"), &GDExample::get_speed); ClassDB::bind_method(D_METHOD("set_speed", "p_speed"), &GDExample::set_speed); - ADD_PROPERTY("GDExample", PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_speed", "get_speed"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_speed", "get_speed"); } GDExample::GDExample() { @@ -625,7 +650,7 @@ as follows: void GDExample::_bind_methods() { ... - ADD_PROPERTY("GDExample", PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_speed", "get_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_speed", "get_speed"); ADD_SIGNAL(MethodInfo("position_changed", PropertyInfo(Variant::OBJECT, "node"), PropertyInfo(Variant::VECTOR2, "new_pos"))); } diff --git a/tutorials/scripting/gdextension/gdextension_docs_system.rst b/tutorials/scripting/gdextension/gdextension_docs_system.rst index 0a5f09338ca..f635a8fdc94 100644 --- a/tutorials/scripting/gdextension/gdextension_docs_system.rst +++ b/tutorials/scripting/gdextension/gdextension_docs_system.rst @@ -18,6 +18,8 @@ XML files (one per class) to document the exposed constructors, properties, meth We are assuming you are using the project files explained in the :ref:`GDExtension C++ Example ` with the following structure: +.. code-block:: none + gdextension_cpp_example/ # GDExtension directory | +--demo/ # game example/demo to test the extension @@ -114,9 +116,9 @@ Currently they supported tags for the GDExtension documentation system are: - ``[s]{text}[/s]`` * - | **kbd** - | Makes ``{text}`` use the mono font and styles the text color and background like a shortcut. + | Makes ``{text}`` use a grey beveled background, indicating a keyboard shortcut. - - ``[code]{text}[/code]`` + - ``[kbd]{text}[/kbd]`` * - | **code** | Makes inline ``{text}`` use the mono font and styles the text color and background like code. @@ -140,9 +142,7 @@ Currently they supported tags for the GDExtension documentation system are: - ``[center]{text}[/center]`` * - | **url** - | Creates a hyperlink (underlined and clickable text). Can contain optional - ``{text}`` or display ``{link}`` as is. - | **Must be handled with the "meta_clicked" signal to have an effect,** see :ref:`doc_bbcode_in_richtextlabel_handling_url_tag_clicks`. + | Creates a hyperlink (underlined and clickable text). Can contain optional ``{text}`` or display ``{link}`` as is. - | ``[url]{link}[/url]`` | ``[url={link}]{text}[/url]`` diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst index 0f1451799d4..76e8560af95 100644 --- a/tutorials/scripting/gdscript/gdscript_basics.rst +++ b/tutorials/scripting/gdscript/gdscript_basics.rst @@ -165,6 +165,8 @@ in case you want to take a look under the hood. +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ | match | See match_. | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ +| when | Used by `pattern guards `_ in ``match`` statements. | ++------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ | break | Exits the execution of the current ``for`` or ``while`` loop. | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ | continue | Immediately skips to the next iteration of the ``for`` or ``while`` loop. | @@ -570,8 +572,6 @@ considered a comment. The list of highlighted keywords and their colors can be changed in the **Text Editor > Theme > Comment Markers** section of the Editor Settings. -.. _doc_gdscript_builtin_types: - Code regions ~~~~~~~~~~~~ @@ -661,6 +661,8 @@ A line can be continued multiple times like this: 10 + \ 4 +.. _doc_gdscript_builtin_types: + Built-in types -------------- @@ -893,6 +895,7 @@ arrays. They are therefore only recommended to use for large data sets: - :ref:`PackedStringArray `: An array of strings. - :ref:`PackedVector2Array `: An array of :ref:`Vector2 ` values. - :ref:`PackedVector3Array `: An array of :ref:`Vector3 ` values. +- :ref:`PackedVector4Array `: An array of :ref:`Vector4 ` values. - :ref:`PackedColorArray `: An array of :ref:`Color ` values. :ref:`Dictionary ` @@ -1654,10 +1657,10 @@ Basic syntax :: - match : + match : : - when : + when : <...> @@ -1790,9 +1793,13 @@ The following pattern types are available: Pattern guards """""""""""""" +A *pattern guard* is an optional condition that follows the pattern list +and allows you to make additional checks before choosing a ``match`` branch. +Unlike a pattern, a pattern guard can be an arbitrary expression. + Only one branch can be executed per ``match``. Once a branch is chosen, the rest are not checked. If you want to use the same pattern for multiple branches or to prevent choosing a branch with too general pattern, -you can specify a guard expression after the list of patterns with the ``when`` keyword:: +you can specify a pattern guard after the list of patterns with the ``when`` keyword:: match point: [0, 0]: @@ -1808,9 +1815,9 @@ you can specify a guard expression after the list of patterns with the ``when`` [var x, var y]: print("Point (%s, %s)" % [x, y]) -- If there is no matching pattern for the current branch, the guard expression +- If there is no matching pattern for the current branch, the pattern guard is **not** evaluated and the patterns of the next branch are checked. -- If a matching pattern is found, the guard expression is evaluated. +- If a matching pattern is found, the pattern guard is evaluated. - If it's true, then the body of the branch is executed and ``match`` ends. - If it's false, then the patterns of the next branch are checked. diff --git a/tutorials/scripting/gdscript/gdscript_styleguide.rst b/tutorials/scripting/gdscript/gdscript_styleguide.rst index b069c790987..ce2c6787fe9 100644 --- a/tutorials/scripting/gdscript/gdscript_styleguide.rst +++ b/tutorials/scripting/gdscript/gdscript_styleguide.rst @@ -734,7 +734,7 @@ more easily, and also makes for cleaner diffs in version control when items are Code order ---------- -This first section focuses on code order. For formatting, see +This section focuses on code order. For formatting, see :ref:`formatting`. For naming conventions, see :ref:`naming_conventions`. We suggest to organize GDScript code this way: diff --git a/tutorials/scripting/img/autoload_example.webp b/tutorials/scripting/img/autoload_example.webp index 0ab122861e0..47ab9829b58 100644 Binary files a/tutorials/scripting/img/autoload_example.webp and b/tutorials/scripting/img/autoload_example.webp differ diff --git a/tutorials/scripting/img/autoload_tab.webp b/tutorials/scripting/img/autoload_tab.webp index 2419ea54f03..69bae3f19b9 100644 Binary files a/tutorials/scripting/img/autoload_tab.webp and b/tutorials/scripting/img/autoload_tab.webp differ diff --git a/tutorials/scripting/img/autoload_tutorial1.webp b/tutorials/scripting/img/autoload_tutorial1.webp index dcccaacc3b8..4b51c680673 100644 Binary files a/tutorials/scripting/img/autoload_tutorial1.webp and b/tutorials/scripting/img/autoload_tutorial1.webp differ diff --git a/tutorials/scripting/index.rst b/tutorials/scripting/index.rst index 0f4e979a5be..cca739a0c13 100644 --- a/tutorials/scripting/index.rst +++ b/tutorials/scripting/index.rst @@ -10,8 +10,7 @@ Here, you will find information that is not already covered in more specific sections. For instance, to learn about inputs, we recommend you to read :ref:`Inputs `. -Programming languages ---------------------- +.. rubric:: Programming languages The sections below each focus on a given programming language. diff --git a/tutorials/scripting/singletons_autoload.rst b/tutorials/scripting/singletons_autoload.rst index 851c1a2a7c6..fdc4be9670a 100644 --- a/tutorials/scripting/singletons_autoload.rst +++ b/tutorials/scripting/singletons_autoload.rst @@ -205,7 +205,7 @@ current scene and replace it with the requested one. # The solution is to defer the load to a later time, when # we can be sure that no code from the current scene is running: - call_deferred("_deferred_goto_scene", path) + _deferred_goto_scene.call_deferred(path) func _deferred_goto_scene(path): diff --git a/tutorials/shaders/advanced_postprocessing.rst b/tutorials/shaders/advanced_postprocessing.rst index d562e8fd790..1f508141524 100644 --- a/tutorials/shaders/advanced_postprocessing.rst +++ b/tutorials/shaders/advanced_postprocessing.rst @@ -93,11 +93,10 @@ Once defined, the depth texture can be read with the ``texture()`` function. possible when reading from the current viewport. The depth texture cannot be accessed from another viewport to which you have rendered. -The values returned by ``depth_texture`` are between ``0.0`` and ``1.0`` and are nonlinear. +The values returned by ``depth_texture`` are between ``1.0`` and ``0.0`` (corresponding to +the near and far plane, respectively, because of using a "reverse-z" depth buffer) and are nonlinear. When displaying depth directly from the ``depth_texture``, everything will look almost -white unless it is very close. This is because the depth buffer stores objects closer -to the camera using more bits than those further, so most of the detail in depth -buffer is found close to the camera. In order to make the depth value align with world or +black unless it is very close due to that nonlinearity. In order to make the depth value align with world or model coordinates, we need to linearize the value. When we apply the projection matrix to the vertex position, the z value is made nonlinear, so to linearize it, we multiply it by the inverse of the projection matrix, which in Godot, is accessible with the variable @@ -137,22 +136,51 @@ the distance to the point. Because the camera is facing the negative ``z`` direction, the position will have a negative ``z`` value. In order to get a usable depth value, we have to negate ``view.z``. -The world position can be constructed from the depth buffer using the following code. Note -that the ``INV_VIEW_MATRIX`` is needed to transform the position from view space into world space, so -it needs to be passed to the fragment shader with a varying. +The world position can be constructed from the depth buffer using the following code, using the +``INV_VIEW_MATRIX`` to transform the position from view space into world space. .. code-block:: glsl - varying mat4 CAMERA; + void fragment() { + ... + vec4 world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0); + vec3 world_position = world.xyz / world.w; + } + +Example shader +-------------- + +Once we add a line to output to ``ALBEDO``, we have a complete shader that looks something like this. +This shader lets you visualize the linear depth or world space coordinates, depending on which +line is commented out. + +.. code-block:: glsl + + shader_type spatial; + // Prevent the quad from being affected by lighting and fog. This also improves performance. + render_mode unshaded, fog_disabled; + + uniform sampler2D depth_texture : source_color, hint_depth_texture; void vertex() { - CAMERA = INV_VIEW_MATRIX; + POSITION = vec4(VERTEX.xy, 1.0, 1.0); } void fragment() { - ... - vec4 world = CAMERA * INV_PROJECTION_MATRIX * vec4(ndc, 1.0); + float depth = texture(depth_texture, SCREEN_UV).x; + vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth); + vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0); + view.xyz /= view.w; + float linear_depth = -view.z; + + vec4 world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0); vec3 world_position = world.xyz / world.w; + + // Visualize linear depth + ALBEDO.rgb = vec3(fract(linear_depth)); + + // Visualize world coordinates + //ALBEDO.rgb = fract(world_position).xyz; } An optimization diff --git a/tutorials/shaders/shader_reference/shading_language.rst b/tutorials/shaders/shader_reference/shading_language.rst index db74e561809..ba2ca01d7c0 100644 --- a/tutorials/shaders/shader_reference/shading_language.rst +++ b/tutorials/shaders/shader_reference/shading_language.rst @@ -32,7 +32,7 @@ Most GLSL ES 3.0 datatypes are supported: +----------------------+---------------------------------------------------------------------------------+ | **bvec4** | Four-component vector of booleans. | +----------------------+---------------------------------------------------------------------------------+ -| **int** | Signed scalar integer. | +| **int** | 32 bit signed scalar integer. | +----------------------+---------------------------------------------------------------------------------+ | **ivec2** | Two-component vector of signed integers. | +----------------------+---------------------------------------------------------------------------------+ @@ -48,7 +48,7 @@ Most GLSL ES 3.0 datatypes are supported: +----------------------+---------------------------------------------------------------------------------+ | **uvec4** | Four-component vector of unsigned integers. | +----------------------+---------------------------------------------------------------------------------+ -| **float** | Floating-point scalar. | +| **float** | 32 bit floating-point scalar. | +----------------------+---------------------------------------------------------------------------------+ | **vec2** | Two-component vector of floating-point values. | +----------------------+---------------------------------------------------------------------------------+ @@ -227,7 +227,7 @@ variables, arguments and varyings: lowp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // low precision, usually 8 bits per component mapped to 0-1 mediump vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // medium precision, usually 16 bits or half float - highp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // high precision, uses full float or integer range (default) + highp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // high precision, uses full float or integer range (32 bit default) Using lower precision for some operations can speed up the math involved (at the @@ -938,6 +938,9 @@ table of the corresponding types: be thrown if the type does not match. Your shader will just exhibit undefined behavior. +.. warning:: + As with the last note, no error will be thrown if the typing does not match while setting a shader uniform, this unintuitively includes setting a (GDscript) 64 bit int/float into a Godot shader language int/float (32 bit). This may lead to unintentional consequences in cases where high precision is required. + Uniforms can also be assigned default values: .. code-block:: glsl diff --git a/tutorials/shaders/your_first_shader/your_first_3d_shader.rst b/tutorials/shaders/your_first_shader/your_first_3d_shader.rst index c0817a5c136..d9e468cd83c 100644 --- a/tutorials/shaders/your_first_shader/your_first_3d_shader.rst +++ b/tutorials/shaders/your_first_shader/your_first_3d_shader.rst @@ -277,6 +277,7 @@ Interacting with light First, turn wireframe off. To do so, click in the upper-left of the Viewport again, where it says "Perspective", and select "Display Normal". +Additionally in the 3D scene toolbar, turn off preview sunlight. .. image:: img/normal.png diff --git a/tutorials/troubleshooting.rst b/tutorials/troubleshooting.rst index 0cc7a44a8ef..8fe6efe5c46 100644 --- a/tutorials/troubleshooting.rst +++ b/tutorials/troubleshooting.rst @@ -83,7 +83,7 @@ in the Editor Settings (**Network > Debug > Remote Port**). The default is On Windows, when loading the project for the first time after the PC is turned on, Windows Defender will cause the filesystem cache validation on project startup -to take significantly longer. This is especially noticable in projects with a +to take significantly longer. This is especially noticeable in projects with a large number of files. Consinder adding the project folder to the list of exclusions by going to Virus & threat protection > Virus & threat protection settings > Add or remove exclusions. diff --git a/tutorials/ui/bbcode_in_richtextlabel.rst b/tutorials/ui/bbcode_in_richtextlabel.rst index 55fa0ba3cee..6b40540d46c 100644 --- a/tutorials/ui/bbcode_in_richtextlabel.rst +++ b/tutorials/ui/bbcode_in_richtextlabel.rst @@ -633,7 +633,7 @@ Image options If set to ``true``, and the image is smaller than the size specified by ``width`` and ``height``, the image padding is added to match the size instead of upscaling. -- **tootip** +- **tooltip** +-----------+--------------------------------------------+ | `Values` | String | @@ -648,7 +648,7 @@ Image options Image and table vertical alignment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a vertical alignment value is provided with the ``[img]`` or ``[table]``` tag +When a vertical alignment value is provided with the ``[img]`` or ``[table]`` tag the image/table will try to align itself against the surrounding text. Alignment is performed using a vertical point of the image and a vertical point of the text. There are 3 possible points on the image (``top``, ``center``, and ``bottom``) and 4 @@ -715,7 +715,7 @@ Font options Extra spacing for each glyph. -- **glyph_spacing**, **sp** +- **space_spacing**, **sp** +-----------+--------------------------------------------+ | `Values` | Number in pixels. | diff --git a/tutorials/xr/openxr_hand_tracking.rst b/tutorials/xr/openxr_hand_tracking.rst index 9f0da10f5db..5d91708ca97 100644 --- a/tutorials/xr/openxr_hand_tracking.rst +++ b/tutorials/xr/openxr_hand_tracking.rst @@ -127,7 +127,7 @@ For this Godot uses the hand bone structure as defined for the :ref:`Godot Human but optionally supporting an extra tip bone for each finger. The `OpenXR hand tracking demo `_ -contains example GLTF files of properly rigged hands. +contains example glTF files of properly rigged hands. We will be using those here and add them as a child to our ``XRNode3D`` node. We also need to enable editable children to gain access to our :ref:`Skeleton3D ` node.